#31606: Cannot mix Exists expression with keyword arguments to When
-------------------------------------+-------------------------------------
     Reporter:  rheard               |                    Owner:  nobody
         Type:                       |                   Status:  new
  Cleanup/optimization               |
    Component:  Uncategorized        |                  Version:  3.0
     Severity:  Normal               |               Resolution:
     Keywords:                       |             Triage Stage:
                                     |  Unreviewed
    Has patch:  1                    |      Needs documentation:  0
  Needs tests:  0                    |  Patch needs improvement:  0
Easy pickings:  1                    |                    UI/UX:  0
-------------------------------------+-------------------------------------
Description changed by rheard:

Old description:

> 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"),
> ))
> }}}
>
> 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.
> [https://github.com/rheard/django/commit/978e796bb18414d995d515ab7923831149300977
> 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.

New description:

 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.
 
[https://github.com/rheard/django/commit/978e796bb18414d995d515ab7923831149300977
 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.

--

-- 
Ticket URL: <https://code.djangoproject.com/ticket/31606#comment:1>
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 on the web visit 
https://groups.google.com/d/msgid/django-updates/064.5bc5e143e06cc71dc50509a305f563b8%40djangoproject.com.

Reply via email to