summaryrefslogtreecommitdiff
path: root/tests/custom_managers
diff options
context:
space:
mode:
authorshanghui <shangdahao@gmail.com>2018-01-14 10:58:21 +0800
committerTim Graham <timograham@gmail.com>2018-01-25 10:12:04 -0500
commit8dc675d90f14a84ef95f16c7cc8100d9a04459b3 (patch)
tree04d16b6366f756dd76f563070b06a094bb50d735 /tests/custom_managers
parentcbac11f9624d529809e9bdaa7f4d3ab2c5e93009 (diff)
downloaddjango-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.py14
-rw-r--r--tests/custom_managers/tests.py16
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