Fix PEP8 whitespace issues

autopep8 -r polymorphic/ example/ -i
--select=E112,E113,E115,E116,E122,E123,E125,E127,E128,E201,E202,E203,E211,E225,E226,E227,E228,E231,E251,E261,E262,E271,E272,E273,E274,E301,E302,E303,E304,E309,E711,E713,W291,W293,W391
--exclude migrations,south_migrations

(line conditiation fixes: E123,E125,E122,E127,E128)
fix_request_path_info
Diederik van der Boor 2015-12-28 14:53:32 +01:00
parent f656ec438e
commit aaf06c71a5
17 changed files with 304 additions and 180 deletions

View File

@ -75,7 +75,7 @@ INSTALLED_APPS = (
'pexp', # this Django app is for testing and experimentation; not needed otherwise 'pexp', # this Django app is for testing and experimentation; not needed otherwise
) )
if django.VERSION >= (1,7): if django.VERSION >= (1, 7):
TEST_RUNNER = 'django.test.runner.DiscoverRunner' # silence system checks TEST_RUNNER = 'django.test.runner.DiscoverRunner' # silence system checks
# Logging configuration # Logging configuration

View File

@ -14,6 +14,7 @@ class ProjectChildAdmin(PolymorphicChildModelAdmin):
}), }),
) )
class ProjectAdmin(PolymorphicParentModelAdmin): class ProjectAdmin(PolymorphicParentModelAdmin):
base_model = Project base_model = Project
list_filter = (PolymorphicChildModelFilter,) list_filter = (PolymorphicChildModelFilter,)
@ -26,10 +27,10 @@ class ProjectAdmin(PolymorphicParentModelAdmin):
admin.site.register(Project, ProjectAdmin) admin.site.register(Project, ProjectAdmin)
class ModelAChildAdmin(PolymorphicChildModelAdmin): class ModelAChildAdmin(PolymorphicChildModelAdmin):
base_model = ModelA base_model = ModelA
class ModelAAdmin(PolymorphicParentModelAdmin): class ModelAAdmin(PolymorphicParentModelAdmin):
base_model = ModelA base_model = ModelA
list_filter = (PolymorphicChildModelFilter,) list_filter = (PolymorphicChildModelFilter,)
@ -45,6 +46,7 @@ admin.site.register(ModelA, ModelAAdmin)
class Model2AChildAdmin(PolymorphicChildModelAdmin): class Model2AChildAdmin(PolymorphicChildModelAdmin):
base_model = Model2A base_model = Model2A
class Model2AAdmin(PolymorphicParentModelAdmin): class Model2AAdmin(PolymorphicParentModelAdmin):
base_model = Model2A base_model = Model2A
list_filter = (PolymorphicChildModelFilter,) list_filter = (PolymorphicChildModelFilter,)
@ -60,6 +62,7 @@ admin.site.register(Model2A, Model2AAdmin)
class UUIDModelAChildAdmin(PolymorphicChildModelAdmin): class UUIDModelAChildAdmin(PolymorphicChildModelAdmin):
base_model = UUIDModelA base_model = UUIDModelA
class UUIDModelAAdmin(PolymorphicParentModelAdmin): class UUIDModelAAdmin(PolymorphicParentModelAdmin):
base_model = UUIDModelA base_model = UUIDModelA
list_filter = (PolymorphicChildModelFilter,) list_filter = (PolymorphicChildModelFilter,)
@ -75,6 +78,7 @@ admin.site.register(UUIDModelA, UUIDModelAAdmin)
class ProxyChildAdmin(PolymorphicChildModelAdmin): class ProxyChildAdmin(PolymorphicChildModelAdmin):
base_model = ProxyBase base_model = ProxyBase
class ProxyAdmin(PolymorphicParentModelAdmin): class ProxyAdmin(PolymorphicParentModelAdmin):
base_model = ProxyBase base_model = ProxyBase
list_filter = (PolymorphicChildModelFilter,) list_filter = (PolymorphicChildModelFilter,)

View File

@ -8,46 +8,50 @@ import uuid
from django.core.management.base import NoArgsCommand from django.core.management.base import NoArgsCommand
from django.db.models import connection from django.db.models import connection
from pprint import pprint from pprint import pprint
import time,sys import time, sys
from pexp.models import * from pexp.models import *
def reset_queries(): def reset_queries():
connection.queries=[] connection.queries = []
def show_queries(): def show_queries():
print; print 'QUERIES:',len(connection.queries); pprint(connection.queries); print; connection.queries=[] print; print 'QUERIES:', len(connection.queries); pprint(connection.queries); print; connection.queries = []
def print_timing(func, message='', iterations=1): def print_timing(func, message='', iterations=1):
def wrapper(*arg): def wrapper(*arg):
results=[] results = []
reset_queries() reset_queries()
for i in xrange(iterations): for i in xrange(iterations):
t1 = time.time() t1 = time.time()
x = func(*arg) x = func(*arg)
t2 = time.time() t2 = time.time()
results.append((t2-t1)*1000.0) results.append((t2 - t1) * 1000.0)
res_sum=0 res_sum = 0
for r in results: res_sum +=r for r in results: res_sum += r
median = res_sum / len(results) median = res_sum / len(results)
print '%s%-19s: %.4f ms, %i queries (%i times)' % ( print '%s%-19s: %.4f ms, %i queries (%i times)' % (
message,func.func_name, message, func.func_name,
res_sum, res_sum,
len(connection.queries), len(connection.queries),
iterations iterations
) )
sys.stdout.flush() sys.stdout.flush()
return wrapper return wrapper
class Command(NoArgsCommand): class Command(NoArgsCommand):
help = "" help = ""
def handle_noargs(self, **options): def handle_noargs(self, **options):
if False: if False:
ModelA.objects.all().delete() ModelA.objects.all().delete()
a=ModelA.objects.create(field1='A1') a = ModelA.objects.create(field1='A1')
b=ModelB.objects.create(field1='B1', field2='B2') b = ModelB.objects.create(field1='B1', field2='B2')
c=ModelC.objects.create(field1='C1', field2='C2', field3='C3') c = ModelC.objects.create(field1='C1', field2='C2', field3='C3')
reset_queries() reset_queries()
print ModelC.base_objects.all(); print ModelC.base_objects.all();
show_queries() show_queries()
@ -55,29 +59,30 @@ class Command(NoArgsCommand):
if False: if False:
ModelA.objects.all().delete() ModelA.objects.all().delete()
for i in xrange(1000): for i in xrange(1000):
a=ModelA.objects.create(field1=str(i%100)) a = ModelA.objects.create(field1=str(i % 100))
b=ModelB.objects.create(field1=str(i%100), field2=str(i%200)) 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)) c = ModelC.objects.create(field1=str(i % 100), field2=str(i % 200), field3=str(i % 300))
if i%100==0: print i if i % 100 == 0: print i
f=print_timing(poly_sql_query,iterations=1000) f = print_timing(poly_sql_query, iterations=1000)
f() f()
f=print_timing(poly_sql_query2,iterations=1000) f = print_timing(poly_sql_query2, iterations=1000)
f() f()
return return
nModelA.objects.all().delete() nModelA.objects.all().delete()
a=nModelA.objects.create(field1='A1') a = nModelA.objects.create(field1='A1')
b=nModelB.objects.create(field1='B1', field2='B2') b = nModelB.objects.create(field1='B1', field2='B2')
c=nModelC.objects.create(field1='C1', field2='C2', field3='C3') c = nModelC.objects.create(field1='C1', field2='C2', field3='C3')
qs=ModelA.objects.raw("SELECT * from pexp_modela") qs = ModelA.objects.raw("SELECT * from pexp_modela")
for o in list(qs): print o for o in list(qs): print o
from django.db import connection, transaction from django.db import connection, transaction
from random import Random from random import Random
rnd=Random() rnd = Random()
def poly_sql_query(): def poly_sql_query():
cursor = connection.cursor() cursor = connection.cursor()
@ -90,10 +95,11 @@ def poly_sql_query():
ON pexp_modelb.modela_ptr_id = pexp_modelc.modelb_ptr_id ON pexp_modelb.modela_ptr_id = pexp_modelc.modelb_ptr_id
WHERE pexp_modela.field1=%i WHERE pexp_modela.field1=%i
ORDER BY pexp_modela.id ORDER BY pexp_modela.id
""" % rnd.randint(0,100) ) """ % rnd.randint(0, 100) )
#row=cursor.fetchone() #row=cursor.fetchone()
return return
def poly_sql_query2(): def poly_sql_query2():
cursor = connection.cursor() cursor = connection.cursor()
cursor.execute(""" cursor.execute("""
@ -101,6 +107,6 @@ def poly_sql_query2():
FROM pexp_modela FROM pexp_modela
WHERE pexp_modela.field1=%i WHERE pexp_modela.field1=%i
ORDER BY pexp_modela.id ORDER BY pexp_modela.id
""" % rnd.randint(0,100) ) """ % rnd.randint(0, 100) )
#row=cursor.fetchone() #row=cursor.fetchone()
return return

View File

@ -9,27 +9,29 @@ from pprint import pprint
from pexp.models import * from pexp.models import *
def reset_queries(): def reset_queries():
connection.queries=[] connection.queries = []
def show_queries(): def show_queries():
print; print 'QUERIES:',len(connection.queries); pprint(connection.queries); print; connection.queries=[] print; print 'QUERIES:', len(connection.queries); pprint(connection.queries); print; connection.queries = []
class Command(NoArgsCommand): class Command(NoArgsCommand):
help = "" help = ""
def handle_noargs(self, **options): def handle_noargs(self, **options):
Project.objects.all().delete() Project.objects.all().delete()
a=Project.objects.create(topic="John's gathering") a = Project.objects.create(topic="John's gathering")
b=ArtProject.objects.create(topic="Sculpting with Tim", artist="T. Turner") b = ArtProject.objects.create(topic="Sculpting with Tim", artist="T. Turner")
c=ResearchProject.objects.create(topic="Swallow Aerodynamics", supervisor="Dr. Winter") c = ResearchProject.objects.create(topic="Swallow Aerodynamics", supervisor="Dr. Winter")
print Project.objects.all() print Project.objects.all()
print print
ModelA.objects.all().delete() ModelA.objects.all().delete()
a=ModelA.objects.create(field1='A1') a = ModelA.objects.create(field1='A1')
b=ModelB.objects.create(field1='B1', field2='B2') b = ModelB.objects.create(field1='B1', field2='B2')
c=ModelC.objects.create(field1='C1', field2='C2', field3='C3') c = ModelC.objects.create(field1='C1', field2='C2', field3='C3')
print ModelA.objects.all() print ModelA.objects.all()
print print

