From fea5f5a77e72c1249bac5dc832c77c30381dc221 Mon Sep 17 00:00:00 2001 From: Diederik van der Boor Date: Mon, 13 Jun 2016 11:08:34 +0200 Subject: [PATCH] Model cleanups for example app and it's management commands --- example/pexp/admin.py | 30 ---- example/pexp/management/commands/p2cmd.py | 58 ++++--- example/pexp/management/commands/pcmd.py | 19 +-- example/pexp/management/commands/polybench.py | 7 +- .../commands/polymorphic_create_test_data.py | 14 -- example/pexp/migrations/0001_initial.py | 148 +++++++----------- example/pexp/migrations/0002_modelc_field4.py | 20 --- example/pexp/models.py | 67 ++++---- 8 files changed, 120 insertions(+), 243 deletions(-) delete mode 100644 example/pexp/migrations/0002_modelc_field4.py diff --git a/example/pexp/admin.py b/example/pexp/admin.py index 98dbbf0..d359c31 100644 --- a/example/pexp/admin.py +++ b/example/pexp/admin.py @@ -26,36 +26,6 @@ admin.site.register(ArtProject, ProjectChildAdmin) admin.site.register(ResearchProject, ProjectChildAdmin) -class ModelAAdmin(PolymorphicParentModelAdmin): - base_model = ModelA - list_filter = (PolymorphicChildModelFilter,) - child_models = (ModelA, ModelB, ModelC) - - -class ModelAChildAdmin(PolymorphicChildModelAdmin): - base_model = ModelA - - -admin.site.register(ModelA, ModelAAdmin) -admin.site.register(ModelB, ModelAChildAdmin) -admin.site.register(ModelC, ModelAChildAdmin) - - -class Model2AAdmin(PolymorphicParentModelAdmin): - base_model = Model2A - list_filter = (PolymorphicChildModelFilter,) - child_models = (Model2A, Model2B, Model2C) - - -class Model2AChildAdmin(PolymorphicChildModelAdmin): - base_model = Model2A - - -admin.site.register(Model2A, Model2AAdmin) -admin.site.register(Model2B, Model2AChildAdmin) -admin.site.register(Model2C, Model2AChildAdmin) - - class UUIDModelAAdmin(PolymorphicParentModelAdmin): base_model = UUIDModelA list_filter = (PolymorphicChildModelFilter,) diff --git a/example/pexp/management/commands/p2cmd.py b/example/pexp/management/commands/p2cmd.py index f6c31bd..abb7608 100644 --- a/example/pexp/management/commands/p2cmd.py +++ b/example/pexp/management/commands/p2cmd.py @@ -3,11 +3,7 @@ This module is a scratchpad for general development, testing & debugging Well, even more so than pcmd.py. You best ignore p2cmd.py. """ -import uuid -import django - from django.core.management.base import NoArgsCommand -from django.db import connection from pprint import pprint import time import sys @@ -16,7 +12,7 @@ from pexp.models import * def reset_queries(): - if django.VERSION < (1, 9): + if django.VERSION < (1, 8): connection.queries = [] else: connection.queries_log.clear() @@ -58,20 +54,20 @@ class Command(NoArgsCommand): def handle_noargs(self, **options): if False: - ModelA.objects.all().delete() - a = ModelA.objects.create(field1='A1') - b = ModelB.objects.create(field1='B1', field2='B2') - c = ModelC.objects.create(field1='C1', field2='C2', field3='C3') + TestModelA.objects.all().delete() + a = TestModelA.objects.create(field1='A1') + b = TestModelB.objects.create(field1='B1', field2='B2') + c = TestModelC.objects.create(field1='C1', field2='C2', field3='C3') reset_queries() - print ModelC.base_objects.all() + print TestModelC.base_objects.all() show_queries() if False: - ModelA.objects.all().delete() + TestModelA.objects.all().delete() for i in xrange(1000): - a = ModelA.objects.create(field1=str(i % 100)) - b = ModelB.objects.create(field1=str(i % 100), field2=str(i % 200)) - c = ModelC.objects.create(field1=str(i % 100), field2=str(i % 200), field3=str(i % 300)) + a = TestModelA.objects.create(field1=str(i % 100)) + b = TestModelB.objects.create(field1=str(i % 100), field2=str(i % 200)) + c = TestModelC.objects.create(field1=str(i % 100), field2=str(i % 200), field3=str(i % 300)) if i % 100 == 0: print i @@ -83,11 +79,11 @@ class Command(NoArgsCommand): return - nModelA.objects.all().delete() - a = nModelA.objects.create(field1='A1') - b = nModelB.objects.create(field1='B1', field2='B2') - c = nModelC.objects.create(field1='C1', field2='C2', field3='C3') - qs = ModelA.objects.raw("SELECT * from pexp_modela") + NormalModelA.objects.all().delete() + a = NormalModelA.objects.create(field1='A1') + b = NormalModelB.objects.create(field1='B1', field2='B2') + c = NormalModelC.objects.create(field1='C1', field2='C2', field3='C3') + qs = TestModelA.objects.raw("SELECT * from pexp_testmodela") for o in list(qs): print o @@ -99,14 +95,14 @@ rnd = Random() def poly_sql_query(): cursor = connection.cursor() cursor.execute(""" - SELECT id, pexp_modela.field1, pexp_modelb.field2, pexp_modelc.field3 - FROM pexp_modela - LEFT OUTER JOIN pexp_modelb - ON pexp_modela.id = pexp_modelb.modela_ptr_id - LEFT OUTER JOIN pexp_modelc - ON pexp_modelb.modela_ptr_id = pexp_modelc.modelb_ptr_id - WHERE pexp_modela.field1=%i - ORDER BY pexp_modela.id + SELECT id, pexp_testmodela.field1, pexp_testmodelb.field2, pexp_testmodelc.field3 + FROM pexp_testmodela + LEFT OUTER JOIN pexp_testmodelb + ON pexp_testmodela.id = pexp_testmodelb.testmodela_ptr_id + LEFT OUTER JOIN pexp_testmodelc + ON pexp_testmodelb.testmodela_ptr_id = pexp_testmodelc.testmodelb_ptr_id + WHERE pexp_testmodela.field1=%i + ORDER BY pexp_testmodela.id """ % rnd.randint(0, 100) ) # row=cursor.fetchone() return @@ -115,10 +111,10 @@ def poly_sql_query(): def poly_sql_query2(): cursor = connection.cursor() cursor.execute(""" - SELECT id, pexp_modela.field1 - FROM pexp_modela - WHERE pexp_modela.field1=%i - ORDER BY pexp_modela.id + SELECT id, pexp_testmodela.field1 + FROM pexp_testmodela + WHERE pexp_testmodela.field1=%i + ORDER BY pexp_testmodela.id """ % rnd.randint(0, 100) ) # row=cursor.fetchone() return diff --git a/example/pexp/management/commands/pcmd.py b/example/pexp/management/commands/pcmd.py index e28608e..3d4eae7 100644 --- a/example/pexp/management/commands/pcmd.py +++ b/example/pexp/management/commands/pcmd.py @@ -5,7 +5,6 @@ This module is a scratchpad for general development, testing & debugging. from django.core.management.base import NoArgsCommand from django.db import connection -from pprint import pprint from pexp.models import * @@ -14,14 +13,6 @@ def reset_queries(): connection.queries = [] -def show_queries(): - print - print 'QUERIES:', len(connection.queries) - pprint(connection.queries) - print - connection.queries = [] - - class Command(NoArgsCommand): help = "" @@ -33,9 +24,9 @@ class Command(NoArgsCommand): print Project.objects.all() print - ModelA.objects.all().delete() - a = ModelA.objects.create(field1='A1') - b = ModelB.objects.create(field1='B1', field2='B2') - c = ModelC.objects.create(field1='C1', field2='C2', field3='C3') - print ModelA.objects.all() + TestModelA.objects.all().delete() + a = TestModelA.objects.create(field1='A1') + b = TestModelB.objects.create(field1='B1', field2='B2') + c = TestModelC.objects.create(field1='C1', field2='C2', field3='C3') + print TestModelA.objects.all() print diff --git a/example/pexp/management/commands/polybench.py b/example/pexp/management/commands/polybench.py index 7622178..8ca5913 100644 --- a/example/pexp/management/commands/polybench.py +++ b/example/pexp/management/commands/polybench.py @@ -3,7 +3,6 @@ This module is a scratchpad for general development, testing & debugging """ -import django from django.core.management.base import NoArgsCommand from django.db import connection from pprint import pprint @@ -14,7 +13,7 @@ num_objects = 1000 def reset_queries(): - if django.VERSION < (1, 9): + if django.VERSION < (1, 8): connection.queries = [] else: connection.queries_log.clear() @@ -57,9 +56,9 @@ def print_timing(func, message='', iterations=1): def run_vanilla_any_poly(func, iterations=1): f = print_timing(func, ' ', iterations) - f(nModelC) + f(NormalModelC) f = print_timing(func, 'poly ', iterations) - f(ModelC) + f(TestModelC) ################################################################################### diff --git a/example/pexp/management/commands/polymorphic_create_test_data.py b/example/pexp/management/commands/polymorphic_create_test_data.py index 89217db..2b83b8b 100644 --- a/example/pexp/management/commands/polymorphic_create_test_data.py +++ b/example/pexp/management/commands/polymorphic_create_test_data.py @@ -4,24 +4,10 @@ This module is a scratchpad for general development, testing & debugging """ from django.core.management.base import NoArgsCommand -from django.db import connection -from pprint import pprint from pexp.models import * -def reset_queries(): - connection.queries = [] - - -def show_queries(): - print - print 'QUERIES:', len(connection.queries) - pprint(connection.queries) - print - connection.queries = [] - - class Command(NoArgsCommand): help = "" diff --git a/example/pexp/migrations/0001_initial.py b/example/pexp/migrations/0001_initial.py index 55730d1..6fc7616 100644 --- a/example/pexp/migrations/0001_initial.py +++ b/example/pexp/migrations/0001_initial.py @@ -1,53 +1,28 @@ # -*- coding: utf-8 -*- -# Generated by Django 1.9b1 on 2015-10-23 22:20 from __future__ import unicode_literals from django.db import migrations, models -import django.db.models.deletion import polymorphic.showfields class Migration(migrations.Migration): - initial = True - dependencies = [ ('contenttypes', '0002_remove_content_type_name'), ] operations = [ migrations.CreateModel( - name='Model2A', + name='NormalModelA', fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('field1', models.CharField(max_length=10)), - ], - options={ - 'abstract': False, - }, - ), - migrations.CreateModel( - name='ModelA', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('field1', models.CharField(max_length=10)), - ], - options={ - 'abstract': False, - }, - bases=(polymorphic.showfields.ShowFieldTypeAndContent, models.Model), - ), - migrations.CreateModel( - name='nModelA', - fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('field1', models.CharField(max_length=10)), ], ), migrations.CreateModel( name='Project', fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('topic', models.CharField(max_length=30)), ], options={ @@ -58,18 +33,29 @@ class Migration(migrations.Migration): migrations.CreateModel( name='ProxyBase', fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('title', models.CharField(max_length=200)), - ('polymorphic_ctype', models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='polymorphic_pexp.proxybase_set+', to='contenttypes.ContentType')), + ('polymorphic_ctype', models.ForeignKey(related_name='polymorphic_pexp.proxybase_set+', editable=False, to='contenttypes.ContentType', null=True)), ], options={ 'ordering': ('title',), }, ), + migrations.CreateModel( + name='TestModelA', + fields=[ + ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), + ('field1', models.CharField(max_length=10)), + ], + options={ + 'abstract': False, + }, + bases=(polymorphic.showfields.ShowFieldTypeAndContent, models.Model), + ), migrations.CreateModel( name='UUIDModelA', fields=[ - ('uuid_primary_key', models.UUIDField(primary_key=True, serialize=False)), + ('uuid_primary_key', models.UUIDField(serialize=False, primary_key=True)), ('field1', models.CharField(max_length=10)), ], options={ @@ -80,7 +66,7 @@ class Migration(migrations.Migration): migrations.CreateModel( name='ArtProject', fields=[ - ('project_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='pexp.Project')), + ('project_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='pexp.Project')), ('artist', models.CharField(max_length=30)), ], options={ @@ -89,39 +75,17 @@ class Migration(migrations.Migration): bases=('pexp.project',), ), migrations.CreateModel( - name='Model2B', + name='NormalModelB', fields=[ - ('model2a_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='pexp.Model2A')), + ('normalmodela_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='pexp.NormalModelA')), ('field2', models.CharField(max_length=10)), ], - options={ - 'abstract': False, - }, - bases=('pexp.model2a',), - ), - migrations.CreateModel( - name='ModelB', - fields=[ - ('modela_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='pexp.ModelA')), - ('field2', models.CharField(max_length=10)), - ], - options={ - 'abstract': False, - }, - bases=('pexp.modela',), - ), - migrations.CreateModel( - name='nModelB', - fields=[ - ('nmodela_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='pexp.nModelA')), - ('field2', models.CharField(max_length=10)), - ], - bases=('pexp.nmodela',), + bases=('pexp.normalmodela',), ), migrations.CreateModel( name='ResearchProject', fields=[ - ('project_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='pexp.Project')), + ('project_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='pexp.Project')), ('supervisor', models.CharField(max_length=30)), ], options={ @@ -129,10 +93,21 @@ class Migration(migrations.Migration): }, bases=('pexp.project',), ), + migrations.CreateModel( + name='TestModelB', + fields=[ + ('testmodela_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='pexp.TestModelA')), + ('field2', models.CharField(max_length=10)), + ], + options={ + 'abstract': False, + }, + bases=('pexp.testmodela',), + ), migrations.CreateModel( name='UUIDModelB', fields=[ - ('uuidmodela_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='pexp.UUIDModelA')), + ('uuidmodela_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='pexp.UUIDModelA')), ('field2', models.CharField(max_length=10)), ], options={ @@ -143,22 +118,17 @@ class Migration(migrations.Migration): migrations.AddField( model_name='uuidmodela', name='polymorphic_ctype', - field=models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='polymorphic_pexp.uuidmodela_set+', to='contenttypes.ContentType'), + field=models.ForeignKey(related_name='polymorphic_pexp.uuidmodela_set+', editable=False, to='contenttypes.ContentType', null=True), + ), + migrations.AddField( + model_name='testmodela', + name='polymorphic_ctype', + field=models.ForeignKey(related_name='polymorphic_pexp.testmodela_set+', editable=False, to='contenttypes.ContentType', null=True), ), migrations.AddField( model_name='project', name='polymorphic_ctype', - field=models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='polymorphic_pexp.project_set+', to='contenttypes.ContentType'), - ), - migrations.AddField( - model_name='modela', - name='polymorphic_ctype', - field=models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='polymorphic_pexp.modela_set+', to='contenttypes.ContentType'), - ), - migrations.AddField( - model_name='model2a', - name='polymorphic_ctype', - field=models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='polymorphic_pexp.model2a_set+', to='contenttypes.ContentType'), + field=models.ForeignKey(related_name='polymorphic_pexp.project_set+', editable=False, to='contenttypes.ContentType', null=True), ), migrations.CreateModel( name='ProxyA', @@ -179,39 +149,29 @@ class Migration(migrations.Migration): bases=('pexp.proxybase',), ), migrations.CreateModel( - name='Model2C', + name='NormalModelC', fields=[ - ('model2b_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='pexp.Model2B')), + ('normalmodelb_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='pexp.NormalModelB')), ('field3', models.CharField(max_length=10)), ], + bases=('pexp.normalmodelb',), + ), + migrations.CreateModel( + name='TestModelC', + fields=[ + ('testmodelb_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='pexp.TestModelB')), + ('field3', models.CharField(max_length=10)), + ('field4', models.ManyToManyField(related_name='related_c', to='pexp.TestModelB')), + ], options={ 'abstract': False, }, - bases=('pexp.model2b',), - ), - migrations.CreateModel( - name='ModelC', - fields=[ - ('modelb_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='pexp.ModelB')), - ('field3', models.CharField(max_length=10)), - ], - options={ - 'abstract': False, - }, - bases=('pexp.modelb',), - ), - migrations.CreateModel( - name='nModelC', - fields=[ - ('nmodelb_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='pexp.nModelB')), - ('field3', models.CharField(max_length=10)), - ], - bases=('pexp.nmodelb',), + bases=('pexp.testmodelb',), ), migrations.CreateModel( name='UUIDModelC', fields=[ - ('uuidmodelb_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='pexp.UUIDModelB')), + ('uuidmodelb_ptr', models.OneToOneField(parent_link=True, auto_created=True, primary_key=True, serialize=False, to='pexp.UUIDModelB')), ('field3', models.CharField(max_length=10)), ], options={ diff --git a/example/pexp/migrations/0002_modelc_field4.py b/example/pexp/migrations/0002_modelc_field4.py deleted file mode 100644 index c2eb6bb..0000000 --- a/example/pexp/migrations/0002_modelc_field4.py +++ /dev/null @@ -1,20 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.9b1 on 2015-10-24 01:42 -from __future__ import unicode_literals - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('pexp', '0001_initial'), - ] - - operations = [ - migrations.AddField( - model_name='modelc', - name='field4', - field=models.ManyToManyField(related_name='related_c', to='pexp.ModelB'), - ), - ] diff --git a/example/pexp/models.py b/example/pexp/models.py index b3322bd..f49e9a1 100644 --- a/example/pexp/models.py +++ b/example/pexp/models.py @@ -8,6 +8,7 @@ from polymorphic.showfields import ShowFieldContent, ShowFieldTypeAndContent class Project(ShowFieldContent, PolymorphicModel): + """Polymorphic model""" topic = models.CharField(max_length=30) @@ -19,42 +20,6 @@ class ResearchProject(Project): supervisor = models.CharField(max_length=30) -class ModelA(ShowFieldTypeAndContent, PolymorphicModel): - field1 = models.CharField(max_length=10) - - -class ModelB(ModelA): - field2 = models.CharField(max_length=10) - - -class ModelC(ModelB): - field3 = models.CharField(max_length=10) - field4 = models.ManyToManyField(ModelB, related_name='related_c') - - -class nModelA(models.Model): - field1 = models.CharField(max_length=10) - - -class nModelB(nModelA): - field2 = models.CharField(max_length=10) - - -class nModelC(nModelB): - field3 = models.CharField(max_length=10) - - -class Model2A(PolymorphicModel): - field1 = models.CharField(max_length=10) - - -class Model2B(Model2A): - field2 = models.CharField(max_length=10) - - -class Model2C(Model2B): - field3 = models.CharField(max_length=10) - if django.VERSION < (1, 8): from polymorphic.tools_for_tests import UUIDField else: @@ -62,6 +27,7 @@ else: class UUIDModelA(ShowFieldTypeAndContent, PolymorphicModel): + """UUID as primary key example""" uuid_primary_key = UUIDField(primary_key=True) field1 = models.CharField(max_length=10) @@ -75,6 +41,7 @@ class UUIDModelC(UUIDModelB): class ProxyBase(PolymorphicModel): + """Proxy model example - a single table with multiple types.""" title = models.CharField(max_length=200) def __unicode__(self): @@ -100,3 +67,31 @@ class ProxyB(ProxyBase): def __unicode__(self): return u"".format(self.title) + + +# Internals for management command tests + +class TestModelA(ShowFieldTypeAndContent, PolymorphicModel): + field1 = models.CharField(max_length=10) + + +class TestModelB(TestModelA): + field2 = models.CharField(max_length=10) + + +class TestModelC(TestModelB): + field3 = models.CharField(max_length=10) + field4 = models.ManyToManyField(TestModelB, related_name='related_c') + + +class NormalModelA(models.Model): + """Normal Django inheritance, no polymorphic behavior""" + field1 = models.CharField(max_length=10) + + +class NormalModelB(NormalModelA): + field2 = models.CharField(max_length=10) + + +class NormalModelC(NormalModelB): + field3 = models.CharField(max_length=10)