Opened 8 years ago

Closed 3 years ago

#7312 closed Uncategorized (fixed)

QuerySet.complex_filter() chokes on custom Q objects (with add_to_query() method)

Reported by: Johannes Dollinger Owned by: nobody
Component: Database layer (models, ORM) Version: master
Severity: Normal Keywords: qsrf-cleanup
Cc: Triage Stage: Unreviewed
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no


To reproduce, try:

class DoNothingQ:
    def add_to_query(self, query, aliases):


A side effect: My patch prevents builtin Q objects from being wrapped in another Q object when passed to complex_filter(). I'm not sure that's ok.

The cause ist the same as in

Attachments (2)

complex_filter_q.diff (617 bytes) - added by Johannes Dollinger 8 years ago.
7312.regressiontest.diff (934 bytes) - added by anonymous 8 years ago.

Download all attachments as: .zip

Change History (10)

Changed 8 years ago by Johannes Dollinger

Attachment: complex_filter_q.diff added

Changed 8 years ago by anonymous

Attachment: 7312.regressiontest.diff added

comment:1 Changed 8 years ago by George Vilches

Keywords: qsrf-cleanup added
Needs documentation: unset
Needs tests: unset
Patch needs improvement: unset

comment:2 Changed 8 years ago by Jacob

milestone: 1.0

comment:3 Changed 8 years ago by Malcolm Tredinnick

The patch looks fine. complex_filter() is a bit of an ugly method, though, and definitely not part of the public API, so I'm going to leave out the test. We'll add tests when we fix limit_choices_to, but I'm not sure locking down the behaviour of complex_filter() just yet is the right thing to do. Non-internal code should really only be calling filter() and exclude() (or calling .query.add_q() directly, I guess).

comment:4 Changed 8 years ago by Malcolm Tredinnick

Resolution: fixed
Status: newclosed

(In [7766]) Fixed #7312 -- Fixed handling of custom Q-like objects in QuerySet.custom_filter().

This is pretty much internal-use-only code, so doesn't affect public API at
all, but it's nice to be able to handle things properly in any case. Patch from

comment:5 Changed 5 years ago by Jacob

milestone: 1.0

Milestone 1.0 deleted

comment:6 Changed 3 years ago by Mikhail Podgurskiy

Easy pickings: unset
Resolution: fixed
Severity: Normal
Status: closednew
Type: Uncategorized
UI/UX: unset

Seems broken again in django 1.6.1

*** AttributeError: DoNothingQ instance has no attribute '__getitem__'

this happens b/c we lost in django.db.models.sql.query.Query.add_q method

if hasattr(q_object, 'add_to_query'):
    # Complex custom objects are responsible for adding themselves.
    q_object.add_to_query(self, used_aliases)

comment:7 Changed 3 years ago by Tim Graham

I'm not sure the example in the ticket is valid anymore. add_to_query is not a documented API. Could you clarify? There seems to be a typo in your comment: "we lost in django.db.models.sql.query.Query.add_q method" -- I'm not sure what that means.

comment:8 Changed 3 years ago by Anssi Kääriäinen

Resolution: fixed
Status: newclosed

I created a separate ticket for this, see #21696.

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