Browse Source

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

darius BERNARD 9 years ago
parent
commit
a7ad473ad2

+ 2 - 1
django/db/models/sql/query.py

@@ -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
 

+ 4 - 2
tests/foreign_object/models/__init__.py

@@ -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',
 ]

+ 38 - 0
tests/foreign_object/models/customers.py

@@ -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'],
+    )

+ 28 - 0
tests/foreign_object/test_agnostic_order_trimjoin.py

@@ -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')
+        )