#34871: Validation of UniqueConstraint with Case() crashes.
-------------------------------------+-------------------------------------
Reporter: Andrew Roberts | Owner: Francesco
| Panico
Type: Bug | Status: assigned
Component: Database layer | Version: 4.2
(models, ORM) |
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Simon Charette):
* cc: Simon Charette (added)
Comment:
Playing a bit with trying to implement `Q.replace_expressions` I have to
retract myself; it's not trivial.
The only solution I can think of is have the validate logic pass a special
type of dict as `replacement` to `replace_expression` that would default
missing key lookups for tuples of the form `('active', True)` to
`query.resolve_lookup_value` so it gets turned into `Exact(F("active"),
True).replace_expression(replacements)`.
It's doable but certainly not trivial
[https://github.com/charettes/django/pull/new/ticket-34871 as this branch
demonstrate].
I think this has some ties into #24267 where the idea would be that we'd
introduce an `UnresolvedLookup(BaseExpression)` class initialized from
`__init__(self, field, **lookup)` and that would store `F(field)` in its
source expressions and thus allow `replace_expressions` to take place
normally as `Q` would be storing `UnresolvedLookup(key_parts[0],
key_parts[1:])` instead of tuple of the form `tuple[str, Any]` as
children. All `UnresolvedLookup` would do in its `resolve_expressions` is
what can be found in the trailing part of `Query.build_filter` today that
calls `solve_lookup_type`, `resolve_lookup_value`, and `build_lookup` but
it would behave like a normal expression and avoids all the hacks we have
in place today that special case `Q` objects.
Until work towards ^^ can be made the best solution here is to use lookups
directly
{{{#!python
from django.db.models.lookups import Exact
models.UniqueConstraint(
Case(When(Exact(F("active", True), then=F("email"))),
name="unique_active_email",
)
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/34871#comment:10>
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 on the web visit
https://groups.google.com/d/msgid/django-updates/0107018dcfaca76b-1d8ea7e6-649a-42df-b774-bb4fc45cbb29-000000%40eu-central-1.amazonses.com.