Replaced the doctests with unit tests

Making debugging tests much easier. The same repr() logic is preserved,
so this is essentually a huge coding style change.
fix_request_path_info
Diederik van der Boor 2013-04-05 11:33:41 +02:00
parent 32426aa41a
commit 25aa32d7bd
1 changed files with 258 additions and 248 deletions

View File

@ -201,16 +201,21 @@ class RelatedNameClash(ShowFieldType, PolymorphicModel):
ctype = models.ForeignKey(ContentType, null=True, editable=False)
class testclass(TestCase):
class PolymorphicTests(TestCase):
"""
The test suite
"""
def test_diamond_inheritance(self):
# Django diamond problem
o = DiamondXY.objects.create(field_b='b', field_x='x', field_y='y')
print 'DiamondXY fields 1: field_b "%s", field_x "%s", field_y "%s"' % (o.field_b, o.field_x, o.field_y)
o = DiamondXY.objects.get()
print 'DiamondXY fields 2: field_b "%s", field_x "%s", field_y "%s"' % (o.field_b, o.field_x, o.field_y)
if o.field_b != 'b':
o1 = DiamondXY.objects.create(field_b='b', field_x='x', field_y='y')
o2 = DiamondXY.objects.get()
if o2.field_b != 'b':
print
print '# known django model inheritance diamond problem detected'
print 'DiamondXY fields 1: field_b "{0}", field_x "{1}", field_y "{2}"'.format(o1.field_b, o1.field_x, o1.field_y)
print 'DiamondXY fields 2: field_b "{0}", field_x "{1}", field_y "{2}"'.format(o2.field_b, o2.field_x, o2.field_y)
def test_annotate_aggregate_order(self):
@ -330,300 +335,305 @@ class testclass(TestCase):
print '# known type inconstency with custom primary key field detected (django problem?)'
def show_base_manager(model):
print type(model._base_manager),model._base_manager.model
__test__ = {"doctest": """
#######################################################
### Tests
>>> settings.DEBUG=True
### simple inheritance
>>> o=Model2A.objects.create(field1='A1')
>>> o=Model2B.objects.create(field1='B1', field2='B2')
>>> o=Model2C.objects.create(field1='C1', field2='C2', field3='C3')
>>> o=Model2D.objects.create(field1='D1', field2='D2', field3='D3', field4='D4')
>>> Model2A.objects.all()
[ <Model2A: id 1, field1 (CharField)>,
<Model2B: id 2, field1 (CharField), field2 (CharField)>,
<Model2C: id 3, field1 (CharField), field2 (CharField), field3 (CharField)>,
<Model2D: id 4, field1 (CharField), field2 (CharField), field3 (CharField), field4 (CharField)> ]
# manual get_real_instance()
>>> o=Model2A.objects.non_polymorphic().get(field1='C1')
>>> o.get_real_instance()
<Model2C: id 3, field1 (CharField), field2 (CharField), field3 (CharField)>
# non_polymorphic()
>>> qs=Model2A.objects.all().non_polymorphic()
>>> qs
[ <Model2A: id 1, field1 (CharField)>,
<Model2A: id 2, field1 (CharField)>,
<Model2A: id 3, field1 (CharField)>,
<Model2A: id 4, field1 (CharField)> ]
# get_real_instances()
>>> qs.get_real_instances()
[ <Model2A: id 1, field1 (CharField)>,
<Model2B: id 2, field1 (CharField), field2 (CharField)>,
<Model2C: id 3, field1 (CharField), field2 (CharField), field3 (CharField)>,
<Model2D: id 4, field1 (CharField), field2 (CharField), field3 (CharField), field4 (CharField)> ]
>>> l=list(qs)
>>> Model2A.objects.get_real_instances(l)
[ <Model2A: id 1, field1 (CharField)>,
<Model2B: id 2, field1 (CharField), field2 (CharField)>,
<Model2C: id 3, field1 (CharField), field2 (CharField), field3 (CharField)>,
<Model2D: id 4, field1 (CharField), field2 (CharField), field3 (CharField), field4 (CharField)> ]
# translate_polymorphic_Q_object
>>> q=Model2A.translate_polymorphic_Q_object( Q(instance_of=Model2C) )
>>> Model2A.objects.filter(q)
[ <Model2C: id 3, field1 (CharField), field2 (CharField), field3 (CharField)>,
<Model2D: id 4, field1 (CharField), field2 (CharField), field3 (CharField), field4 (CharField)> ]
### test inheritance pointers & _base_managers
>>> show_base_manager(PlainA)
<class 'django.db.models.manager.Manager'> <class 'polymorphic.tests.PlainA'>
>>> show_base_manager(PlainB)
<class 'django.db.models.manager.Manager'> <class 'polymorphic.tests.PlainB'>
>>> show_base_manager(PlainC)
<class 'django.db.models.manager.Manager'> <class 'polymorphic.tests.PlainC'>
>>> show_base_manager(Model2A)
<class 'polymorphic.manager.PolymorphicManager'> <class 'polymorphic.tests.Model2A'>
>>> show_base_manager(Model2B)
<class 'django.db.models.manager.Manager'> <class 'polymorphic.tests.Model2B'>
>>> show_base_manager(Model2C)
<class 'django.db.models.manager.Manager'> <class 'polymorphic.tests.Model2C'>
>>> show_base_manager(One2OneRelatingModel)
<class 'polymorphic.manager.PolymorphicManager'> <class 'polymorphic.tests.One2OneRelatingModel'>
>>> show_base_manager(One2OneRelatingModelDerived)
<class 'django.db.models.manager.Manager'> <class 'polymorphic.tests.One2OneRelatingModelDerived'>
>>> o=Model2A.base_objects.get(field1='C1')
>>> o.model2b
<Model2B: id 3, field1 (CharField), field2 (CharField)>
>>> o=Model2B.base_objects.get(field1='C1')
>>> o.model2c
<Model2C: id 3, field1 (CharField), field2 (CharField), field3 (CharField)>
### OneToOneField, test both directions for polymorphism
>>> a=Model2A.base_objects.get(field1='C1')
>>> b=One2OneRelatingModelDerived.objects.create(one2one=a, field1='f1', field2='f2')
>>> b.one2one # this result is basically wrong, probably due to Django cacheing (we used base_objects), but should not be a problem
<Model2A: id 3, field1 (CharField)>
>>> c=One2OneRelatingModelDerived.objects.get(field1='f1')
>>> c.one2one
<Model2C: id 3, field1 (CharField), field2 (CharField), field3 (CharField)>
>>> a.one2onerelatingmodel
<One2OneRelatingModelDerived: One2OneRelatingModelDerived object>
### ShowFieldContent, ShowFieldType, ShowFieldTypeAndContent, also with annotate()
>>> o=ModelShow1.objects.create(field1='abc')
>>> o.m2m.add(o) ; o.save()
>>> ModelShow1.objects.all()
[ <ModelShow1: id 1, field1 (CharField), m2m (ManyToManyField)> ]
>>> o=ModelShow2.objects.create(field1='abc')
>>> o.m2m.add(o) ; o.save()
>>> ModelShow2.objects.all()
[ <ModelShow2: id 1, field1 "abc", m2m 1> ]
>>> o=ModelShow3.objects.create(field1='abc')
>>> o.m2m.add(o) ; o.save()
>>> ModelShow3.objects.all()
[ <ModelShow3: id 1, field1 (CharField) "abc", m2m (ManyToManyField) 1> ]
>>> ModelShow1.objects.all().annotate(Count('m2m'))
[ <ModelShow1: id 1, field1 (CharField), m2m (ManyToManyField) - Ann: m2m__count (int)> ]
>>> ModelShow2.objects.all().annotate(Count('m2m'))
[ <ModelShow2: id 1, field1 "abc", m2m 1 - Ann: m2m__count 1> ]
>>> ModelShow3.objects.all().annotate(Count('m2m'))
[ <ModelShow3: id 1, field1 (CharField) "abc", m2m (ManyToManyField) 1 - Ann: m2m__count (int) 1> ]
# no pretty printing
>>> o=ModelShow1_plain.objects.create(field1='abc')
>>> o=ModelShow2_plain.objects.create(field1='abc', field2='def')
>>> ModelShow1_plain.objects.all()
[<ModelShow1_plain: ModelShow1_plain object>, <ModelShow2_plain: ModelShow2_plain object>]
def create_model2abcd(self):
"""
Create the chain of objects of Model2,
this is reused in various tests.
"""
Model2A.objects.create(field1='A1')
Model2B.objects.create(field1='B1', field2='B2')
Model2C.objects.create(field1='C1', field2='C2', field3='C3')
Model2D.objects.create(field1='D1', field2='D2', field3='D3', field4='D4')
### extra() method
def test_simple_inheritance(self):
self.create_model2abcd()
>>> Model2A.objects.extra(where=['id IN (2, 3)'])
[ <Model2B: id 2, field1 (CharField), field2 (CharField)>,
<Model2C: id 3, field1 (CharField), field2 (CharField), field3 (CharField)> ]
objects = list(Model2A.objects.all())
self.assertEqual(repr(objects[0]), '<Model2A: id 1, field1 (CharField)>')
self.assertEqual(repr(objects[1]), '<Model2B: id 2, field1 (CharField), field2 (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)>')
>>> Model2A.objects.extra(select={"select_test": "field1 = 'A1'"}, where=["field1 = 'A1' OR field1 = 'B1'"], order_by = ['-id'] )
[ <Model2B: id 2, field1 (CharField), field2 (CharField) - Extra: select_test (int)>,
<Model2A: id 1, field1 (CharField) - Extra: select_test (int)> ]
>>> o=ModelExtraA.objects.create(field1='A1')
>>> o=ModelExtraB.objects.create(field1='B1', field2='B2')
>>> o=ModelExtraC.objects.create(field1='C1', field2='C2', field3='C3')
>>> o=ModelExtraExternal.objects.create(topic='extra1')
>>> o=ModelExtraExternal.objects.create(topic='extra2')
>>> o=ModelExtraExternal.objects.create(topic='extra3')
>>> ModelExtraA.objects.extra(tables=["polymorphic_modelextraexternal"], select={"topic":"polymorphic_modelextraexternal.topic"}, where=["polymorphic_modelextraa.id = polymorphic_modelextraexternal.id"] )
[ <ModelExtraA: id 1, field1 (CharField) "A1" - Extra: topic (unicode) "extra1">,
<ModelExtraB: id 2, field1 (CharField) "B1", field2 (CharField) "B2" - Extra: topic (unicode) "extra2">,
<ModelExtraC: id 3, field1 (CharField) "C1", field2 (CharField) "C2", field3 (CharField) "C3" - Extra: topic (unicode) "extra3"> ]
def test_manual_get_real_instance(self):
self.create_model2abcd()
### class filtering, instance_of, not_instance_of
o = Model2A.objects.non_polymorphic().get(field1='C1')
self.assertEqual(repr(o.get_real_instance()), '<Model2C: id 3, field1 (CharField), field2 (CharField), field3 (CharField)>')
>>> Model2A.objects.instance_of(Model2B)
[ <Model2B: id 2, field1 (CharField), field2 (CharField)>,
<Model2C: id 3, field1 (CharField), field2 (CharField), field3 (CharField)>,
<Model2D: id 4, field1 (CharField), field2 (CharField), field3 (CharField), field4 (CharField)> ]
>>> Model2A.objects.filter(instance_of=Model2B)
[ <Model2B: id 2, field1 (CharField), field2 (CharField)>,
<Model2C: id 3, field1 (CharField), field2 (CharField), field3 (CharField)>,
<Model2D: id 4, field1 (CharField), field2 (CharField), field3 (CharField), field4 (CharField)> ]
def test_non_polymorphic(self):
self.create_model2abcd()
>>> Model2A.objects.filter(Q(instance_of=Model2B))
[ <Model2B: id 2, field1 (CharField), field2 (CharField)>,
<Model2C: id 3, field1 (CharField), field2 (CharField), field3 (CharField)>,
<Model2D: id 4, field1 (CharField), field2 (CharField), field3 (CharField), field4 (CharField)> ]
objects = list(Model2A.objects.all().non_polymorphic())
self.assertEqual(repr(objects[0]), '<Model2A: id 1, field1 (CharField)>')
self.assertEqual(repr(objects[1]), '<Model2A: id 2, field1 (CharField)>')
self.assertEqual(repr(objects[2]), '<Model2A: id 3, field1 (CharField)>')
self.assertEqual(repr(objects[3]), '<Model2A: id 4, field1 (CharField)>')
>>> Model2A.objects.not_instance_of(Model2B)
[ <Model2A: id 1, field1 (CharField)> ]
def test_get_real_instances(self):
self.create_model2abcd()
qs = Model2A.objects.all().non_polymorphic()
### polymorphic filtering
# from queryset
objects = qs.get_real_instances()
self.assertEqual(repr(objects[0]), '<Model2A: id 1, field1 (CharField)>')
self.assertEqual(repr(objects[1]), '<Model2B: id 2, field1 (CharField), field2 (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)>')
>>> Model2A.objects.filter( Q( Model2B___field2 = 'B2' ) | Q( Model2C___field3 = 'C3' ) )
[ <Model2B: id 2, field1 (CharField), field2 (CharField)>,
<Model2C: id 3, field1 (CharField), field2 (CharField), field3 (CharField)> ]
# from a manual list
objects = Model2A.objects.get_real_instances(list(qs))
self.assertEqual(repr(objects[0]), '<Model2A: id 1, field1 (CharField)>')
self.assertEqual(repr(objects[1]), '<Model2B: id 2, field1 (CharField), field2 (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)>')
def test_translate_polymorphic_q_object(self):
self.create_model2abcd()
q = Model2A.translate_polymorphic_Q_object(Q(instance_of=Model2C))
objects = Model2A.objects.filter(q)
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)>')
### get & delete
>>> oa=Model2A.objects.get(id=2)
>>> oa
<Model2B: id 2, field1 (CharField), field2 (CharField)>
def test_base_manager(self):
def show_base_manager(model):
return "{0} {1}".format(
repr(type(model._base_manager)),
repr(model._base_manager.model)
)
self.assertEqual(show_base_manager(PlainA), "<class 'django.db.models.manager.Manager'> <class 'polymorphic.tests.PlainA'>")
self.assertEqual(show_base_manager(PlainB), "<class 'django.db.models.manager.Manager'> <class 'polymorphic.tests.PlainB'>")
self.assertEqual(show_base_manager(PlainC), "<class 'django.db.models.manager.Manager'> <class 'polymorphic.tests.PlainC'>")
self.assertEqual(show_base_manager(Model2A), "<class 'polymorphic.manager.PolymorphicManager'> <class 'polymorphic.tests.Model2A'>")
self.assertEqual(show_base_manager(Model2B), "<class 'django.db.models.manager.Manager'> <class 'polymorphic.tests.Model2B'>")
self.assertEqual(show_base_manager(Model2C), "<class 'django.db.models.manager.Manager'> <class 'polymorphic.tests.Model2C'>")
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'>")
def test_foreignkey_field(self):
self.create_model2abcd()
>>> oa.delete()
>>> Model2A.objects.all()
[ <Model2A: id 1, field1 (CharField)>,
<Model2C: id 3, field1 (CharField), field2 (CharField), field3 (CharField)>,
<Model2D: id 4, field1 (CharField), field2 (CharField), field3 (CharField), field4 (CharField)> ]
object2a = Model2A.base_objects.get(field1='C1')
self.assertEqual(repr(object2a.model2b), '<Model2B: id 3, field1 (CharField), field2 (CharField)>')
object2b = Model2B.base_objects.get(field1='C1')
self.assertEqual(repr(object2b.model2c), '<Model2C: id 3, field1 (CharField), field2 (CharField), field3 (CharField)>')
def test_onetoone_field(self):
self.create_model2abcd()
### queryset combining
a = Model2A.base_objects.get(field1='C1')
b = One2OneRelatingModelDerived.objects.create(one2one=a, field1='f1', field2='f2')
>>> o=ModelX.objects.create(field_x='x')
>>> o=ModelY.objects.create(field_y='y')
# this result is basically wrong, probably due to Django cacheing (we used base_objects), but should not be a problem
self.assertEqual(repr(b.one2one), '<Model2A: id 3, field1 (CharField)>')
>>> Base.objects.instance_of(ModelX) | Base.objects.instance_of(ModelY)
[ <ModelX: id 1, field_b (CharField), field_x (CharField)>,
<ModelY: id 2, field_b (CharField), field_y (CharField)> ]
c = One2OneRelatingModelDerived.objects.get(field1='f1')
self.assertEqual(repr(c.one2one), '<Model2C: id 3, field1 (CharField), field2 (CharField), field3 (CharField)>')
self.assertEqual(repr(a.one2onerelatingmodel), '<One2OneRelatingModelDerived: One2OneRelatingModelDerived object>')
### multiple inheritance, subclassing third party models (mix PolymorphicModel with models.Model)
def test_manytomany_field(self):
# Model 1
o = ModelShow1.objects.create(field1='abc')
o.m2m.add(o)
o.save()
self.assertEqual(repr(ModelShow1.objects.all()), '[ <ModelShow1: id 1, field1 (CharField), m2m (ManyToManyField)> ]')
>>> o = Enhance_Base.objects.create(field_b='b-base')
>>> o = Enhance_Inherit.objects.create(field_b='b-inherit', field_p='p', field_i='i')
# Model 2
o = ModelShow2.objects.create(field1='abc')
o.m2m.add(o)
o.save()
self.assertEqual(repr(ModelShow2.objects.all()), '[ <ModelShow2: id 1, field1 "abc", m2m 1> ]')
>>> Enhance_Base.objects.all()
[ <Enhance_Base: id 1, field_b (CharField) "b-base">,
<Enhance_Inherit: id 2, field_b (CharField) "b-inherit", field_p (CharField) "p", field_i (CharField) "i"> ]
# Model 3
o=ModelShow3.objects.create(field1='abc')
o.m2m.add(o)
o.save()
self.assertEqual(repr(ModelShow3.objects.all()), '[ <ModelShow3: id 1, field1 (CharField) "abc", m2m (ManyToManyField) 1> ]')
self.assertEqual(repr(ModelShow1.objects.all().annotate(Count('m2m'))), '[ <ModelShow1: id 1, field1 (CharField), m2m (ManyToManyField) - Ann: m2m__count (int)> ]')
self.assertEqual(repr(ModelShow2.objects.all().annotate(Count('m2m'))), '[ <ModelShow2: id 1, field1 "abc", m2m 1 - Ann: m2m__count 1> ]')
self.assertEqual(repr(ModelShow3.objects.all().annotate(Count('m2m'))), '[ <ModelShow3: id 1, field1 (CharField) "abc", m2m (ManyToManyField) 1 - Ann: m2m__count (int) 1> ]')
# no pretty printing
ModelShow1_plain.objects.create(field1='abc')
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>]')
### ForeignKey, ManyToManyField
>>> obase=RelationBase.objects.create(field_base='base')
>>> oa=RelationA.objects.create(field_base='A1', field_a='A2', fk=obase)
>>> ob=RelationB.objects.create(field_base='B1', field_b='B2', fk=oa)
>>> oc=RelationBC.objects.create(field_base='C1', field_b='C2', field_c='C3', fk=oa)
>>> oa.m2m.add(oa); oa.m2m.add(ob)
def test_extra_method(self):
self.create_model2abcd()
>>> RelationBase.objects.all()
[ <RelationBase: id 1, field_base (CharField) "base", fk (ForeignKey) None, m2m (ManyToManyField) 0>,
<RelationA: id 2, field_base (CharField) "A1", fk (ForeignKey) RelationBase, field_a (CharField) "A2", m2m (ManyToManyField) 2>,
<RelationB: id 3, field_base (CharField) "B1", fk (ForeignKey) RelationA, field_b (CharField) "B2", m2m (ManyToManyField) 1>,
<RelationBC: id 4, field_base (CharField) "C1", fk (ForeignKey) RelationA, field_b (CharField) "C2", field_c (CharField) "C3", m2m (ManyToManyField) 0> ]
objects = list(Model2A.objects.extra(where=['id IN (2, 3)']))
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)>')
>>> oa=RelationBase.objects.get(id=2)
>>> oa.fk
<RelationBase: id 1, field_base (CharField) "base", fk (ForeignKey) None, m2m (ManyToManyField) 0>
objects = Model2A.objects.extra(select={"select_test": "field1 = 'A1'"}, where=["field1 = 'A1' OR field1 = 'B1'"], order_by=['-id'])
self.assertEqual(repr(objects[0]), '<Model2B: id 2, field1 (CharField), field2 (CharField) - Extra: select_test (int)>')
self.assertEqual(repr(objects[1]), '<Model2A: id 1, field1 (CharField) - Extra: select_test (int)>')
self.assertEqual(len(objects), 2) # Placed after the other tests, only verifying whether there are no more additional objects.
ModelExtraA.objects.create(field1='A1')
ModelExtraB.objects.create(field1='B1', field2='B2')
ModelExtraC.objects.create(field1='C1', field2='C2', field3='C3')
ModelExtraExternal.objects.create(topic='extra1')
ModelExtraExternal.objects.create(topic='extra2')
ModelExtraExternal.objects.create(topic='extra3')
objects = ModelExtraA.objects.extra(tables=["polymorphic_modelextraexternal"], select={"topic":"polymorphic_modelextraexternal.topic"}, where=["polymorphic_modelextraa.id = polymorphic_modelextraexternal.id"])
self.assertEqual(repr(objects[0]), '<ModelExtraA: id 1, field1 (CharField) "A1" - Extra: topic (unicode) "extra1">')
self.assertEqual(repr(objects[1]), '<ModelExtraB: id 2, field1 (CharField) "B1", field2 (CharField) "B2" - Extra: topic (unicode) "extra2">')
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)
>>> oa.relationbase_set.all()
[ <RelationB: id 3, field_base (CharField) "B1", fk (ForeignKey) RelationA, field_b (CharField) "B2", m2m (ManyToManyField) 1>,
<RelationBC: id 4, field_base (CharField) "C1", fk (ForeignKey) RelationA, field_b (CharField) "C2", field_c (CharField) "C3", m2m (ManyToManyField) 0> ]
>>> ob=RelationBase.objects.get(id=3)
>>> ob.fk
<RelationA: id 2, field_base (CharField) "A1", fk (ForeignKey) RelationBase, field_a (CharField) "A2", m2m (ManyToManyField) 2>
def test_instance_of_filter(self):
self.create_model2abcd()
objects = Model2A.objects.instance_of(Model2B)
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[2]), '<Model2D: id 4, field1 (CharField), field2 (CharField), field3 (CharField), field4 (CharField)>')
self.assertEqual(len(objects), 3)
objects = Model2A.objects.filter(instance_of=Model2B)
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[2]), '<Model2D: id 4, field1 (CharField), field2 (CharField), field3 (CharField), field4 (CharField)>')
self.assertEqual(len(objects), 3)
objects = Model2A.objects.filter(Q(instance_of=Model2B))
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[2]), '<Model2D: id 4, field1 (CharField), field2 (CharField), field3 (CharField), field4 (CharField)>')
self.assertEqual(len(objects), 3)
>>> oa=RelationA.objects.get()
>>> oa.m2m.all()
[ <RelationA: id 2, field_base (CharField) "A1", fk (ForeignKey) RelationBase, field_a (CharField) "A2", m2m (ManyToManyField) 2>,
<RelationB: id 3, field_base (CharField) "B1", fk (ForeignKey) RelationA, field_b (CharField) "B2", m2m (ManyToManyField) 1> ]
objects = Model2A.objects.not_instance_of(Model2B)
self.assertEqual(repr(objects[0]), '<Model2A: id 1, field1 (CharField)>')
self.assertEqual(len(objects), 1)
### user-defined manager
>>> o=ModelWithMyManager.objects.create(field1='D1a', field4='D4a')
>>> o=ModelWithMyManager.objects.create(field1='D1b', field4='D4b')
def test_polymorphic___filter(self):
self.create_model2abcd()
>>> ModelWithMyManager.objects.all()
[ <ModelWithMyManager: id 6, field1 (CharField) "D1b", field4 (CharField) "D4b">,
<ModelWithMyManager: id 5, field1 (CharField) "D1a", field4 (CharField) "D4a"> ]
objects = Model2A.objects.filter(Q( Model2B___field2='B2') | Q( Model2C___field3='C3'))
self.assertEqual(len(objects), 2)
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)>')
>>> type(ModelWithMyManager.objects)
<class 'polymorphic.tests.MyManager'>
>>> type(ModelWithMyManager._default_manager)
<class 'polymorphic.manager.PolymorphicManager'>
def test_delete(self):
self.create_model2abcd()
### Manager Inheritance
oa = Model2A.objects.get(id=2)
self.assertEqual(repr(oa), '<Model2B: id 2, field1 (CharField), field2 (CharField)>')
self.assertEqual(Model2A.objects.count(), 4)
>>> type(MRODerived.objects) # MRO
<class 'polymorphic.tests.MyManager'>
oa.delete()
objects = Model2A.objects.all()
self.assertEqual(repr(objects[0]), '<Model2A: id 1, field1 (CharField)>')
self.assertEqual(repr(objects[1]), '<Model2C: id 3, field1 (CharField), field2 (CharField), field3 (CharField)>')
self.assertEqual(repr(objects[2]), '<Model2D: id 4, field1 (CharField), field2 (CharField), field3 (CharField), field4 (CharField)>')
self.assertEqual(len(objects), 3)
def test_combine_querysets(self):
ModelX.objects.create(field_x='x')
ModelY.objects.create(field_y='y')
# check for correct default manager
>>> type(MROBase1._default_manager)
<class 'polymorphic.manager.PolymorphicManager'>
qs = Base.objects.instance_of(ModelX) | Base.objects.instance_of(ModelY)
self.assertEqual(repr(qs[0]), '<ModelX: id 1, field_b (CharField), field_x (CharField)>')
self.assertEqual(repr(qs[1]), '<ModelY: id 2, field_b (CharField), field_y (CharField)>')
self.assertEqual(len(qs), 2)
# Django vanilla inheritance does not inherit MyManager as _default_manager here
>>> type(MROBase2._default_manager)
<class 'polymorphic.manager.PolymorphicManager'>
def test_multiple_inheritance(self):
# multiple inheritance, subclassing third party models (mix PolymorphicModel with models.Model)
### fixed issue in PolymorphicModel.__getattribute__: field name same as model name
>>> ModelFieldNameTest.objects.create(modelfieldnametest='1')
<ModelFieldNameTest: id 1, modelfieldnametest (CharField)>
Enhance_Base.objects.create(field_b='b-base')
Enhance_Inherit.objects.create(field_b='b-inherit', field_p='p', field_i='i')
qs = Enhance_Base.objects.all()
self.assertEqual(repr(qs[0]), '<Enhance_Base: id 1, field_b (CharField) "b-base">')
self.assertEqual(repr(qs[1]), '<Enhance_Inherit: id 2, field_b (CharField) "b-inherit", field_p (CharField) "p", field_i (CharField) "i">')
self.assertEqual(len(qs), 2)
### fixed issue in PolymorphicModel.__getattribute__:
# if subclass defined __init__ and accessed class members, __getattribute__ had a problem: "...has no attribute 'sub_and_superclass_dict'"
#>>> o
>>> o = InitTestModelSubclass.objects.create()
>>> o.bar
'XYZ'
def test_relation_base(self):
# ForeignKey, ManyToManyField
obase = RelationBase.objects.create(field_base='base')
oa = RelationA.objects.create(field_base='A1', field_a='A2', fk=obase)
ob = RelationB.objects.create(field_base='B1', field_b='B2', fk=oa)
oc = RelationBC.objects.create(field_base='C1', field_b='C2', field_c='C3', fk=oa)
oa.m2m.add(oa)
oa.m2m.add(ob)
### Django model inheritance diamond problem, fails for Django 1.1
objects = RelationBase.objects.all()
self.assertEqual(repr(objects[0]), '<RelationBase: id 1, field_base (CharField) "base", fk (ForeignKey) None, m2m (ManyToManyField) 0>')
self.assertEqual(repr(objects[1]), '<RelationA: id 2, field_base (CharField) "A1", fk (ForeignKey) RelationBase, field_a (CharField) "A2", m2m (ManyToManyField) 2>')
self.assertEqual(repr(objects[2]), '<RelationB: id 3, field_base (CharField) "B1", fk (ForeignKey) RelationA, field_b (CharField) "B2", m2m (ManyToManyField) 1>')
self.assertEqual(repr(objects[3]), '<RelationBC: id 4, field_base (CharField) "C1", fk (ForeignKey) RelationA, field_b (CharField) "C2", field_c (CharField) "C3", m2m (ManyToManyField) 0>')
self.assertEqual(len(objects), 4)
#>>> o=DiamondXY.objects.create(field_b='b', field_x='x', field_y='y')
#>>> print 'DiamondXY fields 1: field_b "%s", field_x "%s", field_y "%s"' % (o.field_b, o.field_x, o.field_y)
#DiamondXY fields 1: field_b "a", field_x "x", field_y "y"
oa = RelationBase.objects.get(id=2)
self.assertEqual(repr(oa.fk), '<RelationBase: id 1, field_base (CharField) "base", fk (ForeignKey) None, m2m (ManyToManyField) 0>')
objects = oa.relationbase_set.all()
self.assertEqual(repr(objects[0]), '<RelationB: id 3, field_base (CharField) "B1", fk (ForeignKey) RelationA, field_b (CharField) "B2", m2m (ManyToManyField) 1>')
self.assertEqual(repr(objects[1]), '<RelationBC: id 4, field_base (CharField) "C1", fk (ForeignKey) RelationA, field_b (CharField) "C2", field_c (CharField) "C3", m2m (ManyToManyField) 0>')
self.assertEqual(len(objects), 2)
>>> settings.DEBUG=False
ob = RelationBase.objects.get(id=3)
self.assertEqual(repr(ob.fk), '<RelationA: id 2, field_base (CharField) "A1", fk (ForeignKey) RelationBase, field_a (CharField) "A2", m2m (ManyToManyField) 2>')
"""}
oa = RelationA.objects.get()
objects = oa.m2m.all()
self.assertEqual(repr(objects[0]), '<RelationA: id 2, field_base (CharField) "A1", fk (ForeignKey) RelationBase, field_a (CharField) "A2", m2m (ManyToManyField) 2>')
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)
def test_user_defined_manager(self):
self.create_model2abcd()
ModelWithMyManager.objects.create(field1='D1a', field4='D4a')
ModelWithMyManager.objects.create(field1='D1b', field4='D4b')
objects = ModelWithMyManager.objects.all()
self.assertEqual(repr(objects[0]), '<ModelWithMyManager: id 6, field1 (CharField) "D1b", field4 (CharField) "D4b">')
self.assertEqual(repr(objects[1]), '<ModelWithMyManager: id 5, field1 (CharField) "D1a", field4 (CharField) "D4a">')
self.assertEqual(len(objects), 2)
self.assertEqual(repr(type(ModelWithMyManager.objects)), "<class 'polymorphic.tests.MyManager'>")
self.assertEqual(repr(type(ModelWithMyManager._default_manager)), "<class 'polymorphic.manager.PolymorphicManager'>")
def test_manager_inheritance(self):
self.assertEqual(repr(type(MRODerived.objects)), "<class 'polymorphic.tests.MyManager'>") # MRO
# check for correct default manager
self.assertEqual(repr(type(MROBase1._default_manager)), "<class 'polymorphic.manager.PolymorphicManager'>")
# Django vanilla inheritance does not inherit MyManager as _default_manager here
self.assertEqual(repr(type(MROBase2._default_manager)), "<class 'polymorphic.manager.PolymorphicManager'>")
def test_fix_getattribute(self):
### fixed issue in PolymorphicModel.__getattribute__: field name same as model name
o = ModelFieldNameTest.objects.create(modelfieldnametest='1')
self.assertEqual(repr(o), '<ModelFieldNameTest: id 1, modelfieldnametest (CharField)>')
# if subclass defined __init__ and accessed class members,
# __getattribute__ had a problem: "...has no attribute 'sub_and_superclass_dict'"
o = InitTestModelSubclass.objects.create()
self.assertEqual(o.bar, 'XYZ')
class RegressionTests(TestCase):