diff options
author | shanghui <shangdahao@gmail.com> | 2018-01-14 10:58:21 +0800 |
---|---|---|
committer | Tim Graham <timograham@gmail.com> | 2018-01-25 10:12:04 -0500 |
commit | 8dc675d90f14a84ef95f16c7cc8100d9a04459b3 (patch) | |
tree | 04d16b6366f756dd76f563070b06a094bb50d735 /tests/custom_managers | |
parent | cbac11f9624d529809e9bdaa7f4d3ab2c5e93009 (diff) | |
download | django-8dc675d90f14a84ef95f16c7cc8100d9a04459b3.tar.gz |
Fixed #28838 -- Fixed Model.save() crash if the base manager annotates with a related field.
Diffstat (limited to 'tests/custom_managers')
-rw-r--r-- | tests/custom_managers/models.py | 14 | ||||
-rw-r--r-- | tests/custom_managers/tests.py | 16 |
2 files changed, 29 insertions, 1 deletions
diff --git a/tests/custom_managers/models.py b/tests/custom_managers/models.py index f90425db3c..ca2e14b047 100644 --- a/tests/custom_managers/models.py +++ b/tests/custom_managers/models.py @@ -25,6 +25,13 @@ class PublishedBookManager(models.Manager): return super().get_queryset().filter(is_published=True) +class AnnotatedBookManager(models.Manager): + def get_queryset(self): + return super().get_queryset().annotate( + favorite_avg=models.Avg('favorite_books__favorite_thing_id') + ) + + class CustomQuerySet(models.QuerySet): def filter(self, *args, **kwargs): queryset = super().filter(fun=True) @@ -131,7 +138,6 @@ class Book(models.Model): title = models.CharField(max_length=50) author = models.CharField(max_length=30) is_published = models.BooleanField(default=False) - published_objects = PublishedBookManager() authors = models.ManyToManyField(Person, related_name='books') fun_authors = models.ManyToManyField(FunPerson, related_name='books') favorite_things = GenericRelation( @@ -145,6 +151,12 @@ class Book(models.Model): object_id_field='favorite_thing_id', ) + published_objects = PublishedBookManager() + annotated_objects = AnnotatedBookManager() + + class Meta: + base_manager_name = 'annotated_objects' + def __str__(self): return self.title diff --git a/tests/custom_managers/tests.py b/tests/custom_managers/tests.py index a545382d8f..8e5ab1418f 100644 --- a/tests/custom_managers/tests.py +++ b/tests/custom_managers/tests.py @@ -617,6 +617,22 @@ class CustomManagersRegressTestCase(TestCase): book.refresh_from_db() self.assertEqual(book.title, 'Hi') + def test_save_clears_annotations_from_base_manager(self): + """Model.save() clears annotations from the base manager.""" + self.assertEqual(Book._meta.base_manager.name, 'annotated_objects') + book = Book.annotated_objects.create(title='Hunting') + Person.objects.create( + first_name='Bugs', last_name='Bunny', fun=True, + favorite_book=book, favorite_thing_id=1, + ) + book = Book.annotated_objects.first() + self.assertEqual(book.favorite_avg, 1) # Annotation from the manager. + book.title = 'New Hunting' + # save() fails if annotations that involve related fields aren't + # cleared before the update query. + book.save() + self.assertEqual(Book.annotated_objects.first().title, 'New Hunting') + 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 |