Merge pull request #30 from vdboor/cleanup_for_15

Cleanup before porting to Django 1.5
fix_request_path_info
Chris Glass 2013-04-05 03:09:42 -07:00
commit 62d97f29b1
32 changed files with 541 additions and 613 deletions

1
.gitignore vendored
View File

@ -36,3 +36,4 @@ lib/
MANIFEST
dist/
*.egg-info
.tox/

View File

@ -1,5 +0,0 @@
#!/bin/bash
rm /var/tmp/django-polymorphic-test-db.sqlite3
./manage.py syncdb

View File

@ -1,8 +0,0 @@
#!/bin/bash
colordiff -u -w libraries-local/django-versions/django1.1/core/management/commands/dumpdata.py polymorphic/management/commands/polymorphic_dumpdata_11.py
colordiff -u -w libraries-local/django-versions/django1.2/core/management/commands/dumpdata.py polymorphic/management/commands/polymorphic_dumpdata_12.py
colordiff -u -w libraries-local/django-versions/django1.3/core/management/commands/dumpdata.py polymorphic/management/commands/polymorphic_dumpdata_13.py

View File

@ -0,0 +1,100 @@
import os
DEBUG = True
TEMPLATE_DEBUG = DEBUG
ADMINS = (
# ('Your Name', 'your_email@example.com'),
)
MANAGERS = ADMINS
PROJECT_ROOT = os.path.dirname(os.path.dirname(__file__))
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(PROJECT_ROOT, 'example.db'),
}
}
SITE_ID = 1
# Make this unique, and don't share it with anybody.
SECRET_KEY = '5$f%)&a4tc*bg(79+ku!7o$kri-duw99@hq_)va^_kaw9*l)!7'
# Language
# TIME_ZONE = 'America/Chicago'
LANGUAGE_CODE = 'en-us'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Paths
MEDIA_ROOT = ''
MEDIA_URL = '/media/'
STATIC_ROOT = ''
STATIC_URL = '/static/'
# Apps
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
)
TEMPLATE_LOADERS = (
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
)
MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
)
ROOT_URLCONF = 'example.urls'
WSGI_APPLICATION = 'example.wsgi.application'
TEMPLATE_DIRS = ()
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.admin',
'django.contrib.contenttypes',
'django.contrib.sessions',
#'django.contrib.sites',
'django.contrib.messages',
'django.contrib.staticfiles',
'polymorphic', # needed if you want to use the polymorphic admin
'pexp', # this Django app is for testing and experimentation; not needed otherwise
)
# Logging configuration
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'filters': {
'require_debug_false': {
'()': 'django.utils.log.RequireDebugFalse'
}
},
'handlers': {
'mail_admins': {
'level': 'ERROR',
'filters': ['require_debug_false'],
'class': 'django.utils.log.AdminEmailHandler'
}
},
'loggers': {
'django.request': {
'handlers': ['mail_admins'],
'level': 'ERROR',
'propagate': True,
},
}
}

View File

@ -0,0 +1,11 @@
from django.conf.urls import patterns, include, url
from django.contrib import admin
from django.core.urlresolvers import reverse_lazy
from django.views.generic import RedirectView
admin.autodiscover()
urlpatterns = patterns('',
url(r'^admin/', include(admin.site.urls)),
url(r'^$', RedirectView.as_view(url=reverse_lazy('admin:index'), permanent=False)),
)

View File

@ -0,0 +1,28 @@
"""
WSGI config for example project.
This module contains the WSGI application used by Django's development server
and any production WSGI deployments. It should expose a module-level variable
named ``application``. Django's ``runserver`` and ``runfcgi`` commands discover
this application via the ``WSGI_APPLICATION`` setting.
Usually you will have the standard Django WSGI application here, but it also
might make sense to replace the whole Django WSGI application with a custom one
that later delegates to the Django one. For example, you could introduce WSGI
middleware here, or combine a Django application with an application of another
framework.
"""
import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "example.settings")
# This application object is used by any WSGI server configured to use this
# file. This includes Django's development server, if the WSGI_APPLICATION
# setting points here.
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()
# Apply WSGI middleware here.
# from helloworld.wsgi import HelloWorldApplication
# application = HelloWorldApplication(application)

