- July 16, 2015
- hack orm manager mixin queryset
- 0 (after 0 ratings)
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, Constraint): if child.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()