Opened 4 years ago

Last modified 4 years ago

#31606 closed New feature

Cannot mix Exists expression with keyword arguments to When — at Version 2

Reported by: Ryan Heard Owned by: nobody
Component: Database layer (models, ORM) Version: dev
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 (2)

comment:1 by Ryan Heard, 4 years ago

Description: modified (diff)

comment:2 by Ryan Heard, 4 years ago

Description: modified (diff)
Note: See TracTickets for help on using tickets.
Back to Top