View File

@ -9,43 +9,47 @@ from pprint import pprint
import sys import sys
from pexp.models import * from pexp.models import *
num_objects=1000 num_objects = 1000
def reset_queries(): def reset_queries():
connection.queries=[] connection.queries = []
def show_queries(): def show_queries():
print; print 'QUERIES:',len(connection.queries); pprint(connection.queries); print; reset_queries() print; print 'QUERIES:', len(connection.queries); pprint(connection.queries); print; reset_queries()
import time import time
################################################################################### ###################################################################################
### benchmark wrappers ### benchmark wrappers
def print_timing(func, message='', iterations=1): def print_timing(func, message='', iterations=1):
def wrapper(*arg): def wrapper(*arg):
results=[] results = []
reset_queries() reset_queries()
for i in xrange(iterations): for i in xrange(iterations):
t1 = time.time() t1 = time.time()
x = func(*arg) x = func(*arg)
t2 = time.time() t2 = time.time()
results.append((t2-t1)*1000.0) results.append((t2 - t1) * 1000.0)
res_sum=0 res_sum = 0
for r in results: res_sum +=r for r in results: res_sum += r
median = res_sum / len(results) median = res_sum / len(results)
print '%s%-19s: %.0f ms, %i queries' % ( print '%s%-19s: %.0f ms, %i queries' % (
message,func.func_name, message, func.func_name,
median, median,
len(connection.queries)/len(results) len(connection.queries) / len(results)
) )
sys.stdout.flush() sys.stdout.flush()
return wrapper return wrapper
def run_vanilla_any_poly(func, iterations=1): def run_vanilla_any_poly(func, iterations=1):
f=print_timing(func,' ', iterations) f = print_timing(func, ' ', iterations)
f(nModelC) f(nModelC)
f=print_timing(func,'poly ', iterations) f = print_timing(func, 'poly ', iterations)
f(ModelC) f(ModelC)
@ -54,30 +58,35 @@ def run_vanilla_any_poly(func, iterations=1):
def bench_create(model): def bench_create(model):
for i in xrange(num_objects): for i in xrange(num_objects):
model.objects.create(field1='abc'+str(i), field2='abcd'+str(i), field3='abcde'+str(i)) model.objects.create(field1='abc' + str(i), field2='abcd' + str(i), field3='abcde' + str(i))
#print 'count:',model.objects.count() #print 'count:',model.objects.count()
def bench_load1(model): def bench_load1(model):
for o in model.objects.all(): for o in model.objects.all():
pass pass
def bench_load1_short(model): def bench_load1_short(model):
for i in xrange(num_objects/100): for i in xrange(num_objects / 100):
for o in model.objects.all()[:100]: for o in model.objects.all()[:100]:
pass pass
def bench_load2(model): def bench_load2(model):
for o in model.objects.all(): for o in model.objects.all():
f1=o.field1 f1 = o.field1
f2=o.field2 f2 = o.field2
f3=o.field3 f3 = o.field3
def bench_load2_short(model): def bench_load2_short(model):
for i in xrange(num_objects/100): for i in xrange(num_objects / 100):
for o in model.objects.all()[:100]: for o in model.objects.all()[:100]:
f1=o.field1 f1 = o.field1
f2=o.field2 f2 = o.field2
f3=o.field3 f3 = o.field3
def bench_delete(model): def bench_delete(model):
model.objects.all().delete() model.objects.all().delete()
@ -85,19 +94,20 @@ def bench_delete(model):
################################################################################### ###################################################################################
### Command ### Command
class Command(NoArgsCommand): class Command(NoArgsCommand):
help = "" help = ""
def handle_noargs(self, **options): def handle_noargs(self, **options):
func_list = [ func_list = [
( bench_delete, 1 ), (bench_delete, 1),
( bench_create, 1 ), (bench_create, 1),
( bench_load1, 5 ), (bench_load1, 5),
( bench_load1_short, 5 ), (bench_load1_short, 5),
( bench_load2, 5 ), (bench_load2, 5),
( bench_load2_short, 5 ) (bench_load2_short, 5)
] ]
for f,iterations in func_list: for f, iterations in func_list:
run_vanilla_any_poly(f,iterations=iterations) run_vanilla_any_poly(f, iterations=iterations)
print print

View File

@ -9,22 +9,22 @@ from pprint import pprint
from pexp.models import * from pexp.models import *
def reset_queries(): def reset_queries():
connection.queries=[] connection.queries = []
def show_queries(): def show_queries():
print; print 'QUERIES:',len(connection.queries); pprint(connection.queries); print; connection.queries=[] print; print 'QUERIES:', len(connection.queries); pprint(connection.queries); print; connection.queries = []
class Command(NoArgsCommand): class Command(NoArgsCommand):
help = "" help = ""
def handle_noargs(self, **options): def handle_noargs(self, **options):
Project.objects.all().delete() Project.objects.all().delete()
o=Project.objects.create(topic="John's gathering") o = Project.objects.create(topic="John's gathering")
o=ArtProject.objects.create(topic="Sculpting with Tim", artist="T. Turner") o = ArtProject.objects.create(topic="Sculpting with Tim", artist="T. Turner")
o=ResearchProject.objects.create(topic="Swallow Aerodynamics", supervisor="Dr. Winter") o = ResearchProject.objects.create(topic="Swallow Aerodynamics", supervisor="Dr. Winter")
print Project.objects.all() print Project.objects.all()
print print

View File

@ -6,48 +6,74 @@ from django.db import models
from polymorphic.models import PolymorphicModel from polymorphic.models import PolymorphicModel
from polymorphic.showfields import ShowFieldContent, ShowFieldType, ShowFieldTypeAndContent from polymorphic.showfields import ShowFieldContent, ShowFieldType, ShowFieldTypeAndContent
class Project(ShowFieldContent, PolymorphicModel): class Project(ShowFieldContent, PolymorphicModel):
topic = models.CharField(max_length=30) topic = models.CharField(max_length=30)
class ArtProject(Project): class ArtProject(Project):
artist = models.CharField(max_length=30) artist = models.CharField(max_length=30)
class ResearchProject(Project): class ResearchProject(Project):
supervisor = models.CharField(max_length=30) supervisor = models.CharField(max_length=30)
class ModelA(ShowFieldTypeAndContent, PolymorphicModel): class ModelA(ShowFieldTypeAndContent, PolymorphicModel):
field1 = models.CharField(max_length=10) field1 = models.CharField(max_length=10)
class ModelB(ModelA): class ModelB(ModelA):
field2 = models.CharField(max_length=10) field2 = models.CharField(max_length=10)
class ModelC(ModelB): class ModelC(ModelB):
field3 = models.CharField(max_length=10) field3 = models.CharField(max_length=10)
field4 = models.ManyToManyField(ModelB, related_name='related_c') field4 = models.ManyToManyField(ModelB, related_name='related_c')
class nModelA(models.Model): class nModelA(models.Model):
field1 = models.CharField(max_length=10) field1 = models.CharField(max_length=10)
class nModelB(nModelA): class nModelB(nModelA):
field2 = models.CharField(max_length=10) field2 = models.CharField(max_length=10)
class nModelC(nModelB): class nModelC(nModelB):
field3 = models.CharField(max_length=10) field3 = models.CharField(max_length=10)
class Model2A(PolymorphicModel): class Model2A(PolymorphicModel):
field1 = models.CharField(max_length=10) field1 = models.CharField(max_length=10)
class Model2B(Model2A): class Model2B(Model2A):
field2 = models.CharField(max_length=10) field2 = models.CharField(max_length=10)
class Model2C(Model2B): class Model2C(Model2B):
field3 = models.CharField(max_length=10) field3 = models.CharField(max_length=10)
if django.VERSION < (1,8): if django.VERSION < (1, 8):
from polymorphic.tools_for_tests import UUIDField from polymorphic.tools_for_tests import UUIDField
else: else:
from django.db.models import UUIDField from django.db.models import UUIDField
class UUIDModelA(ShowFieldTypeAndContent, PolymorphicModel): class UUIDModelA(ShowFieldTypeAndContent, PolymorphicModel):
uuid_primary_key = UUIDField(primary_key = True) uuid_primary_key = UUIDField(primary_key=True)
field1 = models.CharField(max_length=10) field1 = models.CharField(max_length=10)
class UUIDModelB(UUIDModelA): class UUIDModelB(UUIDModelA):
field2 = models.CharField(max_length=10) field2 = models.CharField(max_length=10)
class UUIDModelC(UUIDModelB): class UUIDModelC(UUIDModelB):
field3 = models.CharField(max_length=10) field3 = models.CharField(max_length=10)
class ProxyBase(PolymorphicModel): class ProxyBase(PolymorphicModel):
title = models.CharField(max_length=200) title = models.CharField(max_length=200)
@ -57,14 +83,18 @@ class ProxyBase(PolymorphicModel):
class Meta: class Meta:
ordering = ('title',) ordering = ('title',)
class ProxyA(ProxyBase): class ProxyA(ProxyBase):
class Meta: class Meta:
proxy = True proxy = True
def __unicode__(self): def __unicode__(self):
return u"<ProxyA: {0}>".format(self.title) return u"<ProxyA: {0}>".format(self.title)
class ProxyB(ProxyBase): class ProxyB(ProxyBase):
class Meta: class Meta:
proxy = True proxy = True

View File

@ -29,9 +29,9 @@ if django.VERSION[:2] < (1, 5):
ct = self._get_from_cache(opts) ct = self._get_from_cache(opts)
except KeyError: except KeyError:
ct, created = self.get_or_create( ct, created = self.get_or_create(
app_label = opts.app_label, app_label=opts.app_label,
model = opts.object_name.lower(), model=opts.object_name.lower(),
defaults = {'name': smart_text(opts.verbose_name_raw)}, defaults={'name': smart_text(opts.verbose_name_raw)},
) )
self._add_to_cache(self.db, ct) self._add_to_cache(self.db, ct)
@ -39,4 +39,3 @@ if django.VERSION[:2] < (1, 5):
ContentTypeManager.get_for_model__original = ContentTypeManager.get_for_model ContentTypeManager.get_for_model__original = ContentTypeManager.get_for_model
ContentTypeManager.get_for_model = get_for_model ContentTypeManager.get_for_model = get_for_model

View File

