Opened 6 years ago
Last modified 5 years ago
#29545 closed Bug
Nested OuterRef not looking on the right model for the field. — at Version 1
Reported by: | Aaron Lisman | Owned by: | nobody |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | dev |
Severity: | Normal | Keywords: | outerref, subquery |
Cc: | Can Sarıgöl, Oskar Persson | Triage Stage: | Accepted |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description (last modified by )
I ran into this and made a test case for it. It seems similar to the test case above it. I'm not sure what's different about it and causing it to fail.
Let me know if the query is just built wrong.
diff --git a/tests/expressions/models.py b/tests/expressions/models.py index 42e4a37bb0..164bda3b3d 100644 --- a/tests/expressions/models.py +++ b/tests/expressions/models.py @@ -83,6 +83,28 @@ class SimulationRun(models.Model): return "%s (%s to %s)" % (self.midpoint, self.start, self.end) +class Customer(models.Model): + name = models.TextField() + + +class Item(models.Model): + pass + + +class Invoice(models.Model): + INVOICE = 'invoice' + EXPENSE = 'expense' + + KIND_CHOICES = ( + (INVOICE, 'Invoice'), + (EXPENSE, 'Expense'), + ) + + kind = models.CharField(choices=KIND_CHOICES, max_length=255, default=None) + owner = models.ForeignKey(Customer, models.CASCADE) + items = models.ManyToManyField(Item, related_name='invoices') + + class UUIDPK(models.Model): id = models.UUIDField(primary_key=True, default=uuid.uuid4) diff --git a/tests/expressions/tests.py b/tests/expressions/tests.py index d1e622a2d4..2c50744fc8 100644 --- a/tests/expressions/tests.py +++ b/tests/expressions/tests.py @@ -24,7 +24,7 @@ from django.test.utils import Approximate from .models import ( UUID, UUIDPK, Company, Employee, Experiment, Number, Result, SimulationRun, - Time, + Time, Customer, Item, Invoice ) @@ -536,6 +536,55 @@ class BasicExpressionsTests(TestCase): # This is a contrived example. It exercises the double OuterRef form. self.assertCountEqual(outer, [first, second, third]) + def test_nested_subquery_outer_ref_3(self): + customer = Customer.objects.create(name='Test Customer') + other_customer = Customer.objects.create(name='Ohter Customer') + + unexpensed_invoice = Invoice.objects.create(kind=Invoice.INVOICE, owner=customer) + unexpensed_item_1 = Item.objects.create() + unexpensed_invoice.items.add(unexpensed_item_1) + + partially_expensed_invoice = Invoice.objects.create(kind=Invoice.INVOICE, owner=customer) + expense_1 = Invoice.objects.create(kind=Invoice.EXPENSE, owner=customer) + expensed_item_1 = Item.objects.create() + unexpensed_item_2 = Item.objects.create() + partially_expensed_invoice.items.add(expensed_item_1, unexpensed_item_2) + expense_1.items.add(expensed_item_1) + + expensed_invoice = Invoice.objects.create(kind=Invoice.INVOICE, owner=customer) + Invoice.objects.create(kind=Invoice.EXPENSE, owner=customer) + expensed_item_2 = Item.objects.create() + expensed_invoice.items.add(expensed_item_2) + expense_1.items.add(expensed_item_2) + + other_invoice = Invoice.objects.create(kind=Invoice.INVOICE, owner=other_customer) + other_invoice.items.add(unexpensed_item_1) + other_expense = Invoice.objects.create(kind=Invoice.EXPENSE, owner=other_customer) + other_expense.items.add(unexpensed_item_1) + + inner = Invoice.objects.filter( + kind=Invoice.EXPENSE, + owner=OuterRef(OuterRef('owner')), + items=OuterRef('id'), + ) + middle = Item.objects.filter( + invoices=OuterRef('id'), + ).annotate( + expensed=Exists(inner), + ).filter( + expensed=False, + ) + outer = Invoice.objects.filter( + kind=Invoice.INVOICE, + owner=customer, + ).annotate( + unexpensed=Exists(middle), + ) + + self.assertTrue(outer.get(pk=unexpensed_invoice.pk).unexpensed) + self.assertTrue(outer.get(pk=partially_expensed_invoice.pk).unexpensed) + self.assertFalse(outer.get(pk=expensed_invoice.pk).unexpensed) + def test_nested_subquery_outer_ref_with_autofield(self): first = Time.objects.create(time='09:00') second = Time.objects.create(time='17:00')
django.core.exceptions.FieldError: Cannot resolve keyword 'owner' into field. Choices are: expensed, id, invoices
Note:
See TracTickets
for help on using tickets.