#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 [email protected].
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.

Reply via email to