Fixed #26515 -- Fixed Query.trim_joins() for nested ForeignObjects.

This commit is contained in:
darius BERNARD 2016-04-18 14:59:01 +02:00 committed by Tim Graham
parent 2e1d44e46d
commit a7ad473ad2
4 changed files with 72 additions and 3 deletions

View File

@ -1438,7 +1438,8 @@ class Query(object):
cur_targets = set(t.column for t in targets)
if not cur_targets.issubset(join_targets):
break
targets = tuple(r[0] for r in info.join_field.related_fields if r[1].column in cur_targets)
targets_dict = {r[1].column: r[0] for r in info.join_field.related_fields if r[1].column in cur_targets}
targets = tuple(targets_dict[t.column] for t in targets)
self.unref_alias(joins.pop())
return targets, joins[-1], joins

View File

@ -1,10 +1,12 @@
from .article import (
Article, ArticleIdea, ArticleTag, ArticleTranslation, NewsArticle,
)
from .customers import Address, Contact, Customer
from .empty_join import SlugPage
from .person import Country, Friendship, Group, Membership, Person
__all__ = [
'Article', 'ArticleIdea', 'ArticleTag', 'ArticleTranslation', 'Country',
'Friendship', 'Group', 'Membership', 'NewsArticle', 'Person', 'SlugPage',
'Address', 'Article', 'ArticleIdea', 'ArticleTag', 'ArticleTranslation',
'Contact', 'Country', 'Customer', 'Friendship', 'Group', 'Membership',
'NewsArticle', 'Person', 'SlugPage',
]

View File

@ -0,0 +1,38 @@
from django.db import models
from django.db.models.fields.related import ForeignObject
class Address(models.Model):
company = models.CharField(max_length=1)
customer_id = models.IntegerField()
class Meta:
unique_together = [
('company', 'customer_id'),
]
class Customer(models.Model):
company = models.CharField(max_length=1)
customer_id = models.IntegerField()
address = ForeignObject(
Address, models.CASCADE, null=True,
# order mismatches the Contact ForeignObject.
from_fields=['company', 'customer_id'],
to_fields=['company', 'customer_id'],
)
class Meta:
unique_together = [
('company', 'customer_id'),
]
class Contact(models.Model):
company_code = models.CharField(max_length=1)
customer_code = models.IntegerField()
customer = ForeignObject(
Customer, models.CASCADE, related_name='contacts',
to_fields=['customer_id', 'company'],
from_fields=['customer_code', 'company_code'],
)

View File

@ -0,0 +1,28 @@
from operator import attrgetter
from django.test.testcases import TestCase
from .models import Address, Contact, Customer
class TestLookupQuery(TestCase):
@classmethod
def setUpTestData(cls):
cls.address = Address.objects.create(company=1, customer_id=20)
cls.customer1 = Customer.objects.create(company=1, customer_id=20)
cls.contact1 = Contact.objects.create(company_code=1, customer_code=20)
def test_deep_mixed_forward(self):
self.assertQuerysetEqual(
Address.objects.filter(customer__contacts=self.contact1),
[self.address.id],
attrgetter('id')
)
def test_deep_mixed_backward(self):
self.assertQuerysetEqual(
Contact.objects.filter(customer__address=self.address),
[self.contact1.id],
attrgetter('id')
)