Opened 6 months ago

Closed 6 months ago

#31606 closed New feature (fixed)

Cannot mix Exists expression with keyword arguments to When

Reported by: Ryan Heard Owned by: Ryan Heard
Component: Database layer (models, ORM) Version: master
Severity: Normal Keywords:
Cc: Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: yes UI/UX: no

Description (last modified by Ryan Heard)

I don't seem to be able to provide an Exists expression to When alongside keyword arguments like you can with filter. For instance, consider:

class State(models.Model):
 pass

class County(models.Model):
  name = CharField(max_length=50)
  state = ForeignKey(State, related_name='counties')

I can execute the following query just fine:

County.objects.filter(
  Exists(State.objects.filter(counties=OuterRef('pk'), name="Texas")),
  name="Dallas",
)

But a similar query using When does not work:

>>> County.objects.annotate(
  status=Case(
    When(Exists(State.objects.filter(counties=OuterRef('pk'), name="Texas")), name="Dallas", then=Value("DALLAS COUNTY")),
    default=Value("ELSEWHERE"),
))
TypeError: When() supports a Q object, a boolean expression, or lookups as a condition.

Instead the arguments must be wrapped in a Q object:

>>> County.objects.annotate(
  status=Case(
    When(Q(Exists(State.objects.filter(counties=OuterRef('pk'), name="Texas")), name="Dallas"), then=Value("DALLAS COUNTY")),
    default=Value("ELSEWHERE"),
))

This is inconvenient and inconsistent with how filter works, as shown.

When's init method can be modified to allow similar input as filter. Code is in a branch in my repo, but as this is my first time contributing to Django, I want to make sure I open a ticket and get feedback first.

Also I wasn't sure how to classify this. I wasn't sure if it was a bug, as I wasn't sure if it was designed this way.

Change History (7)

comment:1 Changed 6 months ago by Ryan Heard

Description: modified (diff)

comment:2 Changed 6 months ago by Ryan Heard

Description: modified (diff)

comment:3 Changed 6 months ago by Simon Charette

Component: UncategorizedDatabase layer (models, ORM)
Triage Stage: UnreviewedAccepted
Type: Cleanup/optimizationNew feature
Version: 3.0master

comment:4 Changed 6 months ago by Mariusz Felisiak

comment:5 Changed 6 months ago by Mariusz Felisiak

Needs documentation: set

comment:6 Changed 6 months ago by Mariusz Felisiak

Needs documentation: unset
Owner: changed from nobody to Ryan Heard
Status: newassigned
Triage Stage: AcceptedReady for checkin

comment:7 Changed 6 months ago by Mariusz Felisiak <felisiak.mariusz@…>

Resolution: fixed
Status: assignedclosed

In 587b179d:

Fixed #31606 -- Allowed using condition with lookups in When() expression.

Note: See TracTickets for help on using tickets.
Back to Top