Commit a7ad473a authored by darius BERNARD's avatar darius BERNARD Committed by Tim Graham
Browse files

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

parent 2e1d44e4
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -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
Original line number Diff line number Diff line
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
Original line number Diff line number Diff line
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
Original line number Diff line number Diff line
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')
        )