Fixed #26515 -- Fixed Query.trim_joins() for nested ForeignObjects.
This commit is contained in:
parent
2e1d44e46d
commit
a7ad473ad2
|
@ -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
|
||||
|
||||
|
|
|
@ -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',
|
||||
]
|
||||
|
|
|
@ -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'],
|
||||
)
|
|
@ -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')
|
||||
)
|
Loading…
Reference in New Issue