#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.

Reply via email to