diff options
author | Loic Bistuer <loic.bistuer@gmail.com> | 2014-09-23 01:23:34 +0700 |
---|---|---|
committer | Loic Bistuer <loic.bistuer@gmail.com> | 2014-09-23 03:56:19 +0700 |
commit | 0dab07e5da43f8965db24adc4363cec01944de4d (patch) | |
tree | 7209288a2cfcc23f66bce3d60836aa3b496963f7 /tests/custom_managers | |
parent | d42a45de407c7d7962aa7a2dd79f7d32b423e600 (diff) | |
download | django-0dab07e5da43f8965db24adc4363cec01944de4d.tar.gz |
Merged custom_managers_regress into the custom_managers test package.
Diffstat (limited to 'tests/custom_managers')
-rw-r--r-- | tests/custom_managers/models.py | 51 | ||||
-rw-r--r-- | tests/custom_managers/tests.py | 47 |
2 files changed, 86 insertions, 12 deletions
diff --git a/tests/custom_managers/models.py b/tests/custom_managers/models.py index bbf037b362..feda9ef630 100644 --- a/tests/custom_managers/models.py +++ b/tests/custom_managers/models.py @@ -11,28 +11,20 @@ returns. from __future__ import unicode_literals -from django.contrib.contenttypes.fields import ( - GenericForeignKey, GenericRelation -) +from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation from django.db import models from django.utils.encoding import python_2_unicode_compatible -# An example of a custom manager called "objects". - class PersonManager(models.Manager): def get_fun_people(self): return self.filter(fun=True) -# An example of a custom manager that sets get_queryset(). - class PublishedBookManager(models.Manager): def get_queryset(self): return super(PublishedBookManager, self).get_queryset().filter(is_published=True) -# An example of a custom queryset that copies its methods onto the manager. - class CustomQuerySet(models.QuerySet): def filter(self, *args, **kwargs): @@ -138,8 +130,6 @@ class Book(models.Model): def __str__(self): return self.title -# An example of providing multiple custom managers. - class FastCarManager(models.Manager): def get_queryset(self): @@ -156,3 +146,42 @@ class Car(models.Model): def __str__(self): return self.name + + +class RestrictedManager(models.Manager): + def get_queryset(self): + return super(RestrictedManager, self).get_queryset().filter(is_public=True) + + +@python_2_unicode_compatible +class RelatedModel(models.Model): + name = models.CharField(max_length=50) + + def __str__(self): + return self.name + + +@python_2_unicode_compatible +class RestrictedModel(models.Model): + name = models.CharField(max_length=50) + is_public = models.BooleanField(default=False) + related = models.ForeignKey(RelatedModel) + + objects = RestrictedManager() + plain_manager = models.Manager() + + def __str__(self): + return self.name + + +@python_2_unicode_compatible +class OneToOneRestrictedModel(models.Model): + name = models.CharField(max_length=50) + is_public = models.BooleanField(default=False) + related = models.OneToOneField(RelatedModel) + + objects = RestrictedManager() + plain_manager = models.Manager() + + def __str__(self): + return self.name diff --git a/tests/custom_managers/tests.py b/tests/custom_managers/tests.py index 437d75deea..383ccc0e44 100644 --- a/tests/custom_managers/tests.py +++ b/tests/custom_managers/tests.py @@ -3,7 +3,8 @@ from __future__ import unicode_literals from django.test import TestCase from django.utils import six -from .models import Person, FunPerson, Book, Car, PersonManager, PublishedBookManager +from .models import (Book, Car, FunPerson, OneToOneRestrictedModel, Person, + PersonManager, PublishedBookManager, RelatedModel, RestrictedModel) class CustomManagerTests(TestCase): @@ -463,3 +464,47 @@ class CustomManagerTests(TestCase): lambda c: c.first_name, ordered=False, ) + + +class CustomManagersRegressTestCase(TestCase): + def test_filtered_default_manager(self): + """Even though the default manager filters out some records, + we must still be able to save (particularly, save by updating + existing records) those filtered instances. This is a + regression test for #8990, #9527""" + related = RelatedModel.objects.create(name="xyzzy") + obj = RestrictedModel.objects.create(name="hidden", related=related) + obj.name = "still hidden" + obj.save() + + # If the hidden object wasn't seen during the save process, + # there would now be two objects in the database. + self.assertEqual(RestrictedModel.plain_manager.count(), 1) + + def test_delete_related_on_filtered_manager(self): + """Deleting related objects should also not be distracted by a + restricted manager on the related object. This is a regression + test for #2698.""" + related = RelatedModel.objects.create(name="xyzzy") + + for name, public in (('one', True), ('two', False), ('three', False)): + RestrictedModel.objects.create(name=name, is_public=public, related=related) + + obj = RelatedModel.objects.get(name="xyzzy") + obj.delete() + + # All of the RestrictedModel instances should have been + # deleted, since they *all* pointed to the RelatedModel. If + # the default manager is used, only the public one will be + # deleted. + self.assertEqual(len(RestrictedModel.plain_manager.all()), 0) + + def test_delete_one_to_one_manager(self): + # The same test case as the last one, but for one-to-one + # models, which are implemented slightly different internally, + # so it's a different code path. + obj = RelatedModel.objects.create(name="xyzzy") + OneToOneRestrictedModel.objects.create(name="foo", is_public=False, related=obj) + obj = RelatedModel.objects.get(name="xyzzy") + obj.delete() + self.assertEqual(len(OneToOneRestrictedModel.plain_manager.all()), 0) |