1
0
mirror of https://github.com/django/django.git synced 2024-11-18 07:26:04 +00:00
django/tests/managers_regress/tests.py
Aymeric Augustin 8662654d6d Removed module-level functions for the app cache.
Since the original ones in django.db.models.loading were kept only for
backwards compatibility, there's no need to recreate them. However, many
internals of Django still relied on them.

They were also imported in django.db.models. They never appear in the
documentation, except a quick mention of get_models and get_app in the
1.2 release notes to document an edge case in GIS. I don't think that
makes them a public API.

This commit doesn't change the overall amount of global state but
clarifies that it's tied to the app_cache object instead of hiding it
behind half a dozen functions.
2013-12-17 10:17:44 +01:00

203 lines
7.9 KiB
Python

from __future__ import unicode_literals
import copy
from django.apps import app_cache
from django.db import models
from django.template import Context, Template
from django.test import TestCase
from django.test.utils import override_settings
from django.utils.encoding import force_text
from .models import (
Child1,
Child2,
Child3,
Child4,
Child5,
Child6,
Child7,
AbstractBase1,
AbstractBase2,
AbstractBase3,
RelatedModel,
RelationModel,
)
class ManagersRegressionTests(TestCase):
def test_managers(self):
Child1.objects.create(name='fred', data='a1')
Child1.objects.create(name='barney', data='a2')
Child2.objects.create(name='fred', data='b1', value=1)
Child2.objects.create(name='barney', data='b2', value=42)
Child3.objects.create(name='fred', data='c1', comment='yes')
Child3.objects.create(name='barney', data='c2', comment='no')
Child4.objects.create(name='fred', data='d1')
Child4.objects.create(name='barney', data='d2')
Child5.objects.create(name='fred', comment='yes')
Child5.objects.create(name='barney', comment='no')
Child6.objects.create(name='fred', data='f1', value=42)
Child6.objects.create(name='barney', data='f2', value=42)
Child7.objects.create(name='fred')
Child7.objects.create(name='barney')
self.assertQuerysetEqual(Child1.manager1.all(), ["<Child1: a1>"])
self.assertQuerysetEqual(Child1.manager2.all(), ["<Child1: a2>"])
self.assertQuerysetEqual(Child1._default_manager.all(), ["<Child1: a1>"])
self.assertQuerysetEqual(Child2._default_manager.all(), ["<Child2: b1>"])
self.assertQuerysetEqual(Child2.restricted.all(), ["<Child2: b2>"])
self.assertQuerysetEqual(Child3._default_manager.all(), ["<Child3: c1>"])
self.assertQuerysetEqual(Child3.manager1.all(), ["<Child3: c1>"])
self.assertQuerysetEqual(Child3.manager2.all(), ["<Child3: c2>"])
# Since Child6 inherits from Child4, the corresponding rows from f1 and
# f2 also appear here. This is the expected result.
self.assertQuerysetEqual(Child4._default_manager.order_by('data'), [
"<Child4: d1>",
"<Child4: d2>",
"<Child4: f1>",
"<Child4: f2>"
]
)
self.assertQuerysetEqual(Child4.manager1.all(), [
"<Child4: d1>",
"<Child4: f1>"
],
ordered=False
)
self.assertQuerysetEqual(Child5._default_manager.all(), ["<Child5: fred>"])
self.assertQuerysetEqual(Child6._default_manager.all(), ["<Child6: f1>"])
self.assertQuerysetEqual(Child7._default_manager.order_by('name'), [
"<Child7: barney>",
"<Child7: fred>"
]
)
def test_abstract_manager(self):
# Accessing the manager on an abstract model should
# raise an attribute error with an appropriate message.
try:
AbstractBase3.objects.all()
self.fail('Should raise an AttributeError')
except AttributeError as e:
# This error message isn't ideal, but if the model is abstract and
# a lot of the class instantiation logic isn't invoked; if the
# manager is implied, then we don't get a hook to install the
# error-raising manager.
self.assertEqual(str(e), "type object 'AbstractBase3' has no attribute 'objects'")
def test_custom_abstract_manager(self):
# Accessing the manager on an abstract model with an custom
# manager should raise an attribute error with an appropriate
# message.
try:
AbstractBase2.restricted.all()
self.fail('Should raise an AttributeError')
except AttributeError as e:
self.assertEqual(str(e), "Manager isn't available; AbstractBase2 is abstract")
def test_explicit_abstract_manager(self):
# Accessing the manager on an abstract model with an explicit
# manager should raise an attribute error with an appropriate
# message.
try:
AbstractBase1.objects.all()
self.fail('Should raise an AttributeError')
except AttributeError as e:
self.assertEqual(str(e), "Manager isn't available; AbstractBase1 is abstract")
@override_settings(TEST_SWAPPABLE_MODEL='managers_regress.Parent')
def test_swappable_manager(self):
try:
# This test adds dummy models to the app cache. These
# need to be removed in order to prevent bad interactions
# with the flush operation in other tests.
old_app_models = copy.deepcopy(app_cache.app_models)
class SwappableModel(models.Model):
class Meta:
swappable = 'TEST_SWAPPABLE_MODEL'
# Accessing the manager on a swappable model should
# raise an attribute error with a helpful message
try:
SwappableModel.objects.all()
self.fail('Should raise an AttributeError')
except AttributeError as e:
self.assertEqual(str(e), "Manager isn't available; SwappableModel has been swapped for 'managers_regress.Parent'")
finally:
app_cache.app_models = old_app_models
@override_settings(TEST_SWAPPABLE_MODEL='managers_regress.Parent')
def test_custom_swappable_manager(self):
try:
# This test adds dummy models to the app cache. These
# need to be removed in order to prevent bad interactions
# with the flush operation in other tests.
old_app_models = copy.deepcopy(app_cache.app_models)
class SwappableModel(models.Model):
stuff = models.Manager()
class Meta:
swappable = 'TEST_SWAPPABLE_MODEL'
# Accessing the manager on a swappable model with an
# explicit manager should raise an attribute error with a
# helpful message
try:
SwappableModel.stuff.all()
self.fail('Should raise an AttributeError')
except AttributeError as e:
self.assertEqual(str(e), "Manager isn't available; SwappableModel has been swapped for 'managers_regress.Parent'")
finally:
app_cache.app_models = old_app_models
@override_settings(TEST_SWAPPABLE_MODEL='managers_regress.Parent')
def test_explicit_swappable_manager(self):
try:
# This test adds dummy models to the app cache. These
# need to be removed in order to prevent bad interactions
# with the flush operation in other tests.
old_app_models = copy.deepcopy(app_cache.app_models)
class SwappableModel(models.Model):
objects = models.Manager()
class Meta:
swappable = 'TEST_SWAPPABLE_MODEL'
# Accessing the manager on a swappable model with an
# explicit manager should raise an attribute error with a
# helpful message
try:
SwappableModel.objects.all()
self.fail('Should raise an AttributeError')
except AttributeError as e:
self.assertEqual(str(e), "Manager isn't available; SwappableModel has been swapped for 'managers_regress.Parent'")
finally:
app_cache.app_models = old_app_models
def test_regress_3871(self):
related = RelatedModel.objects.create()
relation = RelationModel()
relation.fk = related
relation.gfk = related
relation.save()
relation.m2m.add(related)
t = Template('{{ related.test_fk.all.0 }}{{ related.test_gfk.all.0 }}{{ related.test_m2m.all.0 }}')
self.assertEqual(
t.render(Context({'related': related})),
''.join([force_text(relation.pk)] * 3),
)