Fixed #17541 -- Fixed non-saved/nullable fk querying

This commit is contained in:
Anssi Kääriäinen 2013-01-06 18:40:56 +02:00
parent 34ee7d9875
commit 55da775ce1
3 changed files with 32 additions and 1 deletions

View File

@ -496,6 +496,8 @@ class ForeignRelatedObjectsDescriptor(object):
except (AttributeError, KeyError): except (AttributeError, KeyError):
db = self._db or router.db_for_read(self.model, instance=self.instance) 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) qs = super(RelatedManager, self).get_query_set().using(db).filter(**self.core_filters)
if getattr(self.instance, attname) is None:
return qs.none()
qs._known_related_objects = {rel_field: {self.instance.pk: self.instance}} qs._known_related_objects = {rel_field: {self.instance.pk: self.instance}}
return qs return qs

View File

@ -48,3 +48,9 @@ class Relation(models.Model):
def __str__(self): def __str__(self):
return "%s - %s" % (self.left.category.name, self.right.category.name) return "%s - %s" % (self.left.category.name, self.right.category.name)
class Car(models.Model):
make = models.CharField(max_length=100, null=True, unique=True)
class Driver(models.Model):
car = models.ForeignKey(Car, to_field='make', null=True, related_name='drivers')

View File

@ -4,7 +4,8 @@ from django.db import models
from django.test import TestCase from django.test import TestCase
from django.utils import six from django.utils import six
from .models import First, Third, Parent, Child, Category, Record, Relation from .models import (
First, Third, Parent, Child, Category, Record, Relation, Car, Driver)
class ManyToOneRegressionTests(TestCase): class ManyToOneRegressionTests(TestCase):
@ -111,3 +112,25 @@ class ManyToOneRegressionTests(TestCase):
# of a model, and interrogate its related field. # of a model, and interrogate its related field.
cat = models.ForeignKey(Category) cat = models.ForeignKey(Category)
self.assertEqual('id', cat.rel.get_related_field().name) self.assertEqual('id', cat.rel.get_related_field().name)
def test_relation_unsaved(self):
# Test that the <field>_set manager does not join on Null value fields (#17541)
Third.objects.create(name='Third 1')
Third.objects.create(name='Third 2')
th = Third(name="testing")
# The object isn't saved an thus the relation field is null - we won't even
# execute a query in this case.
with self.assertNumQueries(0):
self.assertEqual(th.child_set.count(), 0)
th.save()
# Now the model is saved, so we will need to execute an query.
with self.assertNumQueries(1):
self.assertEqual(th.child_set.count(), 0)
def test_related_null_to_field(self):
c1 = Car.objects.create()
c2 = Car.objects.create()
d1 = Driver.objects.create()
self.assertIs(d1.car, None)
with self.assertNumQueries(0):
self.assertEqual(list(c1.drivers.all()), [])