#31397: Support qs.filter(related=Q(...))
-------------------------------------+-------------------------------------
               Reporter:  Roman      |          Owner:  nobody
  Odaisky                            |
                   Type:  New        |         Status:  new
  feature                            |
              Component:  Database   |        Version:  3.0
  layer (models, ORM)                |
               Severity:  Normal     |       Keywords:
           Triage Stage:             |      Has patch:  0
  Unreviewed                         |
    Needs documentation:  0          |    Needs tests:  0
Patch needs improvement:  0          |  Easy pickings:  0
                  UI/UX:  0          |
-------------------------------------+-------------------------------------
 It would be very helpful to be able to use Q objects with related models,
 especially if some other code generates the Q objects. Use case:

 {{{
 def bestsellers(q):
     qs = Author.objects.filter(q).annotate(total_sold=Sum("book__n_sold"))
     ...
 }}}
 Suppose that later the calculations become so complex that they can’t be
 expressed in terms of aggregate functions, thus Python code has to be
 written instead, and the queryset changes models:
 {{{
 def bestsellers(q):  # q still contains fields from the Author model
     qs = Book.objects.filter(???)
     for book in qs:
         ...
 }}}
 It would be natural to try to write `Book.objects.filter(author=q)`, but
 this syntax isn’t supported.

 I suggest that `Q(model=Q(a=b, c=d))` be allowed with the same effect as
 `Q(model__a=b, model__c=d)` (recursively if the inner Q is nested).

 The implementation does not seem to be particularly complex. This function
 does most of the work:
 {{{
 def prefix_q(prefix, q):
     """ Q(prefix=q) === prefix_q(prefix, q) """
     if isinstance(q, tuple):
         return (prefix + "__" + q[0], q[1])

     return Q(*[prefix_q(prefix, c) for c in q.children],
         _connector=q.connector, _negated=q.negated)
 }}}

-- 
Ticket URL: <https://code.djangoproject.com/ticket/31397>
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/050.981d3cb3b1e2b12b4c0535f87bfae936%40djangoproject.com.

Reply via email to