Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

[1.5.x] Fixed #19652 -- Fixed .none() regression in related fields

The regression was caused by using .none() when querying for related
models, and the origin field's value was None. This resulted in missing
custom related manager subclass as .none() returns plain QuerySet.

This isn't backport from master, in master .none() correctly preserves
the queryset's class.

Patch provided by Simon Charette, with some minor polish by committer.
  • Loading branch information...
commit f4132140f52c88b67d11743d4062a9d455959ffc 1 parent 54887d6
Anssi Kääriäinen akaariai authored
3  django/db/models/fields/related.py
View
@@ -498,7 +498,8 @@ def get_query_set(self):
db = self._db or router.db_for_read(self.model, instance=self.instance)
qs = super(RelatedManager, self).get_query_set().using(db).filter(**self.core_filters)
if getattr(self.instance, attname) is None:
- return qs.none()
+ # We don't want to use qs.none() here, see #19652
+ return qs.filter(pk__in=[])
qs._known_related_objects = {rel_field: {self.instance.pk: self.instance}}
return qs
21 tests/modeltests/custom_managers/models.py
View
@@ -63,3 +63,24 @@ class Car(models.Model):
def __str__(self):
return self.name
+
+
+# Bug #19652
+class ObjectQuerySet(models.query.QuerySet):
+ pass
+
+class ObjectManager(models.Manager):
+ use_for_related_fields = True
+
+ def get_query_set(self):
+ return ObjectQuerySet(self.model, using=self._db)
+
+
+class RelatedObject(models.Model):
+ pass
+
+
+class Object(models.Model):
+ related = models.ForeignKey(RelatedObject, related_name='objs')
+
+ objects = ObjectManager()
13 tests/modeltests/custom_managers/tests.py
View
@@ -3,7 +3,8 @@
from django.test import TestCase
from django.utils import six
-from .models import Person, Book, Car, PersonManager, PublishedBookManager
+from .models import (ObjectQuerySet, RelatedObject, Person, Book, Car, PersonManager,
+ PublishedBookManager)
class CustomManagerTests(TestCase):
@@ -72,3 +73,13 @@ def test_manager(self):
],
lambda c: c.name
)
+
+ def test_related_manager(self):
+ """
+ Make sure un-saved object's related managers always return an instance
+ of the same class the manager's `get_query_set` returns. Refs #19652.
+ """
+ rel_qs = RelatedObject().objs.all()
+ self.assertIsInstance(rel_qs, ObjectQuerySet)
+ with self.assertNumQueries(0):
+ self.assertFalse(rel_qs.exists())
Please sign in to comment.
Something went wrong with that request. Please try again.