1
0
mirror of https://github.com/django/django.git synced 2025-04-05 22:16:41 +00:00

Fixed #36042 -- Raised ValueError when using CompositePrimaryKey as rhs.

This commit is contained in:
Jacob Walls 2024-12-31 13:10:35 -05:00 committed by Sarah Boyce
parent 8914b571eb
commit 6eec703667
3 changed files with 28 additions and 1 deletions

View File

@ -758,6 +758,8 @@ class CombinedExpression(SQLiteNumericMixin, Expression):
rhs = self.rhs.resolve_expression(
query, allow_joins, reuse, summarize, for_save
)
if isinstance(lhs, ColPairs) or isinstance(rhs, ColPairs):
raise ValueError("CompositePrimaryKey is not combinable.")
if not isinstance(self, (DurationExpression, TemporalSubtraction)):
try:
lhs_type = lhs.output_field.get_internal_type()

View File

@ -4,7 +4,7 @@ import warnings
from django.core.exceptions import EmptyResultSet, FullResultSet
from django.db.backends.base.operations import BaseDatabaseOperations
from django.db.models.expressions import Case, Expression, Func, Value, When
from django.db.models.expressions import Case, ColPairs, Expression, Func, Value, When
from django.db.models.fields import (
BooleanField,
CharField,
@ -119,6 +119,10 @@ class Lookup(Expression):
value = value.resolve_expression(compiler.query)
if hasattr(value, "as_sql"):
sql, params = compiler.compile(value)
if isinstance(value, ColPairs):
raise ValueError(
"CompositePrimaryKey cannot be used as a lookup value."
)
# Ensure expression is wrapped in parentheses to respect operator
# precedence but avoid double wrapping as it can be misinterpreted
# on some backends (e.g. subqueries on SQLite).

View File

@ -1,3 +1,5 @@
from django.db.models import F, TextField
from django.db.models.functions import Cast
from django.test import TestCase
from .models import Comment, Tenant, User
@ -54,6 +56,20 @@ class CompositePKFilterTests(TestCase):
with self.subTest(lookup=lookup, count=count):
self.assertEqual(User.objects.filter(**lookup).count(), count)
def test_rhs_pk(self):
msg = "CompositePrimaryKey cannot be used as a lookup value."
with self.assertRaisesMessage(ValueError, msg):
Comment.objects.filter(text__gt=F("pk")).count()
def test_rhs_combinable(self):
msg = "CompositePrimaryKey is not combinable."
for expr in [F("pk") + (1, 1), (1, 1) + F("pk")]:
with (
self.subTest(expression=expr),
self.assertRaisesMessage(ValueError, msg),
):
Comment.objects.filter(text__gt=expr).count()
def test_order_comments_by_pk_asc(self):
self.assertSequenceEqual(
Comment.objects.order_by("pk"),
@ -410,3 +426,8 @@ class CompositePKFilterTests(TestCase):
subquery = Comment.objects.filter(id=3).only("pk")
queryset = User.objects.filter(comments__in=subquery)
self.assertSequenceEqual(queryset, (self.user_2,))
def test_cannot_cast_pk(self):
msg = "Casting CompositePrimaryKey is not supported."
with self.assertRaisesMessage(ValueError, msg):
Comment.objects.filter(text__gt=Cast(F("pk"), TextField())).count()