Reputation: 83
The question related to python - django framework, and probably to experienced django developers. Googled it for some time, also seeked in django queryset itself, but have no answer. Is it possible to know if queryset has been filtered and if so, get key value of filtered parameters? I'm developing web system with huge filter set, and I must predefine some user-background behavior if some filters had been affected.
Upvotes: 1
Views: 877
Reputation: 14846
I agree with Willem Van Onsen, in that accessing the internals of the query object isn't guaranteed to work in the future. It's correct for now, but might change.
But going half-way down that path, you could use the following:
is_filtered_query = bool(' WHERE ' in str(queryset.query))
which will pretty much do the job!
Upvotes: 1
Reputation: 477607
Yes, but since to the best of my knowledge this is not documented, you probably should not use it. Furthermore it looks to me like bad design if you need to obtain this from a QuerySet
.
For a QuerySet
, for example qs
, you can obtain the .query
attribute, and then query for the .where
attribute. The truthiness of that attribute checks if that node (this attribute is a WhereNode
, which is a node in the syntax of the query) has children (these children are then individual WHERE conditions, or groups of such conditions), hence has done some filtering.
So for example:
qs = Model.objects.all()
bool(qs.query.where) # --> False
qs = Model.objects.filter(foo='bar')
bool(qs.query.where) # --> True
If you inspect the WhereNode
, you can see the elements out of which it is composed, for example:
>>> qs.query.where
<WhereNode: (AND: <django.db.models.lookups.Exact object at 0x7f2c55615160>)>
and by looking to the children, we even can obtain details:
>>> qs.query.where.children[0]
>>> c1.lhs
Col(app_model, app.Model.foo)
>>> c1.lookup_name
'exact'
>>> c1.rhs
'bar'
But the notation is rather cryptic. Furthermore the WhereNode
is not per se a conjunctive one (the AND
), it can also be an disjunctive one (the OR
), and it is not said that any filtering will be done (since the tests can trivially be true, like 1 > 0
). We thus only query if there will be a non-empty WHERE
in the SQL query. Not whether this query will restrict the queryset in any way (although you can of course inspect the WhereNode
, and look if that holds).
Note that some constraints are not part of the WHERE
, for example if you make a JOIN
, you will perform an ON
, but this is not a WHERE
clause.
Since however the above is - to the best of my knowledge - not extenstively documented, it is probably not a good idea to depend on this, since that means that it can easily change, and thus no longer work.
Upvotes: 7
Reputation: 551
You can use the query
attribute (i.e. queryset.query
) to get the data used in the SQL query (the output isn't exactly valid SQL).
You can also use queryset.query.__dict__
to get that data in a dictionary format.
Upvotes: 2