14
example/manage.py 100755
View File

@ -0,0 +1,14 @@
#!/usr/bin/env python
import os
import sys
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "example.settings")
# Import polymorphic from this folder.
SRC_ROOT = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
sys.path.insert(0, SRC_ROOT)
from django.core.management import execute_from_command_line
execute_from_command_line(sys.argv)

View File

@ -8,7 +8,6 @@ import uuid
from django.core.management.base import NoArgsCommand
from django.db.models import connection
from pprint import pprint
import settings
import time,sys
from pexp.models import *
@ -44,9 +43,6 @@ class Command(NoArgsCommand):
help = ""
def handle_noargs(self, **options):
print 'polycmd - sqlite test db is stored in:',settings.SQLITE_DB_PATH
print
if False:
ModelA.objects.all().delete()
a=ModelA.objects.create(field1='A1')

View File

@ -6,7 +6,6 @@ This module is a scratchpad for general development, testing & debugging.
from django.core.management.base import NoArgsCommand
from django.db.models import connection
from pprint import pprint
import settings
from pexp.models import *
@ -20,9 +19,6 @@ class Command(NoArgsCommand):
help = ""
def handle_noargs(self, **options):
print 'polycmd - sqlite test db is stored in:',settings.SQLITE_DB_PATH
print
Project.objects.all().delete()
a=Project.objects.create(topic="John's gathering")
b=ArtProject.objects.create(topic="Sculpting with Tim", artist="T. Turner")

View File

@ -6,7 +6,6 @@ This module is a scratchpad for general development, testing & debugging
from django.core.management.base import NoArgsCommand
from django.db.models import connection
from pprint import pprint
import settings
import sys
from pexp.models import *
@ -90,8 +89,6 @@ class Command(NoArgsCommand):
help = ""
def handle_noargs(self, **options):
print 'polybench - sqlite test db is stored in:',settings.SQLITE_DB_PATH
func_list = [
( bench_delete, 1 ),
( bench_create, 1 ),

View File

@ -6,7 +6,6 @@ This module is a scratchpad for general development, testing & debugging
from django.core.management.base import NoArgsCommand
from django.db.models import connection
from pprint import pprint
import settings
from pexp.models import *
@ -20,9 +19,6 @@ class Command(NoArgsCommand):
help = ""
def handle_noargs(self, **options):
print 'polycmd - sqlite test db is stored in:',settings.SQLITE_DB_PATH
print
Project.objects.all().delete()
o=Project.objects.create(topic="John's gathering")
o=ArtProject.objects.create(topic="Sculpting with Tim", artist="T. Turner")

View File

@ -1,29 +0,0 @@
#!/usr/bin/env python
# Prepend project subdirectory 'libraries-local' to sys.path.
# This allows us to use/test any version of Django
# (e.g. Django 1.2 subversion) or any other packages/libraries.
import sys, os
project_path = os.path.dirname(os.path.abspath(__file__))
libs_local_path = os.path.join(project_path, 'libraries-local')
if libs_local_path not in sys.path: sys.path.insert(1, libs_local_path)
sys.stderr.write( 'using Python version: %s\n' % sys.version[:5])
import django
sys.stderr.write( 'using Django version: %s, from %s\n' % (
django.get_version(),
os.path.dirname(os.path.abspath(django.__file__))) )
# vanilla Django manage.py from here on:
from django.core.management import execute_manager
try:
import settings # Assumed to be in the same directory.
except ImportError:
import sys
sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__)
sys.exit(1)
if __name__ == "__main__":
execute_manager(settings)

View File

