Opened 7 years ago

Closed 16 months ago

#7312 closed Uncategorized (fixed)

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

Reported by: emulbreh 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

Description

To reproduce, try:

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

MyModel.objects.complex_filter(DoNothingQ())

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 http://groups.google.com/group/django-users/msg/3e6d910eacb8b542.

Attachments (2)

complex_filter_q.diff (617 bytes) - added by emulbreh 7 years ago.
7312.regressiontest.diff (934 bytes) - added by anonymous 7 years ago.

Download all attachments as: .zip

Change History (10)

Changed 7 years ago by emulbreh

Changed 7 years ago by anonymous

comment:1 Changed 7 years ago by gav

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

comment:2 Changed 7 years ago by jacob

  • milestone set to 1.0

comment:3 Changed 7 years ago by mtredinnick

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 7 years ago by mtredinnick

  • Resolution set to fixed
  • Status changed from new to closed

(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
emulbreh.

comment:5 Changed 4 years ago by jacob

  • milestone 1.0 deleted

Milestone 1.0 deleted

comment:6 Changed 16 months ago by kmmbvnr

  • Easy pickings unset
  • Resolution fixed deleted
  • Severity set to Normal
  • Status changed from closed to new
  • Type set to 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)
else:
   ...

comment:7 Changed 16 months ago by timo

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 16 months ago by akaariai

  • Resolution set to fixed
  • Status changed from new to closed

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

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