@ -42,6 +42,7 @@ class RegistrationClosed(RuntimeError):
"The admin model can't be registered anymore at this point." "The admin model can't be registered anymore at this point."
pass pass
class ChildAdminNotRegistered(RuntimeError): class ChildAdminNotRegistered(RuntimeError):
"The admin site for the model is not registered." "The admin site for the model is not registered."
pass pass
@ -122,13 +123,11 @@ class PolymorphicParentModelAdmin(admin.ModelAdmin):
#: If your primary key consists of string values, update this regular expression. #: If your primary key consists of string values, update this regular expression.
pk_regex = '(\d+|__fk__)' pk_regex = '(\d+|__fk__)'
def __init__(self, model, admin_site, *args, **kwargs): def __init__(self, model, admin_site, *args, **kwargs):
super(PolymorphicParentModelAdmin, self).__init__(model, admin_site, *args, **kwargs) super(PolymorphicParentModelAdmin, self).__init__(model, admin_site, *args, **kwargs)
self._child_admin_site = self.admin_site.__class__(name=self.admin_site.name) self._child_admin_site = self.admin_site.__class__(name=self.admin_site.name)
self._is_setup = False self._is_setup = False
def _lazy_setup(self): def _lazy_setup(self):
if self._is_setup: if self._is_setup:
return return
@ -150,7 +149,6 @@ class PolymorphicParentModelAdmin(admin.ModelAdmin):
self._child_admin_site._registry = complete_registry self._child_admin_site._registry = complete_registry
self._is_setup = True self._is_setup = True
def register_child(self, model, model_admin): def register_child(self, model, model_admin):
""" """
Register a model with admin to display. Register a model with admin to display.
@ -167,7 +165,6 @@ class PolymorphicParentModelAdmin(admin.ModelAdmin):
self._child_admin_site.register(model, model_admin) self._child_admin_site.register(model, model_admin)
def get_child_models(self): def get_child_models(self):
""" """
Return the derived model classes which this admin should handle. Return the derived model classes which this admin should handle.
@ -181,7 +178,6 @@ class PolymorphicParentModelAdmin(admin.ModelAdmin):
return self.child_models return self.child_models
def get_child_type_choices(self, request, action): def get_child_type_choices(self, request, action):
""" """
Return a list of polymorphic types for which the user has the permission to perform the given action. Return a list of polymorphic types for which the user has the permission to perform the given action.
@ -197,7 +193,6 @@ class PolymorphicParentModelAdmin(admin.ModelAdmin):
choices.append((ct.id, model._meta.verbose_name)) choices.append((ct.id, model._meta.verbose_name))
return choices return choices
def _get_real_admin(self, object_id): def _get_real_admin(self, object_id):
try: try:
obj = self.model.objects.non_polymorphic() \ obj = self.model.objects.non_polymorphic() \
@ -206,7 +201,6 @@ class PolymorphicParentModelAdmin(admin.ModelAdmin):
raise Http404 raise Http404
return self._get_real_admin_by_ct(obj['polymorphic_ctype']) return self._get_real_admin_by_ct(obj['polymorphic_ctype'])
def _get_real_admin_by_ct(self, ct_id): def _get_real_admin_by_ct(self, ct_id):
try: try:
ct = ContentType.objects.get_for_id(ct_id) ct = ContentType.objects.get_for_id(ct_id)
@ -219,7 +213,6 @@ class PolymorphicParentModelAdmin(admin.ModelAdmin):
return self._get_real_admin_by_model(model_class) return self._get_real_admin_by_model(model_class)
def _get_real_admin_by_model(self, model_class): def _get_real_admin_by_model(self, model_class):
# In case of a ?ct_id=### parameter, the view is already checked for permissions. # In case of a ?ct_id=### parameter, the view is already checked for permissions.
# Hence, make sure this is a derived object, or risk exposing other admin interfaces. # Hence, make sure this is a derived object, or risk exposing other admin interfaces.
@ -233,7 +226,6 @@ class PolymorphicParentModelAdmin(admin.ModelAdmin):
except KeyError: except KeyError:
raise ChildAdminNotRegistered("No child admin site was registered for a '{0}' model.".format(model_class)) raise ChildAdminNotRegistered("No child admin site was registered for a '{0}' model.".format(model_class))
def get_queryset(self, request): def get_queryset(self, request):
# optimize the list display. # optimize the list display.
qs = super(PolymorphicParentModelAdmin, self).get_queryset(request) qs = super(PolymorphicParentModelAdmin, self).get_queryset(request)
@ -241,7 +233,6 @@ class PolymorphicParentModelAdmin(admin.ModelAdmin):
qs = qs.non_polymorphic() qs = qs.non_polymorphic()
return qs return qs
# For Django 1.5: # For Django 1.5:
def queryset(self, request): def queryset(self, request):
qs = super(PolymorphicParentModelAdmin, self).queryset(request) qs = super(PolymorphicParentModelAdmin, self).queryset(request)
@ -249,7 +240,6 @@ class PolymorphicParentModelAdmin(admin.ModelAdmin):
qs = qs.non_polymorphic() qs = qs.non_polymorphic()
return qs return qs
def add_view(self, request, form_url='', extra_context=None): def add_view(self, request, form_url='', extra_context=None):
"""Redirect the add view to the real admin.""" """Redirect the add view to the real admin."""
ct_id = int(request.GET.get('ct_id', 0)) ct_id = int(request.GET.get('ct_id', 0))
@ -266,13 +256,11 @@ class PolymorphicParentModelAdmin(admin.ModelAdmin):
) )
return real_admin.add_view(request, form_url, extra_context) return real_admin.add_view(request, form_url, extra_context)
def change_view(self, request, object_id, *args, **kwargs): def change_view(self, request, object_id, *args, **kwargs):
"""Redirect the change view to the real admin.""" """Redirect the change view to the real admin."""
real_admin = self._get_real_admin(object_id) real_admin = self._get_real_admin(object_id)
return real_admin.change_view(request, object_id, *args, **kwargs) return real_admin.change_view(request, object_id, *args, **kwargs)
def delete_view(self, request, object_id, extra_context=None): def delete_view(self, request, object_id, extra_context=None):
"""Redirect the delete view to the real admin.""" """Redirect the delete view to the real admin."""
real_admin = self._get_real_admin(object_id) real_admin = self._get_real_admin(object_id)
@ -331,7 +319,6 @@ class PolymorphicParentModelAdmin(admin.ModelAdmin):
return urls + custom_urls + dummy_urls return urls + custom_urls + dummy_urls
def subclass_view(self, request, path): def subclass_view(self, request, path):
""" """
Forward any request to a custom view of the real admin. Forward any request to a custom view of the real admin.
@ -350,7 +337,6 @@ class PolymorphicParentModelAdmin(admin.ModelAdmin):
ct_id = self.model.objects.values_list('polymorphic_ctype_id', flat=True).get(pk=object_id) ct_id = self.model.objects.values_list('polymorphic_ctype_id', flat=True).get(pk=object_id)
real_admin = self._get_real_admin_by_ct(ct_id) real_admin = self._get_real_admin_by_ct(ct_id)
resolver = RegexURLResolver('^', real_admin.urls) resolver = RegexURLResolver('^', real_admin.urls)
resolvermatch = resolver.resolve(path) # May raise Resolver404 resolvermatch = resolver.resolve(path) # May raise Resolver404
@ -359,7 +345,6 @@ class PolymorphicParentModelAdmin(admin.ModelAdmin):
return resolvermatch.func(request, *resolvermatch.args, **resolvermatch.kwargs) return resolvermatch.func(request, *resolvermatch.args, **resolvermatch.kwargs)
def add_type_view(self, request, form_url=''): def add_type_view(self, request, form_url=''):
""" """
Display a choice form to select which page type to add. Display a choice form to select which page type to add.
@ -402,7 +387,6 @@ class PolymorphicParentModelAdmin(admin.ModelAdmin):
} }
return self.render_add_type_form(request, context, form_url) return self.render_add_type_form(request, context, form_url)
def render_add_type_form(self, request, context, form_url=''): def render_add_type_form(self, request, context, form_url=''):
""" """
Render the page type choice form. Render the page type choice form.
@ -426,7 +410,6 @@ class PolymorphicParentModelAdmin(admin.ModelAdmin):
"admin/add_type_form.html" "admin/add_type_form.html"
], context, context_instance=context_instance) ], context, context_instance=context_instance)
@property @property
def change_list_template(self): def change_list_template(self):
opts = self.model._meta opts = self.model._meta
@ -446,7 +429,6 @@ class PolymorphicParentModelAdmin(admin.ModelAdmin):
] ]
class PolymorphicChildModelAdmin(admin.ModelAdmin): class PolymorphicChildModelAdmin(admin.ModelAdmin):
""" """
The *optional* base class for the admin interface of derived models. The *optional* base class for the admin interface of derived models.
@ -465,7 +447,6 @@ class PolymorphicChildModelAdmin(admin.ModelAdmin):
base_fieldsets = None base_fieldsets = None
extra_fieldset_title = _("Contents") # Default title for extra fieldset extra_fieldset_title = _("Contents") # Default title for extra fieldset
def get_form(self, request, obj=None, **kwargs): def get_form(self, request, obj=None, **kwargs):
# The django admin validation requires the form to have a 'class Meta: model = ..' # The django admin validation requires the form to have a 'class Meta: model = ..'
# attribute, or it will complain that the fields are missing. # attribute, or it will complain that the fields are missing.
@ -482,7 +463,6 @@ class PolymorphicChildModelAdmin(admin.ModelAdmin):
return super(PolymorphicChildModelAdmin, self).get_form(request, obj, **kwargs) return super(PolymorphicChildModelAdmin, self).get_form(request, obj, **kwargs)
@property @property
def change_form_template(self): def change_form_template(self):
opts = self.model._meta opts = self.model._meta
@ -502,7 +482,6 @@ class PolymorphicChildModelAdmin(admin.ModelAdmin):
"admin/change_form.html" "admin/change_form.html"
] ]
@property @property
def delete_confirmation_template(self): def delete_confirmation_template(self):
opts = self.model._meta opts = self.model._meta
@ -522,21 +501,18 @@ class PolymorphicChildModelAdmin(admin.ModelAdmin):
"admin/delete_confirmation.html" "admin/delete_confirmation.html"
] ]
def render_change_form(self, request, context, add=False, change=False, form_url='', obj=None): def render_change_form(self, request, context, add=False, change=False, form_url='', obj=None):
context.update({ context.update({
'base_opts': self.base_model._meta, 'base_opts': self.base_model._meta,
}) })
return super(PolymorphicChildModelAdmin, self).render_change_form(request, context, add=add, change=change, form_url=form_url, obj=obj) return super(PolymorphicChildModelAdmin, self).render_change_form(request, context, add=add, change=change, form_url=form_url, obj=obj)
def delete_view(self, request, object_id, context=None): def delete_view(self, request, object_id, context=None):
extra_context = { extra_context = {
'base_opts': self.base_model._meta, 'base_opts': self.base_model._meta,
} }
return super(PolymorphicChildModelAdmin, self).delete_view(request, object_id, extra_context) return super(PolymorphicChildModelAdmin, self).delete_view(request, object_id, extra_context)
# ---- Extra: improving the form/fieldset default display ---- # ---- Extra: improving the form/fieldset default display ----
def get_fieldsets(self, request, obj=None): def get_fieldsets(self, request, obj=None):
@ -557,7 +533,6 @@ class PolymorphicChildModelAdmin(admin.ModelAdmin):
else: else:
return self.base_fieldsets return self.base_fieldsets
def get_subclass_fields(self, request, obj=None): def get_subclass_fields(self, request, obj=None):
# Find out how many fields would really be on the form, # Find out how many fields would really be on the form,
# if it weren't restricted by declared fields. # if it weren't restricted by declared fields.

