def insertion_target_filters(self, instance, order_insertion_by):
"""
Creates a filter which matches suitable right siblings for ``node``,
where insertion should maintain ordering according to the list of
fields in ``order_insertion_by``.
For example, given an ``order_insertion_by`` of
``['field1', 'field2', 'field3']``, the resulting filter should
correspond to the following SQL::
field1 > %s
OR (field1 = %s AND field2 > %s)
OR (field1 = %s AND field2 = %s AND field3 > %s)
"""
fields = []
filters = []
fields__append = fields.append
filters__append = filters.append
and_ = operator.and_
or_ = operator.or_
for field_name in order_insertion_by:
if field_name[0] == '-':
field_name = field_name[1:]
filter_suffix = '__lt'
else:
filter_suffix = '__gt'
value = getattr(instance, field_name)
if value is None:
# node isn't saved yet. get the insertion value from pre_save.
field = instance._meta.get_field(field_name)
value = field.pre_save(instance, True)
q = Q(**{field_name + filter_suffix: value})
filters__append(reduce(and_, [Q(**{f: v}) for f, v in fields] + [q]))
fields__append((field_name, value))
return reduce(or_, filters)
评论列表
文章目录