From 9493bd8bc166ee993c3d8d40525f053bb66b915e Mon Sep 17 00:00:00 2001 From: Diederik van der Boor Date: Sun, 25 Dec 2016 13:25:48 +0100 Subject: [PATCH] split tests.py into a python package --- polymorphic/tests/__init__.py | 6 + polymorphic/tests/models.py | 412 +++++++++++++++ polymorphic/tests/test_multidb.py | 105 ++++ polymorphic/{tests.py => tests/test_orm.py} | 523 +------------------- polymorphic/tests/test_regression.py | 24 + 5 files changed, 548 insertions(+), 522 deletions(-) create mode 100644 polymorphic/tests/__init__.py create mode 100644 polymorphic/tests/models.py create mode 100644 polymorphic/tests/test_multidb.py rename polymorphic/{tests.py => tests/test_orm.py} (73%) create mode 100644 polymorphic/tests/test_regression.py diff --git a/polymorphic/tests/__init__.py b/polymorphic/tests/__init__.py new file mode 100644 index 0000000..bcf705a --- /dev/null +++ b/polymorphic/tests/__init__.py @@ -0,0 +1,6 @@ +# -*- coding: utf-8 -*- +from .models import * +from .test_orm import * +from .test_multidb import * +from .test_regression import * + diff --git a/polymorphic/tests/models.py b/polymorphic/tests/models.py new file mode 100644 index 0000000..77fda0a --- /dev/null +++ b/polymorphic/tests/models.py @@ -0,0 +1,412 @@ +import uuid + +import django +from django.contrib.contenttypes.models import ContentType +from django.db import models +from django.db.models.query import QuerySet + +from polymorphic.managers import PolymorphicManager +from polymorphic.models import PolymorphicModel +from polymorphic.query import PolymorphicQuerySet +from polymorphic.showfields import ShowFieldContent, ShowFieldType, ShowFieldTypeAndContent + +try: + from django.db.models import UUIDField +except ImportError: + # django<1.8 + from polymorphic.tools_for_tests import UUIDField + + +class PlainA(models.Model): + field1 = models.CharField(max_length=10) + + +class PlainB(PlainA): + field2 = models.CharField(max_length=10) + + +class PlainC(PlainB): + field3 = models.CharField(max_length=10) + + +class Model2A(ShowFieldType, PolymorphicModel): + field1 = models.CharField(max_length=10) + polymorphic_showfield_deferred = True + + +class Model2B(Model2A): + field2 = models.CharField(max_length=10) + + +class Model2C(Model2B): + field3 = models.CharField(max_length=10) + + +class Model2D(Model2C): + field4 = models.CharField(max_length=10) + + +class ModelExtraA(ShowFieldTypeAndContent, PolymorphicModel): + field1 = models.CharField(max_length=10) + + +class ModelExtraB(ModelExtraA): + field2 = models.CharField(max_length=10) + + +class ModelExtraC(ModelExtraB): + field3 = models.CharField(max_length=10) + + +class ModelExtraExternal(models.Model): + topic = models.CharField(max_length=10) + + +class ModelShow1(ShowFieldType, PolymorphicModel): + field1 = models.CharField(max_length=10) + m2m = models.ManyToManyField('self') + + +class ModelShow2(ShowFieldContent, PolymorphicModel): + field1 = models.CharField(max_length=10) + m2m = models.ManyToManyField('self') + + +class ModelShow3(ShowFieldTypeAndContent, PolymorphicModel): + field1 = models.CharField(max_length=10) + m2m = models.ManyToManyField('self') + + +class ModelShow1_plain(PolymorphicModel): + field1 = models.CharField(max_length=10) + + +class ModelShow2_plain(ModelShow1_plain): + field2 = models.CharField(max_length=10) + + +class Base(ShowFieldType, PolymorphicModel): + field_b = models.CharField(max_length=10) + + +class ModelX(Base): + field_x = models.CharField(max_length=10) + + +class ModelY(Base): + field_y = models.CharField(max_length=10) + + +class Enhance_Plain(models.Model): + field_p = models.CharField(max_length=10) + + +class Enhance_Base(ShowFieldTypeAndContent, PolymorphicModel): + base_id = models.AutoField(primary_key=True) + field_b = models.CharField(max_length=10) + + +class Enhance_Inherit(Enhance_Base, Enhance_Plain): + field_i = models.CharField(max_length=10) + + +class RelationBase(ShowFieldTypeAndContent, PolymorphicModel): + field_base = models.CharField(max_length=10) + fk = models.ForeignKey('self', null=True, related_name='relationbase_set') + m2m = models.ManyToManyField('self') + + +class RelationA(RelationBase): + field_a = models.CharField(max_length=10) + + +class RelationB(RelationBase): + field_b = models.CharField(max_length=10) + + +class RelationBC(RelationB): + field_c = models.CharField(max_length=10) + + +class RelatingModel(models.Model): + many2many = models.ManyToManyField(Model2A) + + +class One2OneRelatingModel(PolymorphicModel): + one2one = models.OneToOneField(Model2A) + field1 = models.CharField(max_length=10) + + +class One2OneRelatingModelDerived(One2OneRelatingModel): + field2 = models.CharField(max_length=10) + + +class ModelUnderRelParent(PolymorphicModel): + field1 = models.CharField(max_length=10) + _private = models.CharField(max_length=10) + + +class ModelUnderRelChild(PolymorphicModel): + parent = models.ForeignKey(ModelUnderRelParent, related_name='children') + _private2 = models.CharField(max_length=10) + + +class MyManagerQuerySet(PolymorphicQuerySet): + + def my_queryset_foo(self): + return self.all() # Just a method to prove the existance of the custom queryset. + + +class MyManager(PolymorphicManager): + queryset_class = MyManagerQuerySet + + def get_queryset(self): + return super(MyManager, self).get_queryset().order_by('-field1') + + def my_queryset_foo(self): + return self.all().my_queryset_foo() + + # Django <= 1.5 compatibility + get_query_set = get_queryset + + +class ModelWithMyManager(ShowFieldTypeAndContent, Model2A): + objects = MyManager() + field4 = models.CharField(max_length=10) + + +class ModelWithMyManagerNoDefault(ShowFieldTypeAndContent, Model2A): + objects = PolymorphicManager() + my_objects = MyManager() + field4 = models.CharField(max_length=10) + + +class ModelWithMyManagerDefault(ShowFieldTypeAndContent, Model2A): + my_objects = MyManager() + objects = PolymorphicManager() + field4 = models.CharField(max_length=10) + + +if django.VERSION >= (1, 7): + class ModelWithMyManager2(ShowFieldTypeAndContent, Model2A): + objects = MyManagerQuerySet.as_manager() + field4 = models.CharField(max_length=10) + + +class MROBase1(ShowFieldType, PolymorphicModel): + objects = MyManager() + field1 = models.CharField(max_length=10) # needed as MyManager uses it + + +class MROBase2(MROBase1): + pass # Django vanilla inheritance does not inherit MyManager as _default_manager here + + +class MROBase3(models.Model): + objects = PolymorphicManager() + + +class MRODerived(MROBase2, MROBase3): + pass + + +class ParentModelWithManager(PolymorphicModel): + pass + + +class ChildModelWithManager(PolymorphicModel): + # Also test whether foreign keys receive the manager: + fk = models.ForeignKey(ParentModelWithManager, related_name='childmodel_set') + objects = MyManager() + + +class PlainMyManagerQuerySet(QuerySet): + + def my_queryset_foo(self): + return self.all() # Just a method to prove the existance of the custom queryset. + + +class PlainMyManager(models.Manager): + + def my_queryset_foo(self): + return self.get_queryset().my_queryset_foo() + + def get_queryset(self): + return PlainMyManagerQuerySet(self.model, using=self._db) + + # Django <= 1.5 compatibility + get_query_set = get_queryset + + +class PlainParentModelWithManager(models.Model): + pass + + +class PlainChildModelWithManager(models.Model): + fk = models.ForeignKey(PlainParentModelWithManager, related_name='childmodel_set') + objects = PlainMyManager() + + +class MgrInheritA(models.Model): + mgrA = models.Manager() + mgrA2 = models.Manager() + field1 = models.CharField(max_length=10) + + +class MgrInheritB(MgrInheritA): + mgrB = models.Manager() + field2 = models.CharField(max_length=10) + + +class MgrInheritC(ShowFieldTypeAndContent, MgrInheritB): + pass + + +class BlogBase(ShowFieldTypeAndContent, PolymorphicModel): + name = models.CharField(max_length=10) + + +class BlogA(BlogBase): + info = models.CharField(max_length=10) + + +class BlogB(BlogBase): + pass + + +class BlogEntry(ShowFieldTypeAndContent, PolymorphicModel): + blog = models.ForeignKey(BlogA) + text = models.CharField(max_length=10) + + +class BlogEntry_limit_choices_to(ShowFieldTypeAndContent, PolymorphicModel): + blog = models.ForeignKey(BlogBase) + text = models.CharField(max_length=10) + + +class ModelFieldNameTest(ShowFieldType, PolymorphicModel): + modelfieldnametest = models.CharField(max_length=10) + + +class InitTestModel(ShowFieldType, PolymorphicModel): + bar = models.CharField(max_length=100) + + def __init__(self, *args, **kwargs): + kwargs['bar'] = self.x() + super(InitTestModel, self).__init__(*args, **kwargs) + + +class InitTestModelSubclass(InitTestModel): + + def x(self): + return 'XYZ' + +# models from github issue + + +class Top(PolymorphicModel): + name = models.CharField(max_length=50) + + class Meta: + ordering = ('pk',) + + +class Middle(Top): + description = models.TextField() + + +class Bottom(Middle): + author = models.CharField(max_length=50) + + +class UUIDProject(ShowFieldTypeAndContent, PolymorphicModel): + uuid_primary_key = UUIDField(primary_key=True, default=uuid.uuid1) + topic = models.CharField(max_length=30) + + +class UUIDArtProject(UUIDProject): + artist = models.CharField(max_length=30) + + +class UUIDResearchProject(UUIDProject): + supervisor = models.CharField(max_length=30) + + +class UUIDPlainA(models.Model): + uuid_primary_key = UUIDField(primary_key=True, default=uuid.uuid1) + field1 = models.CharField(max_length=10) + + +class UUIDPlainB(UUIDPlainA): + field2 = models.CharField(max_length=10) + + +class UUIDPlainC(UUIDPlainB): + field3 = models.CharField(max_length=10) + +# base -> proxy + + +class ProxyBase(PolymorphicModel): + some_data = models.CharField(max_length=128) + + +class ProxyChild(ProxyBase): + + class Meta: + proxy = True + + +class NonProxyChild(ProxyBase): + name = models.CharField(max_length=10) + +# base -> proxy -> real models + + +class ProxiedBase(ShowFieldTypeAndContent, PolymorphicModel): + name = models.CharField(max_length=10) + + +class ProxyModelBase(ProxiedBase): + + class Meta: + proxy = True + + +class ProxyModelA(ProxyModelBase): + field1 = models.CharField(max_length=10) + + +class ProxyModelB(ProxyModelBase): + field2 = models.CharField(max_length=10) + + +# test bad field name +# class TestBadFieldModel(ShowFieldType, PolymorphicModel): +# instance_of = models.CharField(max_length=10) + +# validation error: "polymorphic.relatednameclash: Accessor for field 'polymorphic_ctype' clashes +# with related field 'ContentType.relatednameclash_set'." (reported by Andrew Ingram) +# fixed with related_name +class RelatedNameClash(ShowFieldType, PolymorphicModel): + ctype = models.ForeignKey(ContentType, null=True, editable=False) + +# class with a parent_link to superclass, and a related_name back to subclass + + +class TestParentLinkAndRelatedName(ModelShow1_plain): + superclass = models.OneToOneField(ModelShow1_plain, parent_link=True, related_name='related_name_subclass') + + +class CustomPkBase(ShowFieldTypeAndContent, PolymorphicModel): + b = models.CharField(max_length=1) + + +class CustomPkInherit(CustomPkBase): + custom_id = models.AutoField(primary_key=True) + i = models.CharField(max_length=1) + + +class DateModel(PolymorphicModel): + + date = models.DateTimeField() diff --git a/polymorphic/tests/test_multidb.py b/polymorphic/tests/test_multidb.py new file mode 100644 index 0000000..5308abd --- /dev/null +++ b/polymorphic/tests/test_multidb.py @@ -0,0 +1,105 @@ +from __future__ import print_function +import django +from django.contrib.contenttypes.models import ContentType + +from django.test import TestCase +from django.db.models import Q + +from .models import * + +try: + from unittest import skipIf +except ImportError: + # python<2.7 + from django.utils.unittest import skipIf + + + +class MultipleDatabasesTests(TestCase): + multi_db = True + + @skipIf(django.VERSION < (1, 5,), "This test needs Django >=1.5") + def test_save_to_non_default_database(self): + Model2A.objects.db_manager('secondary').create(field1='A1') + Model2C(field1='C1', field2='C2', field3='C3').save(using='secondary') + Model2B.objects.create(field1='B1', field2='B2') + Model2D(field1='D1', field2='D2', field3='D3', field4='D4').save() + + default_objects = list(Model2A.objects.order_by('id')) + self.assertEqual(len(default_objects), 2) + self.assertEqual(repr(default_objects[0]), '') + self.assertEqual(repr(default_objects[1]), '') + + secondary_objects = list(Model2A.objects.db_manager('secondary').order_by('id')) + self.assertEqual(len(secondary_objects), 2) + self.assertEqual(repr(secondary_objects[0]), '') + self.assertEqual(repr(secondary_objects[1]), '') + + def test_instance_of_filter_on_non_default_database(self): + Base.objects.db_manager('secondary').create(field_b='B1') + ModelX.objects.db_manager('secondary').create(field_b='B', field_x='X') + ModelY.objects.db_manager('secondary').create(field_b='Y', field_y='Y') + + objects = Base.objects.db_manager('secondary').filter(instance_of=Base) + self.assertEqual(len(objects), 3) + self.assertEqual(repr(objects[0]), '') + self.assertEqual(repr(objects[1]), '') + self.assertEqual(repr(objects[2]), '') + + objects = Base.objects.db_manager('secondary').filter(instance_of=ModelX) + self.assertEqual(len(objects), 1) + self.assertEqual(repr(objects[0]), '') + + objects = Base.objects.db_manager('secondary').filter(instance_of=ModelY) + self.assertEqual(len(objects), 1) + self.assertEqual(repr(objects[0]), '') + + objects = Base.objects.db_manager('secondary').filter(Q(instance_of=ModelX) | Q(instance_of=ModelY)) + self.assertEqual(len(objects), 2) + self.assertEqual(repr(objects[0]), '') + self.assertEqual(repr(objects[1]), '') + + def test_forward_many_to_one_descriptor_on_non_default_database(self): + def func(): + blog = BlogA.objects.db_manager('secondary').create(name='Blog', info='Info') + entry = BlogEntry.objects.db_manager('secondary').create(blog=blog, text='Text') + ContentType.objects.clear_cache() + entry = BlogEntry.objects.db_manager('secondary').get(pk=entry.id) + self.assertEqual(blog, entry.blog) + + # Ensure no queries are made using the default database. + self.assertNumQueries(0, func) + + def test_reverse_many_to_one_descriptor_on_non_default_database(self): + def func(): + blog = BlogA.objects.db_manager('secondary').create(name='Blog', info='Info') + entry = BlogEntry.objects.db_manager('secondary').create(blog=blog, text='Text') + ContentType.objects.clear_cache() + blog = BlogA.objects.db_manager('secondary').get(pk=blog.id) + self.assertEqual(entry, blog.blogentry_set.using('secondary').get()) + + # Ensure no queries are made using the default database. + self.assertNumQueries(0, func) + + def test_reverse_one_to_one_descriptor_on_non_default_database(self): + def func(): + m2a = Model2A.objects.db_manager('secondary').create(field1='A1') + one2one = One2OneRelatingModel.objects.db_manager('secondary').create(one2one=m2a, field1='121') + ContentType.objects.clear_cache() + m2a = Model2A.objects.db_manager('secondary').get(pk=m2a.id) + self.assertEqual(one2one, m2a.one2onerelatingmodel) + + # Ensure no queries are made using the default database. + self.assertNumQueries(0, func) + + def test_many_to_many_descriptor_on_non_default_database(self): + def func(): + m2a = Model2A.objects.db_manager('secondary').create(field1='A1') + rm = RelatingModel.objects.db_manager('secondary').create() + rm.many2many.add(m2a) + ContentType.objects.clear_cache() + m2a = Model2A.objects.db_manager('secondary').get(pk=m2a.id) + self.assertEqual(rm, m2a.relatingmodel_set.using('secondary').get()) + + # Ensure no queries are made using the default database. + self.assertNumQueries(0, func) diff --git a/polymorphic/tests.py b/polymorphic/tests/test_orm.py similarity index 73% rename from polymorphic/tests.py rename to polymorphic/tests/test_orm.py index 3c777d2..e3d81f6 100644 --- a/polymorphic/tests.py +++ b/polymorphic/tests/test_orm.py @@ -1,24 +1,16 @@ -# -*- coding: utf-8 -*- -""" Test Cases - Please see README.rst or DOCS.rst or http://chrisglass.github.com/django_polymorphic/ -""" from __future__ import print_function import uuid import re import django -from django.db.models.query import QuerySet from django.test import TestCase from django.db.models import Q, Count from django.db import models -from django.contrib.contenttypes.models import ContentType from django.utils import six from polymorphic.contrib.guardian import get_polymorphic_base_content_type -from polymorphic.models import PolymorphicModel from polymorphic.managers import PolymorphicManager -from polymorphic.query import PolymorphicQuerySet -from polymorphic.showfields import ShowFieldContent, ShowFieldType, ShowFieldTypeAndContent +from .models import * try: from unittest import skipIf @@ -29,407 +21,6 @@ except ImportError: if django.VERSION >= (1, 8): from django.db.models import Case, When -try: - from django.db.models import UUIDField -except ImportError: - # django<1.8 - from polymorphic.tools_for_tests import UUIDField - - -class PlainA(models.Model): - field1 = models.CharField(max_length=10) - - -class PlainB(PlainA): - field2 = models.CharField(max_length=10) - - -class PlainC(PlainB): - field3 = models.CharField(max_length=10) - - -class Model2A(ShowFieldType, PolymorphicModel): - field1 = models.CharField(max_length=10) - polymorphic_showfield_deferred = True - - -class Model2B(Model2A): - field2 = models.CharField(max_length=10) - - -class Model2C(Model2B): - field3 = models.CharField(max_length=10) - - -class Model2D(Model2C): - field4 = models.CharField(max_length=10) - - -class ModelExtraA(ShowFieldTypeAndContent, PolymorphicModel): - field1 = models.CharField(max_length=10) - - -class ModelExtraB(ModelExtraA): - field2 = models.CharField(max_length=10) - - -class ModelExtraC(ModelExtraB): - field3 = models.CharField(max_length=10) - - -class ModelExtraExternal(models.Model): - topic = models.CharField(max_length=10) - - -class ModelShow1(ShowFieldType, PolymorphicModel): - field1 = models.CharField(max_length=10) - m2m = models.ManyToManyField('self') - - -class ModelShow2(ShowFieldContent, PolymorphicModel): - field1 = models.CharField(max_length=10) - m2m = models.ManyToManyField('self') - - -class ModelShow3(ShowFieldTypeAndContent, PolymorphicModel): - field1 = models.CharField(max_length=10) - m2m = models.ManyToManyField('self') - - -class ModelShow1_plain(PolymorphicModel): - field1 = models.CharField(max_length=10) - - -class ModelShow2_plain(ModelShow1_plain): - field2 = models.CharField(max_length=10) - - -class Base(ShowFieldType, PolymorphicModel): - field_b = models.CharField(max_length=10) - - -class ModelX(Base): - field_x = models.CharField(max_length=10) - - -class ModelY(Base): - field_y = models.CharField(max_length=10) - - -class Enhance_Plain(models.Model): - field_p = models.CharField(max_length=10) - - -class Enhance_Base(ShowFieldTypeAndContent, PolymorphicModel): - base_id = models.AutoField(primary_key=True) - field_b = models.CharField(max_length=10) - - -class Enhance_Inherit(Enhance_Base, Enhance_Plain): - field_i = models.CharField(max_length=10) - - -class RelationBase(ShowFieldTypeAndContent, PolymorphicModel): - field_base = models.CharField(max_length=10) - fk = models.ForeignKey('self', null=True, related_name='relationbase_set') - m2m = models.ManyToManyField('self') - - -class RelationA(RelationBase): - field_a = models.CharField(max_length=10) - - -class RelationB(RelationBase): - field_b = models.CharField(max_length=10) - - -class RelationBC(RelationB): - field_c = models.CharField(max_length=10) - - -class RelatingModel(models.Model): - many2many = models.ManyToManyField(Model2A) - - -class One2OneRelatingModel(PolymorphicModel): - one2one = models.OneToOneField(Model2A) - field1 = models.CharField(max_length=10) - - -class One2OneRelatingModelDerived(One2OneRelatingModel): - field2 = models.CharField(max_length=10) - - -class ModelUnderRelParent(PolymorphicModel): - field1 = models.CharField(max_length=10) - _private = models.CharField(max_length=10) - - -class ModelUnderRelChild(PolymorphicModel): - parent = models.ForeignKey(ModelUnderRelParent, related_name='children') - _private2 = models.CharField(max_length=10) - - -class MyManagerQuerySet(PolymorphicQuerySet): - - def my_queryset_foo(self): - return self.all() # Just a method to prove the existance of the custom queryset. - - -class MyManager(PolymorphicManager): - queryset_class = MyManagerQuerySet - - def get_queryset(self): - return super(MyManager, self).get_queryset().order_by('-field1') - - def my_queryset_foo(self): - return self.all().my_queryset_foo() - - # Django <= 1.5 compatibility - get_query_set = get_queryset - - -class ModelWithMyManager(ShowFieldTypeAndContent, Model2A): - objects = MyManager() - field4 = models.CharField(max_length=10) - - -class ModelWithMyManagerNoDefault(ShowFieldTypeAndContent, Model2A): - objects = PolymorphicManager() - my_objects = MyManager() - field4 = models.CharField(max_length=10) - - -class ModelWithMyManagerDefault(ShowFieldTypeAndContent, Model2A): - my_objects = MyManager() - objects = PolymorphicManager() - field4 = models.CharField(max_length=10) - - -if django.VERSION >= (1, 7): - class ModelWithMyManager2(ShowFieldTypeAndContent, Model2A): - objects = MyManagerQuerySet.as_manager() - field4 = models.CharField(max_length=10) - - -class MROBase1(ShowFieldType, PolymorphicModel): - objects = MyManager() - field1 = models.CharField(max_length=10) # needed as MyManager uses it - - -class MROBase2(MROBase1): - pass # Django vanilla inheritance does not inherit MyManager as _default_manager here - - -class MROBase3(models.Model): - objects = PolymorphicManager() - - -class MRODerived(MROBase2, MROBase3): - pass - - -class ParentModelWithManager(PolymorphicModel): - pass - - -class ChildModelWithManager(PolymorphicModel): - # Also test whether foreign keys receive the manager: - fk = models.ForeignKey(ParentModelWithManager, related_name='childmodel_set') - objects = MyManager() - - -class PlainMyManagerQuerySet(QuerySet): - - def my_queryset_foo(self): - return self.all() # Just a method to prove the existance of the custom queryset. - - -class PlainMyManager(models.Manager): - - def my_queryset_foo(self): - return self.get_queryset().my_queryset_foo() - - def get_queryset(self): - return PlainMyManagerQuerySet(self.model, using=self._db) - - # Django <= 1.5 compatibility - get_query_set = get_queryset - - -class PlainParentModelWithManager(models.Model): - pass - - -class PlainChildModelWithManager(models.Model): - fk = models.ForeignKey(PlainParentModelWithManager, related_name='childmodel_set') - objects = PlainMyManager() - - -class MgrInheritA(models.Model): - mgrA = models.Manager() - mgrA2 = models.Manager() - field1 = models.CharField(max_length=10) - - -class MgrInheritB(MgrInheritA): - mgrB = models.Manager() - field2 = models.CharField(max_length=10) - - -class MgrInheritC(ShowFieldTypeAndContent, MgrInheritB): - pass - - -class BlogBase(ShowFieldTypeAndContent, PolymorphicModel): - name = models.CharField(max_length=10) - - -class BlogA(BlogBase): - info = models.CharField(max_length=10) - - -class BlogB(BlogBase): - pass - - -class BlogEntry(ShowFieldTypeAndContent, PolymorphicModel): - blog = models.ForeignKey(BlogA) - text = models.CharField(max_length=10) - - -class BlogEntry_limit_choices_to(ShowFieldTypeAndContent, PolymorphicModel): - blog = models.ForeignKey(BlogBase) - text = models.CharField(max_length=10) - - -class ModelFieldNameTest(ShowFieldType, PolymorphicModel): - modelfieldnametest = models.CharField(max_length=10) - - -class InitTestModel(ShowFieldType, PolymorphicModel): - bar = models.CharField(max_length=100) - - def __init__(self, *args, **kwargs): - kwargs['bar'] = self.x() - super(InitTestModel, self).__init__(*args, **kwargs) - - -class InitTestModelSubclass(InitTestModel): - - def x(self): - return 'XYZ' - -# models from github issue - - -class Top(PolymorphicModel): - name = models.CharField(max_length=50) - - class Meta: - ordering = ('pk',) - - -class Middle(Top): - description = models.TextField() - - -class Bottom(Middle): - author = models.CharField(max_length=50) - - -class UUIDProject(ShowFieldTypeAndContent, PolymorphicModel): - uuid_primary_key = UUIDField(primary_key=True, default=uuid.uuid1) - topic = models.CharField(max_length=30) - - -class UUIDArtProject(UUIDProject): - artist = models.CharField(max_length=30) - - -class UUIDResearchProject(UUIDProject): - supervisor = models.CharField(max_length=30) - - -class UUIDPlainA(models.Model): - uuid_primary_key = UUIDField(primary_key=True, default=uuid.uuid1) - field1 = models.CharField(max_length=10) - - -class UUIDPlainB(UUIDPlainA): - field2 = models.CharField(max_length=10) - - -class UUIDPlainC(UUIDPlainB): - field3 = models.CharField(max_length=10) - -# base -> proxy - - -class ProxyBase(PolymorphicModel): - some_data = models.CharField(max_length=128) - - -class ProxyChild(ProxyBase): - - class Meta: - proxy = True - - -class NonProxyChild(ProxyBase): - name = models.CharField(max_length=10) - -# base -> proxy -> real models - - -class ProxiedBase(ShowFieldTypeAndContent, PolymorphicModel): - name = models.CharField(max_length=10) - - -class ProxyModelBase(ProxiedBase): - - class Meta: - proxy = True - - -class ProxyModelA(ProxyModelBase): - field1 = models.CharField(max_length=10) - - -class ProxyModelB(ProxyModelBase): - field2 = models.CharField(max_length=10) - - -# test bad field name -# class TestBadFieldModel(ShowFieldType, PolymorphicModel): -# instance_of = models.CharField(max_length=10) - -# validation error: "polymorphic.relatednameclash: Accessor for field 'polymorphic_ctype' clashes -# with related field 'ContentType.relatednameclash_set'." (reported by Andrew Ingram) -# fixed with related_name -class RelatedNameClash(ShowFieldType, PolymorphicModel): - ctype = models.ForeignKey(ContentType, null=True, editable=False) - -# class with a parent_link to superclass, and a related_name back to subclass - - -class TestParentLinkAndRelatedName(ModelShow1_plain): - superclass = models.OneToOneField(ModelShow1_plain, parent_link=True, related_name='related_name_subclass') - - -class CustomPkBase(ShowFieldTypeAndContent, PolymorphicModel): - b = models.CharField(max_length=1) - - -class CustomPkInherit(CustomPkBase): - custom_id = models.AutoField(primary_key=True) - i = models.CharField(max_length=1) - - -class DateModel(PolymorphicModel): - - date = models.DateTimeField() - class PolymorphicTests(TestCase): """ @@ -1216,118 +807,6 @@ class PolymorphicTests(TestCase): self.assertEqual(ctype.name, 'model2a') -class RegressionTests(TestCase): - - def test_for_query_result_incomplete_with_inheritance(self): - """ https://github.com/bconstantin/django_polymorphic/issues/15 """ - - top = Top() - top.save() - middle = Middle() - middle.save() - bottom = Bottom() - bottom.save() - - expected_queryset = [top, middle, bottom] - self.assertQuerysetEqual(Top.objects.all(), [repr(r) for r in expected_queryset]) - - expected_queryset = [middle, bottom] - self.assertQuerysetEqual(Middle.objects.all(), [repr(r) for r in expected_queryset]) - - expected_queryset = [bottom] - self.assertQuerysetEqual(Bottom.objects.all(), [repr(r) for r in expected_queryset]) - - -class MultipleDatabasesTests(TestCase): - multi_db = True - - @skipIf(django.VERSION < (1, 5,), "This test needs Django >=1.5") - def test_save_to_non_default_database(self): - Model2A.objects.db_manager('secondary').create(field1='A1') - Model2C(field1='C1', field2='C2', field3='C3').save(using='secondary') - Model2B.objects.create(field1='B1', field2='B2') - Model2D(field1='D1', field2='D2', field3='D3', field4='D4').save() - - default_objects = list(Model2A.objects.order_by('id')) - self.assertEqual(len(default_objects), 2) - self.assertEqual(repr(default_objects[0]), '') - self.assertEqual(repr(default_objects[1]), '') - - secondary_objects = list(Model2A.objects.db_manager('secondary').order_by('id')) - self.assertEqual(len(secondary_objects), 2) - self.assertEqual(repr(secondary_objects[0]), '') - self.assertEqual(repr(secondary_objects[1]), '') - - def test_instance_of_filter_on_non_default_database(self): - Base.objects.db_manager('secondary').create(field_b='B1') - ModelX.objects.db_manager('secondary').create(field_b='B', field_x='X') - ModelY.objects.db_manager('secondary').create(field_b='Y', field_y='Y') - - objects = Base.objects.db_manager('secondary').filter(instance_of=Base) - self.assertEqual(len(objects), 3) - self.assertEqual(repr(objects[0]), '') - self.assertEqual(repr(objects[1]), '') - self.assertEqual(repr(objects[2]), '') - - objects = Base.objects.db_manager('secondary').filter(instance_of=ModelX) - self.assertEqual(len(objects), 1) - self.assertEqual(repr(objects[0]), '') - - objects = Base.objects.db_manager('secondary').filter(instance_of=ModelY) - self.assertEqual(len(objects), 1) - self.assertEqual(repr(objects[0]), '') - - objects = Base.objects.db_manager('secondary').filter(Q(instance_of=ModelX) | Q(instance_of=ModelY)) - self.assertEqual(len(objects), 2) - self.assertEqual(repr(objects[0]), '') - self.assertEqual(repr(objects[1]), '') - - def test_forward_many_to_one_descriptor_on_non_default_database(self): - def func(): - blog = BlogA.objects.db_manager('secondary').create(name='Blog', info='Info') - entry = BlogEntry.objects.db_manager('secondary').create(blog=blog, text='Text') - ContentType.objects.clear_cache() - entry = BlogEntry.objects.db_manager('secondary').get(pk=entry.id) - self.assertEqual(blog, entry.blog) - - # Ensure no queries are made using the default database. - self.assertNumQueries(0, func) - - def test_reverse_many_to_one_descriptor_on_non_default_database(self): - def func(): - blog = BlogA.objects.db_manager('secondary').create(name='Blog', info='Info') - entry = BlogEntry.objects.db_manager('secondary').create(blog=blog, text='Text') - ContentType.objects.clear_cache() - blog = BlogA.objects.db_manager('secondary').get(pk=blog.id) - self.assertEqual(entry, blog.blogentry_set.using('secondary').get()) - - # Ensure no queries are made using the default database. - self.assertNumQueries(0, func) - - def test_reverse_one_to_one_descriptor_on_non_default_database(self): - def func(): - m2a = Model2A.objects.db_manager('secondary').create(field1='A1') - one2one = One2OneRelatingModel.objects.db_manager('secondary').create(one2one=m2a, field1='121') - ContentType.objects.clear_cache() - m2a = Model2A.objects.db_manager('secondary').get(pk=m2a.id) - self.assertEqual(one2one, m2a.one2onerelatingmodel) - - # Ensure no queries are made using the default database. - self.assertNumQueries(0, func) - - def test_many_to_many_descriptor_on_non_default_database(self): - def func(): - m2a = Model2A.objects.db_manager('secondary').create(field1='A1') - rm = RelatingModel.objects.db_manager('secondary').create() - rm.many2many.add(m2a) - ContentType.objects.clear_cache() - m2a = Model2A.objects.db_manager('secondary').get(pk=m2a.id) - self.assertEqual(rm, m2a.relatingmodel_set.using('secondary').get()) - - # Ensure no queries are made using the default database. - self.assertNumQueries(0, func) - - def qrepr(data): """ Ensure consistent repr() output for the QuerySet object. diff --git a/polymorphic/tests/test_regression.py b/polymorphic/tests/test_regression.py new file mode 100644 index 0000000..47310b7 --- /dev/null +++ b/polymorphic/tests/test_regression.py @@ -0,0 +1,24 @@ +from django.test import TestCase +from .models import Top, Middle, Bottom + + +class RegressionTests(TestCase): + + def test_for_query_result_incomplete_with_inheritance(self): + """ https://github.com/bconstantin/django_polymorphic/issues/15 """ + + top = Top() + top.save() + middle = Middle() + middle.save() + bottom = Bottom() + bottom.save() + + expected_queryset = [top, middle, bottom] + self.assertQuerysetEqual(Top.objects.all(), [repr(r) for r in expected_queryset]) + + expected_queryset = [middle, bottom] + self.assertQuerysetEqual(Middle.objects.all(), [repr(r) for r in expected_queryset]) + + expected_queryset = [bottom] + self.assertQuerysetEqual(Bottom.objects.all(), [repr(r) for r in expected_queryset])