#36611: Model validation of constraint involving ForeignObject considers only first column -------------------------------------+------------------------------------- Reporter: Jacob Walls | Owner: (none) Type: Bug | Status: new Component: Database layer | Version: 5.2 (models, ORM) | Severity: Release blocker | Resolution: Keywords: | Triage Stage: Accepted Has patch: 0 | Needs documentation: 0 Needs tests: 0 | Patch needs improvement: 0 Easy pickings: 0 | UI/UX: 0 -------------------------------------+------------------------------------- Comment (by Simon Charette):
I suspect this will be very hard to to solve without solving #35956 of the one ticket I can't find to add generic composite field support as it's preventing us from performing lookups of the form {{{#!python ContactCheck.objects.filter(customer__lt=(1000, "c")) }}} in the first place. Here's an attempt at using `Tuple` which results in the same problem as `Tuple.output_field` is currently ''faked'' as `models.Field` due to the lack of `CompositeField` existence {{{#!diff diff --git a/django/db/models/base.py b/django/db/models/base.py index 36b16c1132..d7af0ebd1a 100644 --- a/django/db/models/base.py +++ b/django/db/models/base.py @@ -39,6 +39,7 @@ lazy_related_operation, resolve_relation, ) +from django.db.models.fields.tuple_lookups import Tuple from django.db.models.functions import Coalesce from django.db.models.manager import Manager from django.db.models.options import Options @@ -1380,11 +1381,27 @@ def _get_field_expression_map(self, meta, exclude=None): isinstance(field.remote_field, ForeignObjectRel) and field not in meta.local_concrete_fields ): - value = tuple( - getattr(self, from_field) for from_field in field.from_fields - ) - if len(value) == 1: - value = value[0] + composed_fields = field.local_related_fields + if len(composed_fields) == 1: + value = getattr(self, composed_fields[0].attname) + else: + composed_values = ( + getattr(self, composed_field.attname) + for composed_field in composed_fields + ) + value = Tuple( + *( + ( + composed_value + if hasattr(composed_value, "resolve_expression") + else Value(composed_value, composed_field) + ) + for composed_value, composed_field in zip( + composed_values, composed_fields + ) + ), + output_field=field, + ) elif field.concrete: value = getattr(self, field.attname) else: }}} -- Ticket URL: <https://code.djangoproject.com/ticket/36611#comment:6> Django <https://code.djangoproject.com/> The Web framework for perfectionists with deadlines. -- You received this message because you are subscribed to the Google Groups "Django updates" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-updates+unsubscr...@googlegroups.com. To view this discussion visit https://groups.google.com/d/msgid/django-updates/010701995dfefb9c-f349f353-8016-4736-9462-0c44f882a7e9-000000%40eu-central-1.amazonses.com.