mirror of https://github.com/django/django.git
[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.
This commit is contained in:
parent
54887d686b
commit
f4132140f5
|
@ -498,7 +498,8 @@ class ForeignRelatedObjectsDescriptor(object):
|
|||
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
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -3,7 +3,8 @@ from __future__ import absolute_import
|
|||
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 @@ class CustomManagerTests(TestCase):
|
|||
],
|
||||
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())
|
||||
|
|
Loading…
Reference in New Issue