1
0
mirror of https://github.com/django/django.git synced 2025-10-24 06:06:09 +00:00

Refs #373 -- Added support for using tuple lookups in filters.

This commit is contained in:
Bendeguz Csirmaz
2024-09-20 02:46:16 +08:00
committed by Sarah Boyce
parent f22ff4561a
commit 5ed72087c4
2 changed files with 180 additions and 53 deletions

View File

@@ -1,6 +1,16 @@
import unittest
from django.db import NotSupportedError, connection
from django.db.models import F
from django.db.models.fields.tuple_lookups import (
TupleExact,
TupleGreaterThan,
TupleGreaterThanOrEqual,
TupleIn,
TupleIsNull,
TupleLessThan,
TupleLessThanOrEqual,
)
from django.test import TestCase
from .models import Contact, Customer
@@ -32,10 +42,25 @@ class TupleLookupsTests(TestCase):
)
for customer, contacts in test_cases:
with self.subTest(customer=customer, contacts=contacts):
with self.subTest(
"filter(customer=customer)",
customer=customer,
contacts=contacts,
):
self.assertSequenceEqual(
Contact.objects.filter(customer=customer).order_by("id"), contacts
)
with self.subTest(
"filter(TupleExact)",
customer=customer,
contacts=contacts,
):
lhs = (F("customer_code"), F("company_code"))
rhs = (customer.customer_id, customer.company)
lookup = TupleExact(lhs, rhs)
self.assertSequenceEqual(
Contact.objects.filter(lookup).order_by("id"), contacts
)
def test_exact_subquery(self):
with self.assertRaisesMessage(
@@ -71,11 +96,26 @@ class TupleLookupsTests(TestCase):
((cust_1, cust_2, cust_3, cust_4, cust_5), (c1, c2, c3, c4, c5, c6)),
)
for contacts, customers in test_cases:
with self.subTest(contacts=contacts, customers=customers):
for customers, contacts in test_cases:
with self.subTest(
"filter(customer__in=customers)",
customers=customers,
contacts=contacts,
):
self.assertSequenceEqual(
Contact.objects.filter(customer__in=contacts).order_by("id"),
customers,
Contact.objects.filter(customer__in=customers).order_by("id"),
contacts,
)
with self.subTest(
"filter(TupleIn)",
customers=customers,
contacts=contacts,
):
lhs = (F("customer_code"), F("company_code"))
rhs = [(c.customer_id, c.company) for c in customers]
lookup = TupleIn(lhs, rhs)
self.assertSequenceEqual(
Contact.objects.filter(lookup).order_by("id"), contacts
)
@unittest.skipIf(
@@ -107,11 +147,26 @@ class TupleLookupsTests(TestCase):
)
for customer, contacts in test_cases:
with self.subTest(customer=customer, contacts=contacts):
with self.subTest(
"filter(customer__lt=customer)",
customer=customer,
contacts=contacts,
):
self.assertSequenceEqual(
Contact.objects.filter(customer__lt=customer).order_by("id"),
contacts,
)
with self.subTest(
"filter(TupleLessThan)",
customer=customer,
contacts=contacts,
):
lhs = (F("customer_code"), F("company_code"))
rhs = (customer.customer_id, customer.company)
lookup = TupleLessThan(lhs, rhs)
self.assertSequenceEqual(
Contact.objects.filter(lookup).order_by("id"), contacts
)
def test_lt_subquery(self):
with self.assertRaisesMessage(
@@ -140,11 +195,26 @@ class TupleLookupsTests(TestCase):
)
for customer, contacts in test_cases:
with self.subTest(customer=customer, contacts=contacts):
with self.subTest(
"filter(customer__lte=customer)",
customer=customer,
contacts=contacts,
):
self.assertSequenceEqual(
Contact.objects.filter(customer__lte=customer).order_by("id"),
contacts,
)
with self.subTest(
"filter(TupleLessThanOrEqual)",
customer=customer,
contacts=contacts,
):
lhs = (F("customer_code"), F("company_code"))
rhs = (customer.customer_id, customer.company)
lookup = TupleLessThanOrEqual(lhs, rhs)
self.assertSequenceEqual(
Contact.objects.filter(lookup).order_by("id"), contacts
)
def test_lte_subquery(self):
with self.assertRaisesMessage(
@@ -165,11 +235,26 @@ class TupleLookupsTests(TestCase):
)
for customer, contacts in test_cases:
with self.subTest(customer=customer, contacts=contacts):
with self.subTest(
"filter(customer__gt=customer)",
customer=customer,
contacts=contacts,
):
self.assertSequenceEqual(
Contact.objects.filter(customer__gt=customer).order_by("id"),
contacts,
)
with self.subTest(
"filter(TupleGreaterThan)",
customer=customer,
contacts=contacts,
):
lhs = (F("customer_code"), F("company_code"))
rhs = (customer.customer_id, customer.company)
lookup = TupleGreaterThan(lhs, rhs)
self.assertSequenceEqual(
Contact.objects.filter(lookup).order_by("id"), contacts
)
def test_gt_subquery(self):
with self.assertRaisesMessage(
@@ -198,11 +283,26 @@ class TupleLookupsTests(TestCase):
)
for customer, contacts in test_cases:
with self.subTest(customer=customer, contacts=contacts):
with self.subTest(
"filter(customer__gte=customer)",
customer=customer,
contacts=contacts,
):
self.assertSequenceEqual(
Contact.objects.filter(customer__gte=customer).order_by("pk"),
contacts,
)
with self.subTest(
"filter(TupleGreaterThanOrEqual)",
customer=customer,
contacts=contacts,
):
lhs = (F("customer_code"), F("company_code"))
rhs = (customer.customer_id, customer.company)
lookup = TupleGreaterThanOrEqual(lhs, rhs)
self.assertSequenceEqual(
Contact.objects.filter(lookup).order_by("id"), contacts
)
def test_gte_subquery(self):
with self.assertRaisesMessage(
@@ -214,22 +314,38 @@ class TupleLookupsTests(TestCase):
)
def test_isnull(self):
with self.subTest("customer__isnull=True"):
contacts = (
self.contact_1,
self.contact_2,
self.contact_3,
self.contact_4,
self.contact_5,
self.contact_6,
)
with self.subTest("filter(customer__isnull=True)"):
self.assertSequenceEqual(
Contact.objects.filter(customer__isnull=True).order_by("id"),
(),
)
with self.subTest("customer__isnull=False"):
with self.subTest("filter(TupleIsNull(True))"):
lhs = (F("customer_code"), F("company_code"))
lookup = TupleIsNull(lhs, True)
self.assertSequenceEqual(
Contact.objects.filter(lookup).order_by("id"),
(),
)
with self.subTest("filter(customer__isnull=False)"):
self.assertSequenceEqual(
Contact.objects.filter(customer__isnull=False).order_by("id"),
(
self.contact_1,
self.contact_2,
self.contact_3,
self.contact_4,
self.contact_5,
self.contact_6,
),
contacts,
)
with self.subTest("filter(TupleIsNull(False))"):
lhs = (F("customer_code"), F("company_code"))
lookup = TupleIsNull(lhs, False)
self.assertSequenceEqual(
Contact.objects.filter(lookup).order_by("id"),
contacts,
)
def test_isnull_subquery(self):