@ -1,23 +0,0 @@
"""
This file demonstrates two different styles of tests (one doctest and one
unittest). These will both pass when you run "manage.py test".
Replace these with more appropriate tests for your application.
"""
from django.test import TestCase
class SimpleTest(TestCase):
def test_basic_addition(self):
"""
Tests that 1 + 1 always equals 2.
"""
self.failUnlessEqual(1 + 1, 2)
__test__ = {"doctest": """
Another way to test that 1 + 1 is equal to 2.
>>> 1 + 1 == 2
True
"""}

View File

@ -1 +0,0 @@
# Create your views here.

View File

@ -1,9 +0,0 @@
"""
polymorphic_dumpdata has been disabled since it's no longer needed
(this is now handled by polymorphic.base.PolymorphicModelBase).
"""
assert False, """
ERROR: The management command polymorphic_dumpdata is no longer supported or needed.
Please use the standard Django dumpdata management command instead!
"""

View File

@ -2,21 +2,18 @@
""" Test Cases
Please see README.rst or DOCS.rst or http://chrisglass.github.com/django_polymorphic/
"""
import uuid
import re
from django.conf import settings
import sys
from pprint import pprint
from django import VERSION as django_VERSION
from django.test import TestCase
from django.db.models.query import QuerySet
from django.db.models import Q,Count
from django.db import models
from django.contrib.contenttypes.models import ContentType
from polymorphic import PolymorphicModel, PolymorphicManager, PolymorphicQuerySet
from polymorphic import ShowFieldContent, ShowFieldType, ShowFieldTypeAndContent, get_version
from polymorphic import translate_polymorphic_Q_object
from polymorphic import PolymorphicModel, PolymorphicManager
from polymorphic import ShowFieldContent, ShowFieldType, ShowFieldTypeAndContent
from polymorphic.tools_for_tests import UUIDField
class PlainA(models.Model):
field1 = models.CharField(max_length=10)
@ -165,27 +162,20 @@ class Bottom(Middle):
author = models.CharField(max_length=50)
# UUID tests won't work with Django 1.1
if not (django_VERSION[0] <= 1 and django_VERSION[1] <= 1):
try: from polymorphic.tools_for_tests import UUIDField
except: pass
if 'UUIDField' in globals():
import uuid
class UUIDProject(ShowFieldTypeAndContent, PolymorphicModel):
class UUIDProject(ShowFieldTypeAndContent, PolymorphicModel):
uuid_primary_key = UUIDField(primary_key = True)
topic = models.CharField(max_length = 30)
class UUIDArtProject(UUIDProject):
class UUIDArtProject(UUIDProject):
artist = models.CharField(max_length = 30)
class UUIDResearchProject(UUIDProject):
class UUIDResearchProject(UUIDProject):
supervisor = models.CharField(max_length = 30)
class UUIDPlainA(models.Model):
class UUIDPlainA(models.Model):
uuid_primary_key = UUIDField(primary_key = True)
field1 = models.CharField(max_length=10)
class UUIDPlainB(UUIDPlainA):
class UUIDPlainB(UUIDPlainA):
field2 = models.CharField(max_length=10)
class UUIDPlainC(UUIDPlainB):
class UUIDPlainC(UUIDPlainB):
field3 = models.CharField(max_length=10)
@ -200,51 +190,53 @@ 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):
# create a blog of type BlogA
blog = BlogA.objects.create(name='B1', info='i1')
# create two blog entries in BlogA
entry1 = blog.blogentry_set.create(text='bla')
entry2 = BlogEntry.objects.create(blog=blog, text='bla2')
# create some blogs of type BlogB to make the BlogBase table data really polymorphic
o = BlogB.objects.create(name='Bb1')
o = BlogB.objects.create(name='Bb2')
o = BlogB.objects.create(name='Bb3')
blog = BlogA.objects.create(name='B1', info='i1')
blog.blogentry_set.create(text='bla')
BlogEntry.objects.create(blog=blog, text='bla2')
BlogB.objects.create(name='Bb1')
BlogB.objects.create(name='Bb2')
BlogB.objects.create(name='Bb3')
qs = BlogBase.objects.annotate(entrycount=Count('BlogA___blogentry'))
assert len(qs)==4
self.assertEqual(len(qs), 4)
for o in qs:
if o.name=='B1':
assert o.entrycount == 2
if o.name == 'B1':
self.assertEqual(o.entrycount, 2)
else:
assert o.entrycount == 0
self.assertEqual(o.entrycount, 0)
x = BlogBase.objects.aggregate(entrycount=Count('BlogA___blogentry'))
assert x['entrycount'] == 2
self.assertEqual(x['entrycount'], 2)
# create some more blogs for next test
b2 = BlogA.objects.create(name='B2', info='i2')
b2 = BlogA.objects.create(name='B3', info='i3')
b2 = BlogA.objects.create(name='B4', info='i4')
b2 = BlogA.objects.create(name='B5', info='i5')
### test ordering for field in all entries
BlogA.objects.create(name='B2', info='i2')
BlogA.objects.create(name='B3', info='i3')
BlogA.objects.create(name='B4', info='i4')
BlogA.objects.create(name='B5', info='i5')
# test ordering for field in all entries
expected = '''
[ <BlogB: id 4, name (CharField) "Bb3">,
<BlogB: id 3, name (CharField) "Bb2">,
@ -255,10 +247,9 @@ class testclass(TestCase):
<BlogA: id 5, name (CharField) "B2", info (CharField) "i2">,
<BlogA: id 1, name (CharField) "B1", info (CharField) "i1"> ]'''
x = '\n' + repr(BlogBase.objects.order_by('-name'))
assert x == expected
### test ordering for field in one subclass only
self.assertEqual(x, expected)
# test ordering for field in one subclass only
# MySQL and SQLite return this order
expected1='''
[ <BlogA: id 8, name (CharField) "B5", info (CharField) "i5">,
@ -282,11 +273,13 @@ class testclass(TestCase):
<BlogA: id 1, name (CharField) "B1", info (CharField) "i1"> ]'''
x = '\n' + repr(BlogBase.objects.order_by('-BlogA___info'))
assert x == expected1 or x == expected2
self.assertTrue(x == expected1 or x == expected2)
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
"""
# create a blog of type BlogA
blog_a = BlogA.objects.create(name='aa', info='aa')
blog_b = BlogB.objects.create(name='bb')
@ -296,332 +289,339 @@ class testclass(TestCase):
def test_primary_key_custom_field_problem(self):
"object retrieval problem occuring with some custom primary key fields (UUIDField as test case)"
if not 'UUIDField' in globals(): return
a=UUIDProject.objects.create(topic="John's gathering")
b=UUIDArtProject.objects.create(topic="Sculpting with Tim", artist="T. Turner")
c=UUIDResearchProject.objects.create(topic="Swallow Aerodynamics", supervisor="Dr. Winter")
qs=UUIDProject.objects.all()
ol=list(qs)
a=qs[0]
b=qs[1]
c=qs[2]
assert len(qs)==3
assert type(a.uuid_primary_key)==uuid.UUID and type(a.pk)==uuid.UUID
res=repr(qs)
import re
res=re.sub(' "(.*?)..", topic',', topic',res)
res_exp="""[ <UUIDProject: uuid_primary_key (UUIDField/pk), topic (CharField) "John's gathering">,
"""
object retrieval problem occuring with some custom primary key fields (UUIDField as test case)
"""
UUIDProject.objects.create(topic="John's gathering")
UUIDArtProject.objects.create(topic="Sculpting with Tim", artist="T. Turner")
UUIDResearchProject.objects.create(topic="Swallow Aerodynamics", supervisor="Dr. Winter")
qs = UUIDProject.objects.all()
ol = list(qs)
a = qs[0]
b = qs[1]
c = qs[2]
self.assertEqual(len(qs), 3)
self.assertIsInstance(a.uuid_primary_key, uuid.UUID)
self.assertIsInstance(a.pk, uuid.UUID)
res = re.sub(' "(.*?)..", topic',', topic', repr(qs))
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">,
<UUIDResearchProject: uuid_primary_key (UUIDField/pk), topic (CharField) "Swallow Aerodynamics", supervisor (CharField) "Dr. Winter"> ]"""
assert res==res_exp, res
self.assertEqual(res, res_exp)
#if (a.pk!= uuid.UUID or c.pk!= uuid.UUID):
# print
# print '# known inconstency with custom primary key field detected (django problem?)'
a=UUIDPlainA.objects.create(field1='A1')
b=UUIDPlainB.objects.create(field1='B1', field2='B2')
c=UUIDPlainC.objects.create(field1='C1', field2='C2', field3='C3')
qs=UUIDPlainA.objects.all()
if (a.pk!= uuid.UUID or c.pk!= uuid.UUID):
a = UUIDPlainA.objects.create(field1='A1')
b = UUIDPlainB.objects.create(field1='B1', field2='B2')
c = UUIDPlainC.objects.create(field1='C1', field2='C2', field3='C3')
qs = UUIDPlainA.objects.all()
if a.pk!= uuid.UUID or c.pk!= uuid.UUID:
print
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):

60
runtests.py 100755
View File

@ -0,0 +1,60 @@
#!/usr/bin/env python
from django.conf import settings, global_settings as default_settings
from django.core.management import call_command
from os.path import dirname, realpath
import django
import sys
import os
# Give feedback on used versions
sys.stderr.write('Using Python version {0} from {1}\n'.format(sys.version[:5], sys.executable))
sys.stderr.write('Using Django version {0} from {1}\n'.format(
django.get_version(),
os.path.dirname(os.path.abspath(django.__file__)))
)
# Detect location and available modules
module_root = dirname(realpath(__file__))
# Inline settings file
settings.configure(
DEBUG = False, # will be False anyway by DjangoTestRunner.
TEMPLATE_DEBUG = False,
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': ':memory:'
}
},
TEMPLATE_LOADERS = (
'django.template.loaders.app_directories.Loader',
),
TEMPLATE_CONTEXT_PROCESSORS = default_settings.TEMPLATE_CONTEXT_PROCESSORS + (
'django.core.context_processors.request',
),
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.messages',
'django.contrib.sites',
'django.contrib.admin',
'polymorphic',
),
SITE_ID = 3,
)
call_command('syncdb', verbosity=1, interactive=False)
# ---- app start
verbosity = 2 if '-v' in sys.argv else 1
from django.test.utils import get_runner
TestRunner = get_runner(settings) # DjangoTestSuiteRunner
runner = TestRunner(verbosity=verbosity, interactive=True, failfast=False)
failures = runner.run_tests(['polymorphic'])
if failures:
sys.exit(bool(failures))

View File

@ -1,87 +0,0 @@
# Django settings for polymorphic_demo project.
DEBUG = True
TEMPLATE_DEBUG = DEBUG
ADMINS = (
# ('Your Name', 'your_email@domain.com'),
)
MANAGERS = ADMINS
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': ':memory:'
}
}
# Local time zone for this installation. Choices can be found here:
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
# although not all choices may be available on all operating systems.
# If running in a Windows environment this must be set to the same as your
# system time zone.
TIME_ZONE = 'America/Chicago'
# Language code for this installation. All choices can be found here:
# http://www.i18nguy.com/unicode/language-identifiers.html
LANGUAGE_CODE = 'en-us'
SITE_ID = 1
# If you set this to False, Django will make some optimizations so as not
# to load the internationalization machinery.
USE_I18N = True
# Absolute path to the directory that holds media.
# Example: "/home/media/media.lawrence.com/"
MEDIA_ROOT = ''
# URL that handles the media served from MEDIA_ROOT. Make sure to use a
# trailing slash if there is a path component (optional in other cases).
# Examples: "http://media.lawrence.com", "http://example.com/media/"
MEDIA_URL = ''
# URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a
# trailing slash.
# Examples: "http://foo.com/media/", "/media/".
ADMIN_MEDIA_PREFIX = '/media/'
# Make this unique, and don't share it with anybody.
SECRET_KEY = 'nk=c&k+c&#+)8557)%&0auysdd3g^sfq6@rw8_x1k8)-p@y)!('
# List of callables that know how to import templates from various sources.
TEMPLATE_LOADERS = (
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
)
MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
)
ROOT_URLCONF = 'urls'
STATIC_URL = '/static/'
ADMIN_MEDIA_PREFIX = '/static/admin/' # 1.3 compatibility
TEMPLATE_DIRS = (
# Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
# Always use forward slashes, even on Windows.
# Don't forget to use absolute paths, not relative paths.
)
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.admin',
'django.contrib.contenttypes',
'django.contrib.messages',
'django.contrib.sessions',
'django.contrib.staticfiles',
#'django.contrib.sites',
'polymorphic', # needed if you want to use the polymorphic admin
'pexp', # this Django app is for testing and experimentation; not needed otherwise
)

View File

@ -20,6 +20,7 @@ setup(
},
install_requires=['setuptools'],
test_suite='runtests',
classifiers=[
'Framework :: Django',

View File

@ -1,73 +0,0 @@
#!/bin/bash
# this test script runs "./manage.py test" for
# all supported python versions (2.4, 2.5, 2.6)
# and all supported Django versions (1.1, 1.2, 1.3)
# it needs symbolic links named "django1.1" and "django1.2" etc. in:
# libraries-local/django-versions
# which point to the respective django versions
cd libraries-local
rm -f django-orig
if test -e django ; then mv django django-orig ; fi
cd ..
function restore_django {
echo "### restoring original libraries-local/django"
cd libraries-local
if test -e django-orig ; then mv django-orig django ; fi
cd .
}
function test_python_version {
echo ; echo ; echo
echo "#########################################################################"
echo "### Testing Python $1, Django $2"
echo "#########################################################################"
echo
if which python$1 ; then
if ! python$1 manage.py test polymorphic; then
echo ERROR
restore_django
exit 10
fi
if ! ./test_dumpdata $1 ; then
echo ERROR
restore_django
exit 10
fi
else
echo
echo "### python $1 is not installed!"
echo
fi
}
function test_all_python_versions {
test_python_version 2.4 $1
test_python_version 2.5 $1
test_python_version 2.6 $1
}
function test_django_version {
if ! test -e libraries-local/django-versions/django$1 ; then
echo
echo "### django $1 is not installed!"
echo
return
fi
cd libraries-local
rm -f django
ln -s django-versions/django$1 django
cd ..
test_all_python_versions $1
}
test_django_version 1.1
test_django_version 1.2
test_django_version 1.3
restore_django

View File

@ -1,27 +0,0 @@
#!/bin/bash
rm -f /var/tmp/django-polymorphic-test-db.sqlite3
rm -f /ram/django-polymorphic-test-db.sqlite3
TMPFILE=/tmp/django-polymorphic-test.dump
PYCMD="python$1"
echo
echo "#####################################################################"
echo "### Testing dumpdata"
echo
$PYCMD ./manage.py syncdb
$PYCMD ./manage.py polymorphic_create_test_data
$PYCMD ./manage.py dumpdata --indent=4 pexp >$TMPFILE
if ! diff -w $TMPFILE pexp/dumpdata_test_correct_output.txt ; then
echo "#####################################################################"
echo "ERROR: test_dumpdata failed!"
exit 10
fi
echo "#####################################################################"
echo 'SUCCESS!'

View File

@ -7,7 +7,7 @@ envlist=
[testenv]
commands=
python manage.py test
python runtests.py
# Build configurations

10
urls.py
View File

@ -1,10 +0,0 @@
from django.conf import settings
from django.conf.urls.defaults import patterns, include, url
from django.conf.urls.static import static
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
url(r'^admin/', include(admin.site.urls)),
)