Укажите, в каком порядке применять фильтры в django_filters.Набор фильтров
В течение django_filters.FilterSet
:
class SomeFilter(django_filters.FilterSet):
model = SomeModel
fields = {
"is_archived": ("exact",),
}
include_ancestors = django_filters.BooleanFilter(method="include_ancestors_filter")
def include_ancestors_filter(self, queryset, name, value):
pass
как я могу указать, что поле фильтра include_ancestors
должно применяться после всех других полей фильтра (например is_archived
)?
Это необходимо в моем случае, потому что включение предков зависит от результирующего набора (т.е. зависит от того, какие дочерние элементы были включены на основе всех других фильтров).
Вероятно, вы можете "взломать" это, переместив include_ancestors
вниз по списку значений:
class MoveDownForm:
move_down_field = 'include_ancestors'
@property
def cleaned_data(self):
new = old = super().cleaned_data
if self.move_down_field in old:
new = {k: v for k, v in old.items() if k != self.move_down_field}
new['move_down_field'] = old['move_down_field']
return new
а затем работайте с:
class SomeFilter(django_filters.FilterSet):
class Meta:
model = SomeModel
form = MoveDownForm
fields = {
"is_archived": ("exact",),
}
include_ancestors = django_filters.BooleanFilter(method="include_ancestors_filter")
def include_ancestors_filter(self, queryset, name, value):
pass
Но я бы протестировал это с помощью двух пользовательских фильтров и проверил порядок печати, если вы поменяете местами параметры строки запроса.
class SomeFilter(django_filters.FilterSet):
include_ancestors = django_filters.BooleanFilter(required=False) # dont add a method
class Meta:
model = SomeModel
fields = {"is_archived": ["exact"]}
@property
def qs(self):
queryset = super().qs # it wont be filtered here
if self.form.cleaned_data.get("include_ancestors"):
queryset = self._apply_ancestor_logic(queryset)
return queryset
def _apply_ancestor_logic(self, queryset):
pass
Я бы сделал что-то вроде этого, где я бы не стал присваивать method
имя filter
, чтобы Django
оставлял ancestor filter
при выполнении queryset
звоните.
Как только все filters
будут использованы, я проверю, нужно ли добавлять логику ancestor
к возвращаемому queryset
или нет.