Fixed #18432 -- Prevented the ForeignKey field from creating an invalid query when chained. Thanks, Jann Kleen.

This commit is contained in:
Jann Kleen 2012-06-07 18:39:27 +02:00 committed by Jannis Leidel
parent 5e6ded2e58
commit 1a412dda62
3 changed files with 38 additions and 5 deletions

View File

@ -359,7 +359,7 @@ class ReverseSingleRelatedObjectDescriptor(object):
else: else:
other_field = self.field.rel.get_related_field() other_field = self.field.rel.get_related_field()
if other_field.rel: if other_field.rel:
params = {'%s__pk' % self.field.rel.field_name: val} params = {'%s__%s' % (self.field.rel.field_name, other_field.rel.field_name): val}
else: else:
params = {'%s__exact' % self.field.rel.field_name: val} params = {'%s__exact' % self.field.rel.field_name: val}
qs = self.get_query_set(instance=instance) qs = self.get_query_set(instance=instance)

View File

@ -7,6 +7,7 @@ CHOICES = (
(2, 'second'), (2, 'second'),
) )
class Article(models.Model): class Article(models.Model):
headline = models.CharField(max_length=100, default='Default headline') headline = models.CharField(max_length=100, default='Default headline')
pub_date = models.DateTimeField() pub_date = models.DateTimeField()
@ -22,17 +23,21 @@ class Article(models.Model):
def __unicode__(self): def __unicode__(self):
return self.headline return self.headline
class Movie(models.Model): class Movie(models.Model):
#5218: Test models with non-default primary keys / AutoFields #5218: Test models with non-default primary keys / AutoFields
movie_id = models.AutoField(primary_key=True) movie_id = models.AutoField(primary_key=True)
name = models.CharField(max_length=60) name = models.CharField(max_length=60)
class Party(models.Model): class Party(models.Model):
when = models.DateField(null=True) when = models.DateField(null=True)
class Event(models.Model): class Event(models.Model):
when = models.DateTimeField() when = models.DateTimeField()
class Department(models.Model): class Department(models.Model):
id = models.PositiveIntegerField(primary_key=True) id = models.PositiveIntegerField(primary_key=True)
name = models.CharField(max_length=200) name = models.CharField(max_length=200)
@ -40,6 +45,7 @@ class Department(models.Model):
def __unicode__(self): def __unicode__(self):
return self.name return self.name
class Worker(models.Model): class Worker(models.Model):
department = models.ForeignKey(Department) department = models.ForeignKey(Department)
name = models.CharField(max_length=200) name = models.CharField(max_length=200)
@ -47,6 +53,7 @@ class Worker(models.Model):
def __unicode__(self): def __unicode__(self):
return self.name return self.name
class BrokenUnicodeMethod(models.Model): class BrokenUnicodeMethod(models.Model):
name = models.CharField(max_length=7) name = models.CharField(max_length=7)
@ -55,5 +62,19 @@ class BrokenUnicodeMethod(models.Model):
# object). # object).
return 'Názov: %s' % self.name return 'Názov: %s' % self.name
class NonAutoPK(models.Model): class NonAutoPK(models.Model):
name = models.CharField(max_length=10, primary_key=True) name = models.CharField(max_length=10, primary_key=True)
#18432: Chained foreign keys with to_field produce incorrect query
class Model1(models.Model):
pkey = models.IntegerField(unique=True, db_index=True)
class Model2(models.Model):
model1 = models.ForeignKey(Model1, unique=True, to_field='pkey')
class Model3(models.Model):
model2 = models.ForeignKey(Model2, unique=True, to_field='model1')

View File

@ -8,8 +8,7 @@ from django.test import TestCase, skipUnlessDBFeature
from django.utils import tzinfo from django.utils import tzinfo
from .models import (Worker, Article, Party, Event, Department, from .models import (Worker, Article, Party, Event, Department,
BrokenUnicodeMethod, NonAutoPK) BrokenUnicodeMethod, NonAutoPK, Model1, Model2, Model3)
class ModelTests(TestCase): class ModelTests(TestCase):
@ -164,6 +163,19 @@ class ModelTests(TestCase):
1 1
) )
def test_chained_fks(self):
"""
Regression for #18432: Chained foreign keys with to_field produce incorrect query
"""
m1 = Model1.objects.create(pkey=1000)
m2 = Model2.objects.create(model1=m1)
m3 = Model3.objects.create(model2=m2)
# this is the actual test for #18432
m3 = Model3.objects.get(model2=1000)
m3.model2
class ModelValidationTest(TestCase): class ModelValidationTest(TestCase):
def test_pk_validation(self): def test_pk_validation(self):