View File

@ -57,7 +57,7 @@ class PolymorphicModelBase(ModelBase):
# Workaround compatibility issue with six.with_metaclass() and custom Django model metaclasses: # Workaround compatibility issue with six.with_metaclass() and custom Django model metaclasses:
if not attrs and model_name == 'NewBase': if not attrs and model_name == 'NewBase':
if django.VERSION < (1,5): if django.VERSION < (1, 5):
# Let Django fully ignore the class which is inserted in between. # Let Django fully ignore the class which is inserted in between.
# Django 1.5 fixed this, see https://code.djangoproject.com/ticket/19688 # Django 1.5 fixed this, see https://code.djangoproject.com/ticket/19688
attrs['__module__'] = 'django.utils.six' attrs['__module__'] = 'django.utils.six'
@ -191,9 +191,9 @@ class PolymorphicModelBase(ModelBase):
# app_label here for PolymorphicModel. # app_label here for PolymorphicModel.
meta = attrs.get('Meta', None) meta = attrs.get('Meta', None)
do_app_label_workaround = (meta do_app_label_workaround = (meta
and attrs['__module__'] == 'polymorphic' and attrs['__module__'] == 'polymorphic'
and model_name == 'PolymorphicModel' and model_name == 'PolymorphicModel'
and getattr(meta, 'app_label', None) is None) and getattr(meta, 'app_label', None) is None)
if do_app_label_workaround: if do_app_label_workaround:
meta.app_label = 'poly_dummy_app_label' meta.app_label = 'poly_dummy_app_label'

View File

@ -26,6 +26,7 @@ from .query_translate import translate_polymorphic_Q_object
################################################################################### ###################################################################################
### PolymorphicModel ### PolymorphicModel
class PolymorphicModel(six.with_metaclass(PolymorphicModelBase, models.Model)): class PolymorphicModel(six.with_metaclass(PolymorphicModelBase, models.Model)):
""" """
Abstract base class that provides polymorphic behaviour Abstract base class that provides polymorphic behaviour
@ -56,7 +57,7 @@ class PolymorphicModel(six.with_metaclass(PolymorphicModelBase, models.Model)):
# avoid ContentType related field accessor clash (an error emitted by model validation) # avoid ContentType related field accessor clash (an error emitted by model validation)
polymorphic_ctype = models.ForeignKey(ContentType, null=True, editable=False, polymorphic_ctype = models.ForeignKey(ContentType, null=True, editable=False,
related_name='polymorphic_%(app_label)s.%(class)s_set+') related_name='polymorphic_%(app_label)s.%(class)s_set+')
# some applications want to know the name of the fields that are added to its models # some applications want to know the name of the fields that are added to its models
polymorphic_internal_model_fields = ['polymorphic_ctype'] polymorphic_internal_model_fields = ['polymorphic_ctype']
@ -110,8 +111,8 @@ class PolymorphicModel(six.with_metaclass(PolymorphicModelBase, models.Model)):
# Protect against bad imports (dumpdata without --natural) or other # Protect against bad imports (dumpdata without --natural) or other
# issues missing with the ContentType models. # issues missing with the ContentType models.
if model is not None \ if model is not None \
and not issubclass(model, self.__class__) \ and not issubclass(model, self.__class__) \
and not issubclass(model, self.__class__._meta.proxy_for_model): and not issubclass(model, self.__class__._meta.proxy_for_model):
raise RuntimeError("ContentType {0} for {1} #{2} does not point to a subclass!".format( raise RuntimeError("ContentType {0} for {1} #{2} does not point to a subclass!".format(
self.polymorphic_ctype_id, model, self.pk, self.polymorphic_ctype_id, model, self.pk,
)) ))
@ -196,22 +197,22 @@ class PolymorphicModel(six.with_metaclass(PolymorphicModelBase, models.Model)):
def add_model_if_regular(model, field_name, result): def add_model_if_regular(model, field_name, result):
if (issubclass(model, models.Model) if (issubclass(model, models.Model)
and model != models.Model and model != models.Model
and model != self.__class__ and model != self.__class__
and model != PolymorphicModel): and model != PolymorphicModel):
add_model(model, field_name, result) add_model(model, field_name, result)
def add_all_super_models(model, result): def add_all_super_models(model, result):
for super_cls, field_to_super in model._meta.parents.items(): for super_cls, field_to_super in model._meta.parents.items():
if field_to_super is not None: #if not a link to a proxy model if field_to_super is not None: # if not a link to a proxy model
field_name = field_to_super.name #the field on model can have a different name to super_cls._meta.module_name, if the field is created manually using 'parent_link' field_name = field_to_super.name # the field on model can have a different name to super_cls._meta.module_name, if the field is created manually using 'parent_link'
add_model_if_regular(super_cls, field_name, result) add_model_if_regular(super_cls, field_name, result)
add_all_super_models(super_cls, result) add_all_super_models(super_cls, result)
def add_all_sub_models(super_cls, result): def add_all_sub_models(super_cls, result):
for sub_cls in super_cls.__subclasses__(): #go through all subclasses of model for sub_cls in super_cls.__subclasses__(): # go through all subclasses of model
if super_cls in sub_cls._meta.parents: #super_cls may not be in sub_cls._meta.parents if super_cls is a proxy model if super_cls in sub_cls._meta.parents: # super_cls may not be in sub_cls._meta.parents if super_cls is a proxy model
field_to_super = sub_cls._meta.parents[super_cls] #get the field that links sub_cls to super_cls field_to_super = sub_cls._meta.parents[super_cls] # get the field that links sub_cls to super_cls
if field_to_super is not None: # if filed_to_super is not a link to a proxy model if field_to_super is not None: # if filed_to_super is not a link to a proxy model
super_to_sub_related_field = field_to_super.rel super_to_sub_related_field = field_to_super.rel
if super_to_sub_related_field.related_name is None: if super_to_sub_related_field.related_name is None:
@ -220,7 +221,7 @@ class PolymorphicModel(six.with_metaclass(PolymorphicModelBase, models.Model)):
else: else:
#otherwise use the given related name #otherwise use the given related name
to_subclass_fieldname = super_to_sub_related_field.related_name to_subclass_fieldname = super_to_sub_related_field.related_name
add_model_if_regular(sub_cls, to_subclass_fieldname, result) add_model_if_regular(sub_cls, to_subclass_fieldname, result)
result = {} result = {}

View File

@ -35,7 +35,7 @@ def transmogrify(cls, obj):
else: else:
# Run constructor, reassign values # Run constructor, reassign values
new = cls() new = cls()
for k,v in obj.__dict__.items(): for k, v in obj.__dict__.items():
new.__dict__[k] = v new.__dict__[k] = v
return new return new
@ -72,7 +72,7 @@ class PolymorphicQuerySet(QuerySet):
new.polymorphic_disabled = self.polymorphic_disabled new.polymorphic_disabled = self.polymorphic_disabled
return new return new
if django.VERSION >= (1,7): if django.VERSION >= (1, 7):
def as_manager(cls): def as_manager(cls):
# Make sure the Django 1.7 way of creating managers works. # Make sure the Django 1.7 way of creating managers works.
from .manager import PolymorphicManager from .manager import PolymorphicManager
@ -333,14 +333,15 @@ class PolymorphicQuerySet(QuerySet):
def __repr__(self, *args, **kwargs): def __repr__(self, *args, **kwargs):
if self.model.polymorphic_query_multiline_output: if self.model.polymorphic_query_multiline_output:
result = [repr(o) for o in self.all()] result = [repr(o) for o in self.all()]
return '[ ' + ',\n '.join(result) + ' ]' return '[ ' + ',\n '.join(result) + ' ]'
else: else:
return super(PolymorphicQuerySet, self).__repr__(*args, **kwargs) return super(PolymorphicQuerySet, self).__repr__(*args, **kwargs)
class _p_list_class(list): class _p_list_class(list):
def __repr__(self, *args, **kwargs): def __repr__(self, *args, **kwargs):
result = [repr(o) for o in self] result = [repr(o) for o in self]
return '[ ' + ',\n '.join(result) + ' ]' return '[ ' + ',\n '.join(result) + ' ]'
def get_real_instances(self, base_result_objects=None): def get_real_instances(self, base_result_objects=None):
"same as _get_real_instances, but make sure that __repr__ for ShowField... creates correct output" "same as _get_real_instances, but make sure that __repr__ for ShowField... creates correct output"

View File

@ -248,7 +248,7 @@ def _create_model_filter_Q(modellist, not_instance_of=False):
q = q | q_class_with_subclasses(subclass) q = q | q_class_with_subclasses(subclass)
return q return q
qlist = [q_class_with_subclasses(m) for m in modellist] qlist = [q_class_with_subclasses(m) for m in modellist]
q_ored = reduce(lambda a, b: a | b, qlist) q_ored = reduce(lambda a, b: a | b, qlist)
if not_instance_of: if not_instance_of:

View File

@ -3,6 +3,7 @@
from django.db import models from django.db import models
from django.utils import six from django.utils import six
class ShowFieldBase(object): class ShowFieldBase(object):
""" base class for the ShowField... model mixins, does the work """ """ base class for the ShowField... model mixins, does the work """
@ -119,8 +120,8 @@ class ShowFieldBase(object):
next_new_section, _, _ = parts[i + 1] next_new_section, _, _ = parts[i + 1]
if (self.polymorphic_showfield_max_line_width if (self.polymorphic_showfield_max_line_width
and xpos + len(p) > self.polymorphic_showfield_max_line_width and xpos + len(p) > self.polymorphic_showfield_max_line_width
and possible_line_break_pos != None): and possible_line_break_pos != None):
rest = out[possible_line_break_pos:] rest = out[possible_line_break_pos:]
out = out[:possible_line_break_pos] out = out[:possible_line_break_pos]
out += '\n' + indentstr + rest out += '\n' + indentstr + rest

