I want to create Mixins for QuerySet objects that will by default filter out certain records (e.g. filter out "deleted" records, or filter out "unapproved" records, etc). I'd like those to be separate independent mixins. So in each of those, I override all() to filter out deleted or unapproved, etc. But, I also want to offer a method in the queryset to remove those filters or remove some part of those filters.
That's where this code comes in. After some examination of how QuerySets work, this seemed like the simplest method for "undoing" some filter in a queryset
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | """
Use this hack to remove a where clause from a queryset
It assumes the following internals:
QuerySet has something called a query
query has something called a 'where' which is a tree root
that tree root is of type WhereNode and has connector 'OR' or 'AND' and some number of children
each child can be a simple clause (Constraint) or another WhereNode with a bunch of kids of its own
"""
from django.db.models.sql.where import *
__all__ = ['remove_clause', ]
def remove_clause(queryset, field_name):
# Start the recursive fixin'
_remove_clause(queryset.query.where, field_name)
def _remove_clause(node, field_name):
if isinstance(node, WhereNode):
null_these = []
# look at each child and treat appropriately
for i, child in enumerate(node.children):
if isinstance(child, WhereNode):
_remove_clause(child, field_name)
elif isinstance(child, tuple) and isinstance(child[0], Constraint):
if child[0].field.name == field_name:
null_these.append(i)
# we have some children to "nullify"
for null_this in null_these:
if node.connector == 'AND':
node.children[null_this] = EverythingNode()
else:
node.children[null_this] = NothingNode()
|
More like this
- Template tag - list punctuation for a list of items by shapiromatron 9 months ago
- JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 9 months, 1 week ago
- Serializer factory with Django Rest Framework by julio 1 year, 3 months ago
- Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 4 months ago
- Help text hyperlinks by sa2812 1 year, 5 months ago
Comments
This is good, but will not work from djang0 >= 1.9.0
#
Please login first before commenting.