#25796: annotate() exception if there are same fields name OR in Q
-------------------------------------+-------------------------------------
     Reporter:  Falldog              |                    Owner:  nobody
         Type:  Bug                  |                   Status:  closed
    Component:  Database layer       |                  Version:  master
  (models, ORM)                      |
     Severity:  Normal               |               Resolution:  invalid
     Keywords:  annotate             |             Triage Stage:
                                     |  Unreviewed
    Has patch:  0                    |      Needs documentation:  0
  Needs tests:  0                    |  Patch needs improvement:  0
Easy pickings:  0                    |                    UI/UX:  0
-------------------------------------+-------------------------------------
Changes (by jarshwah):

 * status:  new => closed
 * version:  1.8 => master
 * resolution:   => invalid


Comment:

 The problem here is that you're combining two filters together that can't
 logically be grouped together. You've got half of a "HAVING" clause and
 half of a "WHERE" clause and you're trying to OR them together. This can't
 work.

 This would work (Maybe you should split these two filter clause):

 query.filter(commodity_count=0, Q(name__isnull=False) |
 Q(subshipment_set__name__isnull=False))
 # or maybe..
 query.filter(commodity_count=0).filter(Q(name__isnull=False) |
 Q(subshipment_set__name__isnull=False))

 But I'm not really sure what you're trying to **do** with your query. Do
 you perhaps want to do the name is null checking *before* the Count?
 Adding the filtering after the annotation always filters after the result
 of annotating. These are different:

 {{{
 Shipment.objects
     .annotate(commodity_count=Count('commodity_set'))
     .filter(name__isnull=False)

 # different!
 Shipment.objects
     .filter(name__isnull=False)
     .annotate(commodity_count=Count('commodity_set'))
 }}}

 The first will do the count, and then will remove any with null. The
 second will remove any with null and *then* do a count, which is important
 when you're trying to filter on the result of the count.

 This is *probably* the query you want:

 {{{

 Shipment.objects
     .filter(Q(name__isnull=False) | Q(subshipment__name__isnull=False)) #
 WHERE CLAUSE
     .annotate(commodity_count=Count('commodity_set'))  # count excludes
 null names
     .filter(commodity_count=0)  # inserts HAVING CLAUSE

 }}}

 Closing this as invalid because you can't combine aggregate filters with
 regular filters, but please reopen if I've misinterpreted your query.

--
Ticket URL: <https://code.djangoproject.com/ticket/25796#comment:2>
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 post to this group, send email to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/065.151c98f5deb2a76c5d9614666db6f175%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to