Migrated proxy_models doctests. Thanks to Eric Florenzano.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@13831 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
b7cd1682f5
commit
17c097b166
|
@ -161,232 +161,4 @@ class Improvement(Issue):
|
||||||
|
|
||||||
class ProxyImprovement(Improvement):
|
class ProxyImprovement(Improvement):
|
||||||
class Meta:
|
class Meta:
|
||||||
proxy = True
|
proxy = True
|
||||||
|
|
||||||
__test__ = {'API_TESTS' : """
|
|
||||||
# The MyPerson model should be generating the same database queries as the
|
|
||||||
# Person model (when the same manager is used in each case).
|
|
||||||
>>> from django.db import DEFAULT_DB_ALIAS
|
|
||||||
>>> MyPerson.other.all().query.get_compiler(DEFAULT_DB_ALIAS).as_sql() == Person.objects.order_by("name").query.get_compiler(DEFAULT_DB_ALIAS).as_sql()
|
|
||||||
True
|
|
||||||
|
|
||||||
# The StatusPerson models should have its own table (it's using ORM-level
|
|
||||||
# inheritance).
|
|
||||||
>>> StatusPerson.objects.all().query.get_compiler(DEFAULT_DB_ALIAS).as_sql() == Person.objects.all().query.get_compiler(DEFAULT_DB_ALIAS).as_sql()
|
|
||||||
False
|
|
||||||
|
|
||||||
# Creating a Person makes them accessible through the MyPerson proxy.
|
|
||||||
>>> _ = Person.objects.create(name="Foo McBar")
|
|
||||||
>>> len(Person.objects.all())
|
|
||||||
1
|
|
||||||
>>> len(MyPerson.objects.all())
|
|
||||||
1
|
|
||||||
>>> MyPerson.objects.get(name="Foo McBar").id
|
|
||||||
1
|
|
||||||
>>> MyPerson.objects.get(id=1).has_special_name()
|
|
||||||
False
|
|
||||||
|
|
||||||
# Person is not proxied by StatusPerson subclass, however.
|
|
||||||
>>> StatusPerson.objects.all()
|
|
||||||
[]
|
|
||||||
|
|
||||||
# A new MyPerson also shows up as a standard Person
|
|
||||||
>>> _ = MyPerson.objects.create(name="Bazza del Frob")
|
|
||||||
>>> len(MyPerson.objects.all())
|
|
||||||
2
|
|
||||||
>>> len(Person.objects.all())
|
|
||||||
2
|
|
||||||
|
|
||||||
>>> _ = LowerStatusPerson.objects.create(status="low", name="homer")
|
|
||||||
>>> LowerStatusPerson.objects.all()
|
|
||||||
[<LowerStatusPerson: homer>]
|
|
||||||
|
|
||||||
# Correct type when querying a proxy of proxy
|
|
||||||
|
|
||||||
>>> MyPersonProxy.objects.all()
|
|
||||||
[<MyPersonProxy: Bazza del Frob>, <MyPersonProxy: Foo McBar>, <MyPersonProxy: homer>]
|
|
||||||
|
|
||||||
# Proxy models are included in the ancestors for a model's DoesNotExist and MultipleObjectsReturned
|
|
||||||
>>> try:
|
|
||||||
... MyPersonProxy.objects.get(name='Zathras')
|
|
||||||
... except Person.DoesNotExist:
|
|
||||||
... pass
|
|
||||||
>>> try:
|
|
||||||
... MyPersonProxy.objects.get(id__lt=10)
|
|
||||||
... except Person.MultipleObjectsReturned:
|
|
||||||
... pass
|
|
||||||
>>> try:
|
|
||||||
... StatusPerson.objects.get(name='Zathras')
|
|
||||||
... except Person.DoesNotExist:
|
|
||||||
... pass
|
|
||||||
>>> sp1 = StatusPerson.objects.create(name='Bazza Jr.')
|
|
||||||
>>> sp2 = StatusPerson.objects.create(name='Foo Jr.')
|
|
||||||
>>> try:
|
|
||||||
... StatusPerson.objects.get(id__lt=10)
|
|
||||||
... except Person.MultipleObjectsReturned:
|
|
||||||
... pass
|
|
||||||
|
|
||||||
# And now for some things that shouldn't work...
|
|
||||||
#
|
|
||||||
# All base classes must be non-abstract
|
|
||||||
>>> class NoAbstract(Abstract):
|
|
||||||
... class Meta:
|
|
||||||
... proxy = True
|
|
||||||
Traceback (most recent call last):
|
|
||||||
....
|
|
||||||
TypeError: Abstract base class containing model fields not permitted for proxy model 'NoAbstract'.
|
|
||||||
|
|
||||||
# The proxy must actually have one concrete base class
|
|
||||||
>>> class TooManyBases(Person, Abstract):
|
|
||||||
... class Meta:
|
|
||||||
... proxy = True
|
|
||||||
Traceback (most recent call last):
|
|
||||||
....
|
|
||||||
TypeError: Abstract base class containing model fields not permitted for proxy model 'TooManyBases'.
|
|
||||||
|
|
||||||
>>> class NoBaseClasses(models.Model):
|
|
||||||
... class Meta:
|
|
||||||
... proxy = True
|
|
||||||
Traceback (most recent call last):
|
|
||||||
....
|
|
||||||
TypeError: Proxy model 'NoBaseClasses' has no non-abstract model base class.
|
|
||||||
|
|
||||||
|
|
||||||
# A proxy cannot introduce any new fields
|
|
||||||
>>> class NoNewFields(Person):
|
|
||||||
... newfield = models.BooleanField()
|
|
||||||
... class Meta:
|
|
||||||
... proxy = True
|
|
||||||
Traceback (most recent call last):
|
|
||||||
....
|
|
||||||
FieldError: Proxy model 'NoNewFields' contains model fields.
|
|
||||||
|
|
||||||
# Manager tests.
|
|
||||||
|
|
||||||
>>> Person.objects.all().delete()
|
|
||||||
>>> _ = Person.objects.create(name="fred")
|
|
||||||
>>> _ = Person.objects.create(name="wilma")
|
|
||||||
>>> _ = Person.objects.create(name="barney")
|
|
||||||
|
|
||||||
>>> MyPerson.objects.all()
|
|
||||||
[<MyPerson: barney>, <MyPerson: fred>]
|
|
||||||
>>> MyPerson._default_manager.all()
|
|
||||||
[<MyPerson: barney>, <MyPerson: fred>]
|
|
||||||
|
|
||||||
>>> OtherPerson.objects.all()
|
|
||||||
[<OtherPerson: barney>, <OtherPerson: wilma>]
|
|
||||||
>>> OtherPerson.excluder.all()
|
|
||||||
[<OtherPerson: barney>, <OtherPerson: fred>]
|
|
||||||
>>> OtherPerson._default_manager.all()
|
|
||||||
[<OtherPerson: barney>, <OtherPerson: wilma>]
|
|
||||||
|
|
||||||
# Test save signals for proxy models
|
|
||||||
>>> from django.db.models import signals
|
|
||||||
>>> def make_handler(model, event):
|
|
||||||
... def _handler(*args, **kwargs):
|
|
||||||
... print u"%s %s save" % (model, event)
|
|
||||||
... return _handler
|
|
||||||
>>> h1 = make_handler('MyPerson', 'pre')
|
|
||||||
>>> h2 = make_handler('MyPerson', 'post')
|
|
||||||
>>> h3 = make_handler('Person', 'pre')
|
|
||||||
>>> h4 = make_handler('Person', 'post')
|
|
||||||
>>> signals.pre_save.connect(h1, sender=MyPerson)
|
|
||||||
>>> signals.post_save.connect(h2, sender=MyPerson)
|
|
||||||
>>> signals.pre_save.connect(h3, sender=Person)
|
|
||||||
>>> signals.post_save.connect(h4, sender=Person)
|
|
||||||
>>> dino = MyPerson.objects.create(name=u"dino")
|
|
||||||
MyPerson pre save
|
|
||||||
MyPerson post save
|
|
||||||
|
|
||||||
# Test save signals for proxy proxy models
|
|
||||||
>>> h5 = make_handler('MyPersonProxy', 'pre')
|
|
||||||
>>> h6 = make_handler('MyPersonProxy', 'post')
|
|
||||||
>>> signals.pre_save.connect(h5, sender=MyPersonProxy)
|
|
||||||
>>> signals.post_save.connect(h6, sender=MyPersonProxy)
|
|
||||||
>>> dino = MyPersonProxy.objects.create(name=u"pebbles")
|
|
||||||
MyPersonProxy pre save
|
|
||||||
MyPersonProxy post save
|
|
||||||
|
|
||||||
>>> signals.pre_save.disconnect(h1, sender=MyPerson)
|
|
||||||
>>> signals.post_save.disconnect(h2, sender=MyPerson)
|
|
||||||
>>> signals.pre_save.disconnect(h3, sender=Person)
|
|
||||||
>>> signals.post_save.disconnect(h4, sender=Person)
|
|
||||||
>>> signals.pre_save.disconnect(h5, sender=MyPersonProxy)
|
|
||||||
>>> signals.post_save.disconnect(h6, sender=MyPersonProxy)
|
|
||||||
|
|
||||||
# A proxy has the same content type as the model it is proxying for (at the
|
|
||||||
# storage level, it is meant to be essentially indistinguishable).
|
|
||||||
>>> ctype = ContentType.objects.get_for_model
|
|
||||||
>>> ctype(Person) is ctype(OtherPerson)
|
|
||||||
True
|
|
||||||
|
|
||||||
>>> MyPersonProxy.objects.all()
|
|
||||||
[<MyPersonProxy: barney>, <MyPersonProxy: dino>, <MyPersonProxy: fred>, <MyPersonProxy: pebbles>]
|
|
||||||
|
|
||||||
>>> u = User.objects.create(name='Bruce')
|
|
||||||
>>> User.objects.all()
|
|
||||||
[<User: Bruce>]
|
|
||||||
>>> UserProxy.objects.all()
|
|
||||||
[<UserProxy: Bruce>]
|
|
||||||
>>> UserProxyProxy.objects.all()
|
|
||||||
[<UserProxyProxy: Bruce>]
|
|
||||||
|
|
||||||
# Proxy objects can be deleted
|
|
||||||
>>> u2 = UserProxy.objects.create(name='George')
|
|
||||||
>>> UserProxy.objects.all()
|
|
||||||
[<UserProxy: Bruce>, <UserProxy: George>]
|
|
||||||
>>> u2.delete()
|
|
||||||
>>> UserProxy.objects.all()
|
|
||||||
[<UserProxy: Bruce>]
|
|
||||||
|
|
||||||
|
|
||||||
# We can still use `select_related()` to include related models in our querysets.
|
|
||||||
>>> country = Country.objects.create(name='Australia')
|
|
||||||
>>> state = State.objects.create(name='New South Wales', country=country)
|
|
||||||
|
|
||||||
>>> State.objects.select_related()
|
|
||||||
[<State: New South Wales>]
|
|
||||||
>>> StateProxy.objects.select_related()
|
|
||||||
[<StateProxy: New South Wales>]
|
|
||||||
>>> StateProxy.objects.get(name='New South Wales')
|
|
||||||
<StateProxy: New South Wales>
|
|
||||||
>>> StateProxy.objects.select_related().get(name='New South Wales')
|
|
||||||
<StateProxy: New South Wales>
|
|
||||||
|
|
||||||
>>> contributor = TrackerUser.objects.create(name='Contributor',status='contrib')
|
|
||||||
>>> someone = BaseUser.objects.create(name='Someone')
|
|
||||||
>>> _ = Bug.objects.create(summary='fix this', version='1.1beta',
|
|
||||||
... assignee=contributor, reporter=someone)
|
|
||||||
>>> pcontributor = ProxyTrackerUser.objects.create(name='OtherContributor',
|
|
||||||
... status='proxy')
|
|
||||||
>>> _ = Improvement.objects.create(summary='improve that', version='1.1beta',
|
|
||||||
... assignee=contributor, reporter=pcontributor,
|
|
||||||
... associated_bug=ProxyProxyBug.objects.all()[0])
|
|
||||||
|
|
||||||
# Related field filter on proxy
|
|
||||||
>>> ProxyBug.objects.get(version__icontains='beta')
|
|
||||||
<ProxyBug: ProxyBug:fix this>
|
|
||||||
|
|
||||||
# Select related + filter on proxy
|
|
||||||
>>> ProxyBug.objects.select_related().get(version__icontains='beta')
|
|
||||||
<ProxyBug: ProxyBug:fix this>
|
|
||||||
|
|
||||||
# Proxy of proxy, select_related + filter
|
|
||||||
>>> ProxyProxyBug.objects.select_related().get(version__icontains='beta')
|
|
||||||
<ProxyProxyBug: ProxyProxyBug:fix this>
|
|
||||||
|
|
||||||
# Select related + filter on a related proxy field
|
|
||||||
>>> ProxyImprovement.objects.select_related().get(reporter__name__icontains='butor')
|
|
||||||
<ProxyImprovement: ProxyImprovement:improve that>
|
|
||||||
|
|
||||||
# Select related + filter on a related proxy of proxy field
|
|
||||||
>>> ProxyImprovement.objects.select_related().get(associated_bug__summary__icontains='fix')
|
|
||||||
<ProxyImprovement: ProxyImprovement:improve that>
|
|
||||||
|
|
||||||
Proxy models can be loaded from fixtures (Regression for #11194)
|
|
||||||
>>> from django.core import management
|
|
||||||
>>> management.call_command('loaddata', 'mypeople.json', verbosity=0)
|
|
||||||
>>> MyPerson.objects.get(pk=100)
|
|
||||||
<MyPerson: Elvis Presley>
|
|
||||||
|
|
||||||
"""}
|
|
|
@ -0,0 +1,314 @@
|
||||||
|
from django.test import TestCase
|
||||||
|
from django.db import models, DEFAULT_DB_ALIAS
|
||||||
|
from django.db.models import signals
|
||||||
|
from django.core import management
|
||||||
|
from django.core.exceptions import FieldError
|
||||||
|
|
||||||
|
from django.contrib.contenttypes.models import ContentType
|
||||||
|
|
||||||
|
from models import MyPerson, Person, StatusPerson, LowerStatusPerson
|
||||||
|
from models import MyPersonProxy, Abstract, OtherPerson, User, UserProxy
|
||||||
|
from models import UserProxyProxy, Country, State, StateProxy, TrackerUser
|
||||||
|
from models import BaseUser, Bug, ProxyTrackerUser, Improvement, ProxyProxyBug
|
||||||
|
from models import ProxyBug, ProxyImprovement
|
||||||
|
|
||||||
|
class ProxyModelTests(TestCase):
|
||||||
|
def test_same_manager_queries(self):
|
||||||
|
"""
|
||||||
|
The MyPerson model should be generating the same database queries as
|
||||||
|
the Person model (when the same manager is used in each case).
|
||||||
|
"""
|
||||||
|
my_person_sql = MyPerson.other.all().query.get_compiler(
|
||||||
|
DEFAULT_DB_ALIAS).as_sql()
|
||||||
|
person_sql = Person.objects.order_by("name").query.get_compiler(
|
||||||
|
DEFAULT_DB_ALIAS).as_sql()
|
||||||
|
self.assertEqual(my_person_sql, person_sql)
|
||||||
|
|
||||||
|
def test_inheretance_new_table(self):
|
||||||
|
"""
|
||||||
|
The StatusPerson models should have its own table (it's using ORM-level
|
||||||
|
inheritance).
|
||||||
|
"""
|
||||||
|
sp_sql = StatusPerson.objects.all().query.get_compiler(
|
||||||
|
DEFAULT_DB_ALIAS).as_sql()
|
||||||
|
p_sql = Person.objects.all().query.get_compiler(
|
||||||
|
DEFAULT_DB_ALIAS).as_sql()
|
||||||
|
self.assertNotEqual(sp_sql, p_sql)
|
||||||
|
|
||||||
|
def test_basic_proxy(self):
|
||||||
|
"""
|
||||||
|
Creating a Person makes them accessible through the MyPerson proxy.
|
||||||
|
"""
|
||||||
|
Person.objects.create(name="Foo McBar")
|
||||||
|
self.assertEqual(len(Person.objects.all()), 1)
|
||||||
|
self.assertEqual(len(MyPerson.objects.all()), 1)
|
||||||
|
self.assertEqual(MyPerson.objects.get(name="Foo McBar").id, 1)
|
||||||
|
self.assertFalse(MyPerson.objects.get(id=1).has_special_name())
|
||||||
|
|
||||||
|
def test_no_proxy(self):
|
||||||
|
"""
|
||||||
|
Person is not proxied by StatusPerson subclass.
|
||||||
|
"""
|
||||||
|
Person.objects.create(name="Foo McBar")
|
||||||
|
self.assertEqual(list(StatusPerson.objects.all()), [])
|
||||||
|
|
||||||
|
def test_basic_proxy_reverse(self):
|
||||||
|
"""
|
||||||
|
A new MyPerson also shows up as a standard Person.
|
||||||
|
"""
|
||||||
|
MyPerson.objects.create(name="Bazza del Frob")
|
||||||
|
self.assertEqual(len(MyPerson.objects.all()), 1)
|
||||||
|
self.assertEqual(len(Person.objects.all()), 1)
|
||||||
|
|
||||||
|
LowerStatusPerson.objects.create(status="low", name="homer")
|
||||||
|
lsps = [lsp.name for lsp in LowerStatusPerson.objects.all()]
|
||||||
|
self.assertEqual(lsps, ["homer"])
|
||||||
|
|
||||||
|
def test_correct_type_proxy_of_proxy(self):
|
||||||
|
"""
|
||||||
|
Correct type when querying a proxy of proxy
|
||||||
|
"""
|
||||||
|
Person.objects.create(name="Foo McBar")
|
||||||
|
MyPerson.objects.create(name="Bazza del Frob")
|
||||||
|
LowerStatusPerson.objects.create(status="low", name="homer")
|
||||||
|
pp = sorted([mpp.name for mpp in MyPersonProxy.objects.all()])
|
||||||
|
self.assertEqual(pp, ['Bazza del Frob', 'Foo McBar', 'homer'])
|
||||||
|
|
||||||
|
def test_proxy_included_in_ancestors(self):
|
||||||
|
"""
|
||||||
|
Proxy models are included in the ancestors for a model's DoesNotExist
|
||||||
|
and MultipleObjectsReturned
|
||||||
|
"""
|
||||||
|
Person.objects.create(name="Foo McBar")
|
||||||
|
MyPerson.objects.create(name="Bazza del Frob")
|
||||||
|
LowerStatusPerson.objects.create(status="low", name="homer")
|
||||||
|
max_id = Person.objects.aggregate(max_id=models.Max('id'))['max_id']
|
||||||
|
|
||||||
|
self.assertRaises(Person.DoesNotExist,
|
||||||
|
MyPersonProxy.objects.get,
|
||||||
|
name='Zathras'
|
||||||
|
)
|
||||||
|
self.assertRaises(Person.MultipleObjectsReturned,
|
||||||
|
MyPersonProxy.objects.get,
|
||||||
|
id__lt=max_id+1
|
||||||
|
)
|
||||||
|
self.assertRaises(Person.DoesNotExist,
|
||||||
|
StatusPerson.objects.get,
|
||||||
|
name='Zathras'
|
||||||
|
)
|
||||||
|
|
||||||
|
sp1 = StatusPerson.objects.create(name='Bazza Jr.')
|
||||||
|
sp2 = StatusPerson.objects.create(name='Foo Jr.')
|
||||||
|
max_id = Person.objects.aggregate(max_id=models.Max('id'))['max_id']
|
||||||
|
|
||||||
|
self.assertRaises(Person.MultipleObjectsReturned,
|
||||||
|
StatusPerson.objects.get,
|
||||||
|
id__lt=max_id+1
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_abc(self):
|
||||||
|
"""
|
||||||
|
All base classes must be non-abstract
|
||||||
|
"""
|
||||||
|
def build_abc():
|
||||||
|
class NoAbstract(Abstract):
|
||||||
|
class Meta:
|
||||||
|
proxy = True
|
||||||
|
self.assertRaises(TypeError, build_abc)
|
||||||
|
|
||||||
|
def test_no_cbc(self):
|
||||||
|
"""
|
||||||
|
The proxy must actually have one concrete base class
|
||||||
|
"""
|
||||||
|
def build_no_cbc():
|
||||||
|
class TooManyBases(Person, Abstract):
|
||||||
|
class Meta:
|
||||||
|
proxy = True
|
||||||
|
self.assertRaises(TypeError, build_no_cbc)
|
||||||
|
|
||||||
|
def test_no_base_classes(self):
|
||||||
|
def build_no_base_classes():
|
||||||
|
class NoBaseClasses(models.Model):
|
||||||
|
class Meta:
|
||||||
|
proxy = True
|
||||||
|
self.assertRaises(TypeError, build_no_base_classes)
|
||||||
|
|
||||||
|
def test_new_fields(self):
|
||||||
|
def build_new_fields():
|
||||||
|
class NoNewFields(Person):
|
||||||
|
newfield = models.BooleanField()
|
||||||
|
class Meta:
|
||||||
|
proxy = True
|
||||||
|
self.assertRaises(FieldError, build_new_fields)
|
||||||
|
|
||||||
|
def test_myperson_manager(self):
|
||||||
|
Person.objects.create(name="fred")
|
||||||
|
Person.objects.create(name="wilma")
|
||||||
|
Person.objects.create(name="barney")
|
||||||
|
|
||||||
|
resp = [p.name for p in MyPerson.objects.all()]
|
||||||
|
self.assertEqual(resp, ['barney', 'fred'])
|
||||||
|
|
||||||
|
resp = [p.name for p in MyPerson._default_manager.all()]
|
||||||
|
self.assertEqual(resp, ['barney', 'fred'])
|
||||||
|
|
||||||
|
def test_otherperson_manager(self):
|
||||||
|
Person.objects.create(name="fred")
|
||||||
|
Person.objects.create(name="wilma")
|
||||||
|
Person.objects.create(name="barney")
|
||||||
|
|
||||||
|
resp = [p.name for p in OtherPerson.objects.all()]
|
||||||
|
self.assertEqual(resp, ['barney', 'wilma'])
|
||||||
|
|
||||||
|
resp = [p.name for p in OtherPerson.excluder.all()]
|
||||||
|
self.assertEqual(resp, ['barney', 'fred'])
|
||||||
|
|
||||||
|
resp = [p.name for p in OtherPerson._default_manager.all()]
|
||||||
|
self.assertEqual(resp, ['barney', 'wilma'])
|
||||||
|
|
||||||
|
def test_proxy_model_signals(self):
|
||||||
|
"""
|
||||||
|
Test save signals for proxy models
|
||||||
|
"""
|
||||||
|
output = []
|
||||||
|
|
||||||
|
def make_handler(model, event):
|
||||||
|
def _handler(*args, **kwargs):
|
||||||
|
output.append('%s %s save' % (model, event))
|
||||||
|
return _handler
|
||||||
|
|
||||||
|
h1 = make_handler('MyPerson', 'pre')
|
||||||
|
h2 = make_handler('MyPerson', 'post')
|
||||||
|
h3 = make_handler('Person', 'pre')
|
||||||
|
h4 = make_handler('Person', 'post')
|
||||||
|
|
||||||
|
signals.pre_save.connect(h1, sender=MyPerson)
|
||||||
|
signals.post_save.connect(h2, sender=MyPerson)
|
||||||
|
signals.pre_save.connect(h3, sender=Person)
|
||||||
|
signals.post_save.connect(h4, sender=Person)
|
||||||
|
|
||||||
|
dino = MyPerson.objects.create(name=u"dino")
|
||||||
|
self.assertEqual(output, [
|
||||||
|
'MyPerson pre save',
|
||||||
|
'MyPerson post save'
|
||||||
|
])
|
||||||
|
|
||||||
|
output = []
|
||||||
|
|
||||||
|
h5 = make_handler('MyPersonProxy', 'pre')
|
||||||
|
h6 = make_handler('MyPersonProxy', 'post')
|
||||||
|
|
||||||
|
signals.pre_save.connect(h5, sender=MyPersonProxy)
|
||||||
|
signals.post_save.connect(h6, sender=MyPersonProxy)
|
||||||
|
|
||||||
|
dino = MyPersonProxy.objects.create(name=u"pebbles")
|
||||||
|
|
||||||
|
self.assertEqual(output, [
|
||||||
|
'MyPersonProxy pre save',
|
||||||
|
'MyPersonProxy post save'
|
||||||
|
])
|
||||||
|
|
||||||
|
signals.pre_save.disconnect(h1, sender=MyPerson)
|
||||||
|
signals.post_save.disconnect(h2, sender=MyPerson)
|
||||||
|
signals.pre_save.disconnect(h3, sender=Person)
|
||||||
|
signals.post_save.disconnect(h4, sender=Person)
|
||||||
|
signals.pre_save.disconnect(h5, sender=MyPersonProxy)
|
||||||
|
signals.post_save.disconnect(h6, sender=MyPersonProxy)
|
||||||
|
|
||||||
|
def test_content_type(self):
|
||||||
|
ctype = ContentType.objects.get_for_model
|
||||||
|
self.assertTrue(ctype(Person) is ctype(OtherPerson))
|
||||||
|
|
||||||
|
def test_user_userproxy_userproxyproxy(self):
|
||||||
|
User.objects.create(name='Bruce')
|
||||||
|
|
||||||
|
resp = [u.name for u in User.objects.all()]
|
||||||
|
self.assertEqual(resp, ['Bruce'])
|
||||||
|
|
||||||
|
resp = [u.name for u in UserProxy.objects.all()]
|
||||||
|
self.assertEqual(resp, ['Bruce'])
|
||||||
|
|
||||||
|
resp = [u.name for u in UserProxyProxy.objects.all()]
|
||||||
|
self.assertEqual(resp, ['Bruce'])
|
||||||
|
|
||||||
|
def test_proxy_delete(self):
|
||||||
|
"""
|
||||||
|
Proxy objects can be deleted
|
||||||
|
"""
|
||||||
|
User.objects.create(name='Bruce')
|
||||||
|
u2 = UserProxy.objects.create(name='George')
|
||||||
|
|
||||||
|
resp = [u.name for u in UserProxy.objects.all()]
|
||||||
|
self.assertEqual(resp, ['Bruce', 'George'])
|
||||||
|
|
||||||
|
u2.delete()
|
||||||
|
|
||||||
|
resp = [u.name for u in UserProxy.objects.all()]
|
||||||
|
self.assertEqual(resp, ['Bruce'])
|
||||||
|
|
||||||
|
def test_select_related(self):
|
||||||
|
"""
|
||||||
|
We can still use `select_related()` to include related models in our
|
||||||
|
querysets.
|
||||||
|
"""
|
||||||
|
country = Country.objects.create(name='Australia')
|
||||||
|
state = State.objects.create(name='New South Wales', country=country)
|
||||||
|
|
||||||
|
resp = [s.name for s in State.objects.select_related()]
|
||||||
|
self.assertEqual(resp, ['New South Wales'])
|
||||||
|
|
||||||
|
resp = [s.name for s in StateProxy.objects.select_related()]
|
||||||
|
self.assertEqual(resp, ['New South Wales'])
|
||||||
|
|
||||||
|
self.assertEqual(StateProxy.objects.get(name='New South Wales').name,
|
||||||
|
'New South Wales')
|
||||||
|
|
||||||
|
resp = StateProxy.objects.select_related().get(name='New South Wales')
|
||||||
|
self.assertEqual(resp.name, 'New South Wales')
|
||||||
|
|
||||||
|
def test_proxy_bug(self):
|
||||||
|
contributor = TrackerUser.objects.create(name='Contributor',
|
||||||
|
status='contrib')
|
||||||
|
someone = BaseUser.objects.create(name='Someone')
|
||||||
|
Bug.objects.create(summary='fix this', version='1.1beta',
|
||||||
|
assignee=contributor, reporter=someone)
|
||||||
|
pcontributor = ProxyTrackerUser.objects.create(name='OtherContributor',
|
||||||
|
status='proxy')
|
||||||
|
Improvement.objects.create(summary='improve that', version='1.1beta',
|
||||||
|
assignee=contributor, reporter=pcontributor,
|
||||||
|
associated_bug=ProxyProxyBug.objects.all()[0])
|
||||||
|
|
||||||
|
# Related field filter on proxy
|
||||||
|
resp = ProxyBug.objects.get(version__icontains='beta')
|
||||||
|
self.assertEqual(repr(resp), '<ProxyBug: ProxyBug:fix this>')
|
||||||
|
|
||||||
|
# Select related + filter on proxy
|
||||||
|
resp = ProxyBug.objects.select_related().get(version__icontains='beta')
|
||||||
|
self.assertEqual(repr(resp), '<ProxyBug: ProxyBug:fix this>')
|
||||||
|
|
||||||
|
# Proxy of proxy, select_related + filter
|
||||||
|
resp = ProxyProxyBug.objects.select_related().get(
|
||||||
|
version__icontains='beta'
|
||||||
|
)
|
||||||
|
self.assertEqual(repr(resp), '<ProxyProxyBug: ProxyProxyBug:fix this>')
|
||||||
|
|
||||||
|
# Select related + filter on a related proxy field
|
||||||
|
resp = ProxyImprovement.objects.select_related().get(
|
||||||
|
reporter__name__icontains='butor'
|
||||||
|
)
|
||||||
|
self.assertEqual(repr(resp),
|
||||||
|
'<ProxyImprovement: ProxyImprovement:improve that>'
|
||||||
|
)
|
||||||
|
|
||||||
|
# Select related + filter on a related proxy of proxy field
|
||||||
|
resp = ProxyImprovement.objects.select_related().get(
|
||||||
|
associated_bug__summary__icontains='fix'
|
||||||
|
)
|
||||||
|
self.assertEqual(repr(resp),
|
||||||
|
'<ProxyImprovement: ProxyImprovement:improve that>'
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_proxy_load_from_fixture(self):
|
||||||
|
management.call_command('loaddata', 'mypeople.json', verbosity=0, commit=False)
|
||||||
|
p = MyPerson.objects.get(pk=100)
|
||||||
|
self.assertEqual(p.name, 'Elvis Presley')
|
Loading…
Reference in New Issue