View File

@ -5,6 +5,7 @@ register = Library()
class BreadcrumbScope(Node): class BreadcrumbScope(Node):
def __init__(self, base_opts, nodelist): def __init__(self, base_opts, nodelist):
self.base_opts = base_opts self.base_opts = base_opts
self.nodelist = nodelist # Note, takes advantage of Node.child_nodelists self.nodelist = nodelist # Note, takes advantage of Node.child_nodelists
@ -25,7 +26,6 @@ class BreadcrumbScope(Node):
else: else:
raise TemplateSyntaxError("{0} tag expects 1 argument".format(token.contents[0])) raise TemplateSyntaxError("{0} tag expects 1 argument".format(token.contents[0]))
def render(self, context): def render(self, context):
# app_label is really hard to overwrite in the standard Django ModelAdmin. # app_label is really hard to overwrite in the standard Django ModelAdmin.
# To insert it in the template, the entire render_change_form() and delete_view() have to copied and adjusted. # To insert it in the template, the entire render_change_form() and delete_view() have to copied and adjusted.

View File

@ -14,7 +14,7 @@ except ImportError:
from django.db.models.query import QuerySet from django.db.models.query import QuerySet
from django.test import TestCase from django.test import TestCase
from django.db.models import Q,Count from django.db.models import Q, Count
from django.db import models from django.db import models
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.utils import six from django.utils import six
@ -32,85 +32,133 @@ except ImportError:
class PlainA(models.Model): class PlainA(models.Model):
field1 = models.CharField(max_length=10) field1 = models.CharField(max_length=10)
class PlainB(PlainA): class PlainB(PlainA):
field2 = models.CharField(max_length=10) field2 = models.CharField(max_length=10)
class PlainC(PlainB): class PlainC(PlainB):
field3 = models.CharField(max_length=10) field3 = models.CharField(max_length=10)
class Model2A(ShowFieldType, PolymorphicModel): class Model2A(ShowFieldType, PolymorphicModel):
field1 = models.CharField(max_length=10) field1 = models.CharField(max_length=10)
class Model2B(Model2A): class Model2B(Model2A):
field2 = models.CharField(max_length=10) field2 = models.CharField(max_length=10)
class Model2C(Model2B): class Model2C(Model2B):
field3 = models.CharField(max_length=10) field3 = models.CharField(max_length=10)
class Model2D(Model2C): class Model2D(Model2C):
field4 = models.CharField(max_length=10) field4 = models.CharField(max_length=10)
class ModelExtraA(ShowFieldTypeAndContent, PolymorphicModel): class ModelExtraA(ShowFieldTypeAndContent, PolymorphicModel):
field1 = models.CharField(max_length=10) field1 = models.CharField(max_length=10)
class ModelExtraB(ModelExtraA): class ModelExtraB(ModelExtraA):
field2 = models.CharField(max_length=10) field2 = models.CharField(max_length=10)
class ModelExtraC(ModelExtraB): class ModelExtraC(ModelExtraB):
field3 = models.CharField(max_length=10) field3 = models.CharField(max_length=10)
class ModelExtraExternal(models.Model): class ModelExtraExternal(models.Model):
topic = models.CharField(max_length=10) topic = models.CharField(max_length=10)
class ModelShow1(ShowFieldType,PolymorphicModel):
class ModelShow1(ShowFieldType, PolymorphicModel):
field1 = models.CharField(max_length=10) field1 = models.CharField(max_length=10)
m2m = models.ManyToManyField('self') m2m = models.ManyToManyField('self')
class ModelShow2(ShowFieldContent, PolymorphicModel): class ModelShow2(ShowFieldContent, PolymorphicModel):
field1 = models.CharField(max_length=10) field1 = models.CharField(max_length=10)
m2m = models.ManyToManyField('self') m2m = models.ManyToManyField('self')
class ModelShow3(ShowFieldTypeAndContent, PolymorphicModel): class ModelShow3(ShowFieldTypeAndContent, PolymorphicModel):
field1 = models.CharField(max_length=10) field1 = models.CharField(max_length=10)
m2m = models.ManyToManyField('self') m2m = models.ManyToManyField('self')
class ModelShow1_plain(PolymorphicModel): class ModelShow1_plain(PolymorphicModel):
field1 = models.CharField(max_length=10) field1 = models.CharField(max_length=10)
class ModelShow2_plain(ModelShow1_plain): class ModelShow2_plain(ModelShow1_plain):
field2 = models.CharField(max_length=10) field2 = models.CharField(max_length=10)
class Base(ShowFieldType, PolymorphicModel): class Base(ShowFieldType, PolymorphicModel):
field_b = models.CharField(max_length=10) field_b = models.CharField(max_length=10)
class ModelX(Base): class ModelX(Base):
field_x = models.CharField(max_length=10) field_x = models.CharField(max_length=10)
class ModelY(Base): class ModelY(Base):
field_y = models.CharField(max_length=10) field_y = models.CharField(max_length=10)
class Enhance_Plain(models.Model): class Enhance_Plain(models.Model):
field_p = models.CharField(max_length=10) field_p = models.CharField(max_length=10)
class Enhance_Base(ShowFieldTypeAndContent, PolymorphicModel): class Enhance_Base(ShowFieldTypeAndContent, PolymorphicModel):
base_id = models.AutoField(primary_key=True) base_id = models.AutoField(primary_key=True)
field_b = models.CharField(max_length=10) field_b = models.CharField(max_length=10)
class Enhance_Inherit(Enhance_Base, Enhance_Plain): class Enhance_Inherit(Enhance_Base, Enhance_Plain):
field_i = models.CharField(max_length=10) field_i = models.CharField(max_length=10)
class RelationBase(ShowFieldTypeAndContent, PolymorphicModel): class RelationBase(ShowFieldTypeAndContent, PolymorphicModel):
field_base = models.CharField(max_length=10) field_base = models.CharField(max_length=10)
fk = models.ForeignKey('self', null=True, related_name='relationbase_set') fk = models.ForeignKey('self', null=True, related_name='relationbase_set')
m2m = models.ManyToManyField('self') m2m = models.ManyToManyField('self')
class RelationA(RelationBase): class RelationA(RelationBase):
field_a = models.CharField(max_length=10) field_a = models.CharField(max_length=10)
class RelationB(RelationBase): class RelationB(RelationBase):
field_b = models.CharField(max_length=10) field_b = models.CharField(max_length=10)
class RelationBC(RelationB): class RelationBC(RelationB):
field_c = models.CharField(max_length=10) field_c = models.CharField(max_length=10)
class RelatingModel(models.Model): class RelatingModel(models.Model):
many2many = models.ManyToManyField(Model2A) many2many = models.ManyToManyField(Model2A)
class One2OneRelatingModel(PolymorphicModel): class One2OneRelatingModel(PolymorphicModel):
one2one = models.OneToOneField(Model2A) one2one = models.OneToOneField(Model2A)
field1 = models.CharField(max_length=10) field1 = models.CharField(max_length=10)
class One2OneRelatingModelDerived(One2OneRelatingModel): class One2OneRelatingModelDerived(One2OneRelatingModel):
field2 = models.CharField(max_length=10) field2 = models.CharField(max_length=10)
class MyManagerQuerySet(PolymorphicQuerySet): class MyManagerQuerySet(PolymorphicQuerySet):
def my_queryset_foo(self): def my_queryset_foo(self):
return self.all() # Just a method to prove the existance of the custom queryset. return self.all() # Just a method to prove the existance of the custom queryset.
class MyManager(PolymorphicManager): class MyManager(PolymorphicManager):
queryset_class = MyManagerQuerySet queryset_class = MyManagerQuerySet
@ -120,27 +168,38 @@ class MyManager(PolymorphicManager):
# Django <= 1.5 compatibility # Django <= 1.5 compatibility
get_query_set = get_queryset get_query_set = get_queryset
class ModelWithMyManager(ShowFieldTypeAndContent, Model2A): class ModelWithMyManager(ShowFieldTypeAndContent, Model2A):
objects = MyManager() objects = MyManager()
field4 = models.CharField(max_length=10) field4 = models.CharField(max_length=10)
if django.VERSION >= (1,7): if django.VERSION >= (1, 7):
class ModelWithMyManager2(ShowFieldTypeAndContent, Model2A): class ModelWithMyManager2(ShowFieldTypeAndContent, Model2A):
objects = MyManagerQuerySet.as_manager() objects = MyManagerQuerySet.as_manager()
field4 = models.CharField(max_length=10) field4 = models.CharField(max_length=10)
class MROBase1(ShowFieldType, PolymorphicModel): class MROBase1(ShowFieldType, PolymorphicModel):
objects = MyManager() objects = MyManager()
field1 = models.CharField(max_length=10) # needed as MyManager uses it field1 = models.CharField(max_length=10) # needed as MyManager uses it
class MROBase2(MROBase1): class MROBase2(MROBase1):
pass # Django vanilla inheritance does not inherit MyManager as _default_manager here pass # Django vanilla inheritance does not inherit MyManager as _default_manager here
class MROBase3(models.Model): class MROBase3(models.Model):
objects = PolymorphicManager() objects = PolymorphicManager()
class MRODerived(MROBase2, MROBase3): class MRODerived(MROBase2, MROBase3):
pass pass
class ParentModelWithManager(PolymorphicModel): class ParentModelWithManager(PolymorphicModel):
pass pass
class ChildModelWithManager(PolymorphicModel): class ChildModelWithManager(PolymorphicModel):
# Also test whether foreign keys receive the manager: # Also test whether foreign keys receive the manager:
fk = models.ForeignKey(ParentModelWithManager, related_name='childmodel_set') fk = models.ForeignKey(ParentModelWithManager, related_name='childmodel_set')
@ -148,10 +207,13 @@ class ChildModelWithManager(PolymorphicModel):
class PlainMyManagerQuerySet(QuerySet): class PlainMyManagerQuerySet(QuerySet):
def my_queryset_foo(self): def my_queryset_foo(self):
return self.all() # Just a method to prove the existance of the custom queryset. return self.all() # Just a method to prove the existance of the custom queryset.
class PlainMyManager(models.Manager): class PlainMyManager(models.Manager):
def my_queryset_foo(self): def my_queryset_foo(self):
return self.get_queryset().my_queryset_foo() return self.get_queryset().my_queryset_foo()
@ -161,9 +223,11 @@ class PlainMyManager(models.Manager):
# Django <= 1.5 compatibility # Django <= 1.5 compatibility
get_query_set = get_queryset get_query_set = get_queryset
class PlainParentModelWithManager(models.Model): class PlainParentModelWithManager(models.Model):
pass pass
class PlainChildModelWithManager(models.Model): class PlainChildModelWithManager(models.Model):
fk = models.ForeignKey(PlainParentModelWithManager, related_name='childmodel_set') fk = models.ForeignKey(PlainParentModelWithManager, related_name='childmodel_set')
objects = PlainMyManager() objects = PlainMyManager()
@ -173,82 +237,132 @@ class MgrInheritA(models.Model):
mgrA = models.Manager() mgrA = models.Manager()
mgrA2 = models.Manager() mgrA2 = models.Manager()
field1 = models.CharField(max_length=10) field1 = models.CharField(max_length=10)
class MgrInheritB(MgrInheritA): class MgrInheritB(MgrInheritA):
mgrB = models.Manager() mgrB = models.Manager()
field2 = models.CharField(max_length=10) field2 = models.CharField(max_length=10)
class MgrInheritC(ShowFieldTypeAndContent, MgrInheritB): class MgrInheritC(ShowFieldTypeAndContent, MgrInheritB):
pass pass
class BlogBase(ShowFieldTypeAndContent, PolymorphicModel): class BlogBase(ShowFieldTypeAndContent, PolymorphicModel):
name = models.CharField(max_length=10) name = models.CharField(max_length=10)
class BlogA(BlogBase): class BlogA(BlogBase):
info = models.CharField(max_length=10) info = models.CharField(max_length=10)
class BlogB(BlogBase): class BlogB(BlogBase):
pass pass
class BlogEntry(ShowFieldTypeAndContent, PolymorphicModel): class BlogEntry(ShowFieldTypeAndContent, PolymorphicModel):
blog = models.ForeignKey(BlogA) blog = models.ForeignKey(BlogA)
text = models.CharField(max_length=10) text = models.CharField(max_length=10)
class BlogEntry_limit_choices_to(ShowFieldTypeAndContent, PolymorphicModel): class BlogEntry_limit_choices_to(ShowFieldTypeAndContent, PolymorphicModel):
blog = models.ForeignKey(BlogBase) blog = models.ForeignKey(BlogBase)
text = models.CharField(max_length=10) text = models.CharField(max_length=10)
class ModelFieldNameTest(ShowFieldType, PolymorphicModel): class ModelFieldNameTest(ShowFieldType, PolymorphicModel):
modelfieldnametest = models.CharField(max_length=10) modelfieldnametest = models.CharField(max_length=10)
class InitTestModel(ShowFieldType, PolymorphicModel): class InitTestModel(ShowFieldType, PolymorphicModel):
bar = models.CharField(max_length=100) bar = models.CharField(max_length=100)
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
kwargs['bar'] = self.x() kwargs['bar'] = self.x()
super(InitTestModel, self).__init__(*args, **kwargs) super(InitTestModel, self).__init__(*args, **kwargs)
class InitTestModelSubclass(InitTestModel): class InitTestModelSubclass(InitTestModel):
def x(self): def x(self):
return 'XYZ' return 'XYZ'
# models from github issue # models from github issue
class Top(PolymorphicModel): class Top(PolymorphicModel):
name = models.CharField(max_length=50) name = models.CharField(max_length=50)
class Meta: class Meta:
ordering = ('pk',) ordering = ('pk',)
class Middle(Top): class Middle(Top):
description = models.TextField() description = models.TextField()
class Bottom(Middle): class Bottom(Middle):
author = models.CharField(max_length=50) author = models.CharField(max_length=50)
class UUIDProject(ShowFieldTypeAndContent, PolymorphicModel): class UUIDProject(ShowFieldTypeAndContent, PolymorphicModel):
uuid_primary_key = UUIDField(primary_key = True, default=uuid.uuid1) uuid_primary_key = UUIDField(primary_key=True, default=uuid.uuid1)
topic = models.CharField(max_length = 30) topic = models.CharField(max_length=30)
class UUIDArtProject(UUIDProject): class UUIDArtProject(UUIDProject):
artist = models.CharField(max_length = 30) artist = models.CharField(max_length=30)
class UUIDResearchProject(UUIDProject): class UUIDResearchProject(UUIDProject):
supervisor = models.CharField(max_length = 30) supervisor = models.CharField(max_length=30)
class UUIDPlainA(models.Model): class UUIDPlainA(models.Model):
uuid_primary_key = UUIDField(primary_key = True, default=uuid.uuid1) uuid_primary_key = UUIDField(primary_key=True, default=uuid.uuid1)
field1 = models.CharField(max_length=10) field1 = models.CharField(max_length=10)
class UUIDPlainB(UUIDPlainA): class UUIDPlainB(UUIDPlainA):
field2 = models.CharField(max_length=10) field2 = models.CharField(max_length=10)
class UUIDPlainC(UUIDPlainB): class UUIDPlainC(UUIDPlainB):
field3 = models.CharField(max_length=10) field3 = models.CharField(max_length=10)
# base -> proxy # base -> proxy
class ProxyBase(PolymorphicModel): class ProxyBase(PolymorphicModel):
some_data = models.CharField(max_length=128) some_data = models.CharField(max_length=128)
class ProxyChild(ProxyBase): class ProxyChild(ProxyBase):
class Meta: class Meta:
proxy = True proxy = True
class NonProxyChild(ProxyBase): class NonProxyChild(ProxyBase):
name=models.CharField(max_length=10) name = models.CharField(max_length=10)
# base -> proxy -> real models # base -> proxy -> real models
class ProxiedBase(ShowFieldTypeAndContent, PolymorphicModel): class ProxiedBase(ShowFieldTypeAndContent, PolymorphicModel):
name = models.CharField(max_length=10) name = models.CharField(max_length=10)
class ProxyModelBase(ProxiedBase): class ProxyModelBase(ProxiedBase):
class Meta: class Meta:
proxy = True proxy = True
class ProxyModelA(ProxyModelBase): class ProxyModelA(ProxyModelBase):
field1 = models.CharField(max_length=10) field1 = models.CharField(max_length=10)
class ProxyModelB(ProxyModelBase): class ProxyModelB(ProxyModelBase):
field2 = models.CharField(max_length=10) field2 = models.CharField(max_length=10)
@ -264,11 +378,16 @@ class RelatedNameClash(ShowFieldType, PolymorphicModel):
ctype = models.ForeignKey(ContentType, null=True, editable=False) ctype = models.ForeignKey(ContentType, null=True, editable=False)
#class with a parent_link to superclass, and a related_name back to subclass #class with a parent_link to superclass, and a related_name back to subclass
class TestParentLinkAndRelatedName(ModelShow1_plain): class TestParentLinkAndRelatedName(ModelShow1_plain):
superclass = models.OneToOneField(ModelShow1_plain, parent_link=True, related_name='related_name_subclass') superclass = models.OneToOneField(ModelShow1_plain, parent_link=True, related_name='related_name_subclass')
class CustomPkBase(ShowFieldTypeAndContent, PolymorphicModel): class CustomPkBase(ShowFieldTypeAndContent, PolymorphicModel):
b = models.CharField(max_length=1) b = models.CharField(max_length=1)
class CustomPkInherit(CustomPkBase): class CustomPkInherit(CustomPkBase):
custom_id = models.AutoField(primary_key=True) custom_id = models.AutoField(primary_key=True)
i = models.CharField(max_length=1) i = models.CharField(max_length=1)
@ -323,7 +442,7 @@ class PolymorphicTests(TestCase):
# test ordering for field in one subclass only # test ordering for field in one subclass only
# MySQL and SQLite return this order # MySQL and SQLite return this order
expected1=''' expected1 = '''
[ <BlogA: id 8, name (CharField) "B5", info (CharField) "i5">, [ <BlogA: id 8, name (CharField) "B5", info (CharField) "i5">,
<BlogA: id 7, name (CharField) "B4", info (CharField) "i4">, <BlogA: id 7, name (CharField) "B4", info (CharField) "i4">,
<BlogA: id 6, name (CharField) "B3", info (CharField) "i3">, <BlogA: id 6, name (CharField) "B3", info (CharField) "i3">,
@ -334,7 +453,7 @@ class PolymorphicTests(TestCase):
<BlogB: id 4, name (CharField) "Bb3"> ]''' <BlogB: id 4, name (CharField) "Bb3"> ]'''
# PostgreSQL returns this order # PostgreSQL returns this order
expected2=''' expected2 = '''
[ <BlogB: id 2, name (CharField) "Bb1">, [ <BlogB: id 2, name (CharField) "Bb1">,
<BlogB: id 3, name (CharField) "Bb2">, <BlogB: id 3, name (CharField) "Bb2">,
<BlogB: id 4, name (CharField) "Bb3">, <BlogB: id 4, name (CharField) "Bb3">,
@ -347,7 +466,6 @@ class PolymorphicTests(TestCase):
x = '\n' + repr(BlogBase.objects.order_by('-BlogA___info')) x = '\n' + repr(BlogBase.objects.order_by('-BlogA___info'))
self.assertTrue(x == expected1 or x == expected2) self.assertTrue(x == expected1 or x == expected2)
def test_limit_choices_to(self): def test_limit_choices_to(self):
""" """
this is not really a testcase, as limit_choices_to only affects the Django admin this is not really a testcase, as limit_choices_to only affects the Django admin
@ -359,7 +477,6 @@ class PolymorphicTests(TestCase):
entry1 = BlogEntry_limit_choices_to.objects.create(blog=blog_b, text='bla2') entry1 = BlogEntry_limit_choices_to.objects.create(blog=blog_b, text='bla2')
entry2 = BlogEntry_limit_choices_to.objects.create(blog=blog_b, text='bla2') entry2 = BlogEntry_limit_choices_to.objects.create(blog=blog_b, text='bla2')
def test_primary_key_custom_field_problem(self): def test_primary_key_custom_field_problem(self):
""" """
object retrieval problem occuring with some custom primary key fields (UUIDField as test case) object retrieval problem occuring with some custom primary key fields (UUIDField as test case)
@ -377,7 +494,7 @@ class PolymorphicTests(TestCase):
self.assertIsInstance(a.uuid_primary_key, uuid.UUID) self.assertIsInstance(a.uuid_primary_key, uuid.UUID)
self.assertIsInstance(a.pk, uuid.UUID) self.assertIsInstance(a.pk, uuid.UUID)
res = re.sub(' "(.*?)..", topic',', topic', repr(qs)) res = re.sub(' "(.*?)..", topic', ', topic', repr(qs))
res_exp = """[ <UUIDProject: uuid_primary_key (UUIDField/pk), topic (CharField) "John's gathering">, res_exp = """[ <UUIDProject: uuid_primary_key (UUIDField/pk), topic (CharField) "John's gathering">,
<UUIDArtProject: uuid_primary_key (UUIDField/pk), topic (CharField) "Sculpting with Tim", artist (CharField) "T. Turner">, <UUIDArtProject: uuid_primary_key (UUIDField/pk), topic (CharField) "Sculpting with Tim", artist (CharField) "T. Turner">,
<UUIDResearchProject: uuid_primary_key (UUIDField/pk), topic (CharField) "Swallow Aerodynamics", supervisor (CharField) "Dr. Winter"> ]""" <UUIDResearchProject: uuid_primary_key (UUIDField/pk), topic (CharField) "Swallow Aerodynamics", supervisor (CharField) "Dr. Winter"> ]"""
@ -401,7 +518,6 @@ class PolymorphicTests(TestCase):
Model2C.objects.create(field1='C1', field2='C2', field3='C3') Model2C.objects.create(field1='C1', field2='C2', field3='C3')
Model2D.objects.create(field1='D1', field2='D2', field3='D3', field4='D4') Model2D.objects.create(field1='D1', field2='D2', field3='D3', field4='D4')
def test_simple_inheritance(self): def test_simple_inheritance(self):
self.create_model2abcd() self.create_model2abcd()
@ -411,14 +527,12 @@ class PolymorphicTests(TestCase):
self.assertEqual(repr(objects[2]), '<Model2C: id 3, field1 (CharField), field2 (CharField), field3 (CharField)>') self.assertEqual(repr(objects[2]), '<Model2C: id 3, field1 (CharField), field2 (CharField), field3 (CharField)>')
self.assertEqual(repr(objects[3]), '<Model2D: id 4, field1 (CharField), field2 (CharField), field3 (CharField), field4 (CharField)>') self.assertEqual(repr(objects[3]), '<Model2D: id 4, field1 (CharField), field2 (CharField), field3 (CharField), field4 (CharField)>')
def test_manual_get_real_instance(self): def test_manual_get_real_instance(self):
self.create_model2abcd() self.create_model2abcd()
o = Model2A.objects.non_polymorphic().get(field1='C1') o = Model2A.objects.non_polymorphic().get(field1='C1')
self.assertEqual(repr(o.get_real_instance()), '<Model2C: id 3, field1 (CharField), field2 (CharField), field3 (CharField)>') self.assertEqual(repr(o.get_real_instance()), '<Model2C: id 3, field1 (CharField), field2 (CharField), field3 (CharField)>')
def test_non_polymorphic(self): def test_non_polymorphic(self):
self.create_model2abcd() self.create_model2abcd()
@ -428,7 +542,6 @@ class PolymorphicTests(TestCase):
self.assertEqual(repr(objects[2]), '<Model2A: id 3, field1 (CharField)>') self.assertEqual(repr(objects[2]), '<Model2A: id 3, field1 (CharField)>')
self.assertEqual(repr(objects[3]), '<Model2A: id 4, field1 (CharField)>') self.assertEqual(repr(objects[3]), '<Model2A: id 4, field1 (CharField)>')
def test_get_real_instances(self): def test_get_real_instances(self):
self.create_model2abcd() self.create_model2abcd()
qs = Model2A.objects.all().non_polymorphic() qs = Model2A.objects.all().non_polymorphic()
@ -447,7 +560,6 @@ class PolymorphicTests(TestCase):
self.assertEqual(repr(objects[2]), '<Model2C: id 3, field1 (CharField), field2 (CharField), field3 (CharField)>') self.assertEqual(repr(objects[2]), '<Model2C: id 3, field1 (CharField), field2 (CharField), field3 (CharField)>')
self.assertEqual(repr(objects[3]), '<Model2D: id 4, field1 (CharField), field2 (CharField), field3 (CharField), field4 (CharField)>') self.assertEqual(repr(objects[3]), '<Model2D: id 4, field1 (CharField), field2 (CharField), field3 (CharField), field4 (CharField)>')
def test_translate_polymorphic_q_object(self): def test_translate_polymorphic_q_object(self):
self.create_model2abcd() self.create_model2abcd()
@ -456,7 +568,6 @@ class PolymorphicTests(TestCase):
self.assertEqual(repr(objects[0]), '<Model2C: id 3, field1 (CharField), field2 (CharField), field3 (CharField)>') self.assertEqual(repr(objects[0]), '<Model2C: id 3, field1 (CharField), field2 (CharField), field3 (CharField)>')
self.assertEqual(repr(objects[1]), '<Model2D: id 4, field1 (CharField), field2 (CharField), field3 (CharField), field4 (CharField)>') self.assertEqual(repr(objects[1]), '<Model2D: id 4, field1 (CharField), field2 (CharField), field3 (CharField), field4 (CharField)>')
def test_base_manager(self): def test_base_manager(self):
def show_base_manager(model): def show_base_manager(model):
return "{0} {1}".format( return "{0} {1}".format(
@ -475,7 +586,6 @@ class PolymorphicTests(TestCase):
self.assertEqual(show_base_manager(One2OneRelatingModel), "<class 'polymorphic.manager.PolymorphicManager'> <class 'polymorphic.tests.One2OneRelatingModel'>") self.assertEqual(show_base_manager(One2OneRelatingModel), "<class 'polymorphic.manager.PolymorphicManager'> <class 'polymorphic.tests.One2OneRelatingModel'>")
self.assertEqual(show_base_manager(One2OneRelatingModelDerived), "<class 'django.db.models.manager.Manager'> <class 'polymorphic.tests.One2OneRelatingModelDerived'>") self.assertEqual(show_base_manager(One2OneRelatingModelDerived), "<class 'django.db.models.manager.Manager'> <class 'polymorphic.tests.One2OneRelatingModelDerived'>")
def test_instance_default_manager(self): def test_instance_default_manager(self):
def show_default_manager(instance): def show_default_manager(instance):
return "{0} {1}".format( return "{0} {1}".format(
@ -508,7 +618,6 @@ class PolymorphicTests(TestCase):
object2b = Model2B.base_objects.get(field1='C1') object2b = Model2B.base_objects.get(field1='C1')
self.assertEqual(repr(object2b.model2c), '<Model2C: id 3, field1 (CharField), field2 (CharField), field3 (CharField)>') self.assertEqual(repr(object2b.model2c), '<Model2C: id 3, field1 (CharField), field2 (CharField), field3 (CharField)>')
def test_onetoone_field(self): def test_onetoone_field(self):
self.create_model2abcd() self.create_model2abcd()
@ -522,7 +631,6 @@ class PolymorphicTests(TestCase):
self.assertEqual(repr(c.one2one), '<Model2C: id 3, field1 (CharField), field2 (CharField), field3 (CharField)>') self.assertEqual(repr(c.one2one), '<Model2C: id 3, field1 (CharField), field2 (CharField), field3 (CharField)>')
self.assertEqual(repr(a.one2onerelatingmodel), '<One2OneRelatingModelDerived: One2OneRelatingModelDerived object>') self.assertEqual(repr(a.one2onerelatingmodel), '<One2OneRelatingModelDerived: One2OneRelatingModelDerived object>')
def test_manytomany_field(self): def test_manytomany_field(self):
# Model 1 # Model 1
o = ModelShow1.objects.create(field1='abc') o = ModelShow1.objects.create(field1='abc')
@ -537,7 +645,7 @@ class PolymorphicTests(TestCase):
self.assertEqual(repr(ModelShow2.objects.all()), '[ <ModelShow2: id 1, field1 "abc", m2m 1> ]') self.assertEqual(repr(ModelShow2.objects.all()), '[ <ModelShow2: id 1, field1 "abc", m2m 1> ]')
# Model 3 # Model 3
o=ModelShow3.objects.create(field1='abc') o = ModelShow3.objects.create(field1='abc')
o.m2m.add(o) o.m2m.add(o)
o.save() o.save()
self.assertEqual(repr(ModelShow3.objects.all()), '[ <ModelShow3: id 1, field1 (CharField) "abc", m2m (ManyToManyField) 1> ]') self.assertEqual(repr(ModelShow3.objects.all()), '[ <ModelShow3: id 1, field1 (CharField) "abc", m2m (ManyToManyField) 1> ]')
@ -550,7 +658,6 @@ class PolymorphicTests(TestCase):
ModelShow2_plain.objects.create(field1='abc', field2='def') ModelShow2_plain.objects.create(field1='abc', field2='def')
self.assertEqual(repr(ModelShow1_plain.objects.all()), '[<ModelShow1_plain: ModelShow1_plain object>, <ModelShow2_plain: ModelShow2_plain object>]') self.assertEqual(repr(ModelShow1_plain.objects.all()), '[<ModelShow1_plain: ModelShow1_plain object>, <ModelShow2_plain: ModelShow2_plain object>]')
def test_extra_method(self): def test_extra_method(self):
self.create_model2abcd() self.create_model2abcd()
@ -569,7 +676,7 @@ class PolymorphicTests(TestCase):
ModelExtraExternal.objects.create(topic='extra1') ModelExtraExternal.objects.create(topic='extra1')
ModelExtraExternal.objects.create(topic='extra2') ModelExtraExternal.objects.create(topic='extra2')
ModelExtraExternal.objects.create(topic='extra3') ModelExtraExternal.objects.create(topic='extra3')
objects = ModelExtraA.objects.extra(tables=["polymorphic_modelextraexternal"], select={"topic":"polymorphic_modelextraexternal.topic"}, where=["polymorphic_modelextraa.id = polymorphic_modelextraexternal.id"]) objects = ModelExtraA.objects.extra(tables=["polymorphic_modelextraexternal"], select={"topic": "polymorphic_modelextraexternal.topic"}, where=["polymorphic_modelextraa.id = polymorphic_modelextraexternal.id"])
if six.PY3: if six.PY3:
self.assertEqual(repr(objects[0]), '<ModelExtraA: id 1, field1 (CharField) "A1" - Extra: topic (str) "extra1">') self.assertEqual(repr(objects[0]), '<ModelExtraA: id 1, field1 (CharField) "A1" - Extra: topic (str) "extra1">')
self.assertEqual(repr(objects[1]), '<ModelExtraB: id 2, field1 (CharField) "B1", field2 (CharField) "B2" - Extra: topic (str) "extra2">') self.assertEqual(repr(objects[1]), '<ModelExtraB: id 2, field1 (CharField) "B1", field2 (CharField) "B2" - Extra: topic (str) "extra2">')
@ -580,7 +687,6 @@ class PolymorphicTests(TestCase):
self.assertEqual(repr(objects[2]), '<ModelExtraC: id 3, field1 (CharField) "C1", field2 (CharField) "C2", field3 (CharField) "C3" - Extra: topic (unicode) "extra3">') self.assertEqual(repr(objects[2]), '<ModelExtraC: id 3, field1 (CharField) "C1", field2 (CharField) "C2", field3 (CharField) "C3" - Extra: topic (unicode) "extra3">')
self.assertEqual(len(objects), 3) self.assertEqual(len(objects), 3)
def test_instance_of_filter(self): def test_instance_of_filter(self):
self.create_model2abcd() self.create_model2abcd()
@ -606,16 +712,14 @@ class PolymorphicTests(TestCase):
self.assertEqual(repr(objects[0]), '<Model2A: id 1, field1 (CharField)>') self.assertEqual(repr(objects[0]), '<Model2A: id 1, field1 (CharField)>')
self.assertEqual(len(objects), 1) self.assertEqual(len(objects), 1)
def test_polymorphic___filter(self): def test_polymorphic___filter(self):
self.create_model2abcd() self.create_model2abcd()
objects = Model2A.objects.filter(Q( Model2B___field2='B2') | Q( Model2C___field3='C3')) objects = Model2A.objects.filter(Q(Model2B___field2='B2') | Q(Model2C___field3='C3'))
self.assertEqual(len(objects), 2) self.assertEqual(len(objects), 2)
self.assertEqual(repr(objects[0]), '<Model2B: id 2, field1 (CharField), field2 (CharField)>') self.assertEqual(repr(objects[0]), '<Model2B: id 2, field1 (CharField), field2 (CharField)>')
self.assertEqual(repr(objects[1]), '<Model2C: id 3, field1 (CharField), field2 (CharField), field3 (CharField)>') self.assertEqual(repr(objects[1]), '<Model2C: id 3, field1 (CharField), field2 (CharField), field3 (CharField)>')
def test_delete(self): def test_delete(self):
self.create_model2abcd() self.create_model2abcd()
@ -630,7 +734,6 @@ class PolymorphicTests(TestCase):
self.assertEqual(repr(objects[2]), '<Model2D: id 4, field1 (CharField), field2 (CharField), field3 (CharField), field4 (CharField)>') self.assertEqual(repr(objects[2]), '<Model2D: id 4, field1 (CharField), field2 (CharField), field3 (CharField), field4 (CharField)>')
self.assertEqual(len(objects), 3) self.assertEqual(len(objects), 3)
def test_combine_querysets(self): def test_combine_querysets(self):
ModelX.objects.create(field_x='x') ModelX.objects.create(field_x='x')
ModelY.objects.create(field_y='y') ModelY.objects.create(field_y='y')
@ -640,7 +743,6 @@ class PolymorphicTests(TestCase):
self.assertEqual(repr(qs[1]), '<ModelY: id 2, field_b (CharField), field_y (CharField)>') self.assertEqual(repr(qs[1]), '<ModelY: id 2, field_b (CharField), field_y (CharField)>')
self.assertEqual(len(qs), 2) self.assertEqual(len(qs), 2)
def test_multiple_inheritance(self): def test_multiple_inheritance(self):
# multiple inheritance, subclassing third party models (mix PolymorphicModel with models.Model) # multiple inheritance, subclassing third party models (mix PolymorphicModel with models.Model)
@ -685,7 +787,6 @@ class PolymorphicTests(TestCase):
self.assertEqual(repr(objects[1]), '<RelationB: id 3, field_base (CharField) "B1", fk (ForeignKey) RelationA, field_b (CharField) "B2", m2m (ManyToManyField) 1>') self.assertEqual(repr(objects[1]), '<RelationB: id 3, field_base (CharField) "B1", fk (ForeignKey) RelationA, field_b (CharField) "B2", m2m (ManyToManyField) 1>')
self.assertEqual(len(objects), 2) self.assertEqual(len(objects), 2)
def test_user_defined_manager(self): def test_user_defined_manager(self):
self.create_model2abcd() self.create_model2abcd()
ModelWithMyManager.objects.create(field1='D1a', field4='D4a') ModelWithMyManager.objects.create(field1='D1a', field4='D4a')
@ -700,7 +801,7 @@ class PolymorphicTests(TestCase):
self.assertIs(type(ModelWithMyManager._default_manager), MyManager) self.assertIs(type(ModelWithMyManager._default_manager), MyManager)
self.assertIs(type(ModelWithMyManager.base_objects), models.Manager) self.assertIs(type(ModelWithMyManager.base_objects), models.Manager)
@skipIf(django.VERSION < (1,7), "This test needs Django 1.7+") @skipIf(django.VERSION < (1, 7), "This test needs Django 1.7+")
def test_user_defined_queryset_as_manager(self): def test_user_defined_queryset_as_manager(self):
self.create_model2abcd() self.create_model2abcd()
ModelWithMyManager2.objects.create(field1='D1a', field4='D4a') ModelWithMyManager2.objects.create(field1='D1a', field4='D4a')
@ -715,7 +816,6 @@ class PolymorphicTests(TestCase):
self.assertEqual(type(ModelWithMyManager2._default_manager).__name__, 'PolymorphicManagerFromMyManagerQuerySet') self.assertEqual(type(ModelWithMyManager2._default_manager).__name__, 'PolymorphicManagerFromMyManagerQuerySet')
self.assertIs(type(ModelWithMyManager2.base_objects), models.Manager) self.assertIs(type(ModelWithMyManager2.base_objects), models.Manager)
def test_manager_inheritance(self): def test_manager_inheritance(self):
# by choice of MRO, should be MyManager from MROBase1. # by choice of MRO, should be MyManager from MROBase1.
self.assertIs(type(MRODerived.objects), MyManager) self.assertIs(type(MRODerived.objects), MyManager)
@ -726,7 +826,6 @@ class PolymorphicTests(TestCase):
# Django vanilla inheritance does not inherit MyManager as _default_manager here # Django vanilla inheritance does not inherit MyManager as _default_manager here
self.assertIs(type(MROBase2._default_manager), MyManager) self.assertIs(type(MROBase2._default_manager), MyManager)
def test_queryset_assignment(self): def test_queryset_assignment(self):
# This is just a consistency check for now, testing standard Django behavior. # This is just a consistency check for now, testing standard Django behavior.
parent = PlainParentModelWithManager.objects.create() parent = PlainParentModelWithManager.objects.create()
@ -750,7 +849,6 @@ class PolymorphicTests(TestCase):
# A related set is created using the model's _default_manager, so does gain extra methods. # A related set is created using the model's _default_manager, so does gain extra methods.
self.assertIs(type(parent.childmodel_set.my_queryset_foo()), MyManagerQuerySet) self.assertIs(type(parent.childmodel_set.my_queryset_foo()), MyManagerQuerySet)
def test_proxy_models(self): def test_proxy_models(self):
# prepare some data # prepare some data
for data in ('bleep bloop', 'I am a', 'computer'): for data in ('bleep bloop', 'I am a', 'computer'):
@ -771,7 +869,7 @@ class PolymorphicTests(TestCase):
This unit test guards that this check is working properly. For instance, This unit test guards that this check is working properly. For instance,
proxy child models need to be handled separately. proxy child models need to be handled separately.
""" """
name="Item1" name = "Item1"
nonproxychild = NonProxyChild.objects.create(name=name) nonproxychild = NonProxyChild.objects.create(name=name)
pb = ProxyBase.objects.get(id=1) pb = ProxyBase.objects.get(id=1)
@ -792,7 +890,6 @@ class PolymorphicTests(TestCase):
ct = ContentType.objects.get_for_model(ProxyChild, for_concrete_model=False) ct = ContentType.objects.get_for_model(ProxyChild, for_concrete_model=False)
self.assertEqual(ProxyChild, ct.model_class()) self.assertEqual(ProxyChild, ct.model_class())
def test_proxy_model_inheritance(self): def test_proxy_model_inheritance(self):
""" """
Polymorphic abilities should also work when the base model is a proxy object. Polymorphic abilities should also work when the base model is a proxy object.
@ -852,7 +949,7 @@ class PolymorphicTests(TestCase):
#check that the accessors to parent and sublass work correctly and return the right object #check that the accessors to parent and sublass work correctly and return the right object
p = ModelShow1_plain.objects.non_polymorphic().get(field1="TestParentLinkAndRelatedName") p = ModelShow1_plain.objects.non_polymorphic().get(field1="TestParentLinkAndRelatedName")
self.assertNotEqual(p, t) #p should be Plain1 and t TestParentLinkAndRelatedName, so not equal self.assertNotEqual(p, t) # p should be Plain1 and t TestParentLinkAndRelatedName, so not equal
self.assertEqual(p, t.superclass) self.assertEqual(p, t.superclass)
self.assertEqual(p.related_name_subclass, t) self.assertEqual(p.related_name_subclass, t)
@ -860,7 +957,6 @@ class PolymorphicTests(TestCase):
t.delete() t.delete()
class RegressionTests(TestCase): class RegressionTests(TestCase):
def test_for_query_result_incomplete_with_inheritance(self): def test_for_query_result_incomplete_with_inheritance(self):
@ -881,4 +977,3 @@ class RegressionTests(TestCase):
expected_queryset = [bottom] expected_queryset = [bottom]
self.assertQuerysetEqual(Bottom.objects.all(), [repr(r) for r in expected_queryset]) self.assertQuerysetEqual(Bottom.objects.all(), [repr(r) for r in expected_queryset])

View File

@ -63,7 +63,7 @@ class UUIDField(six.with_metaclass(models.SubfieldBase, models.CharField)):
self.namespace, self.name = namespace, name self.namespace, self.name = namespace, name
super(UUIDField, self).__init__(verbose_name=verbose_name, super(UUIDField, self).__init__(verbose_name=verbose_name,
name=name, **kwargs) name=name, **kwargs)
def create_uuid(self): def create_uuid(self):
if not self.version or self.version == 4: if not self.version or self.version == 4:
@ -139,6 +139,6 @@ class UUIDField(six.with_metaclass(models.SubfieldBase, models.CharField)):
defaults = { defaults = {
'form_class': forms.CharField, 'form_class': forms.CharField,
'max_length': self.max_length 'max_length': self.max_length
} }
defaults.update(kwargs) defaults.update(kwargs)
return super(UUIDField, self).formfield(**defaults) return super(UUIDField, self).formfield(**defaults)