Django过滤器-如何为任何过滤器组合调用单个方法



我希望我的所有过滤器都路由到一个方法,这样我就可以查看每个方法,并根据设置的逻辑来决定。我已经完成了这项工作,但每个过滤器现在都调用相同的方法一次,导致下面的代码打印hi4次。

是否有将所有过滤器路由到单个方法的最佳实践方法?我希望hi在这里只打印一次,并想知道是否可以避免使用一个棘手的解决方案。

class CityFilter(FilterSet):
start_date_i = django_filters.DateTimeFilter(field_name='dept_date', method='filter_city')
start_date_j = django_filters.DateTimeFilter(field_name='dept_date', method='filter_city')
end_date_i = django_filters.DateTimeFilter(field_name='ret_date', method='filter_city')
end_date_j = django_filters.DateTimeFilter(field_name='ret_date', method='filter_city')
class Meta:
model = models.City
def filter_city(self, queryset, name, value):
print('hi')
data = self.data
sdate_i = data.get('start_date_i')
sdate_j = data.get('start_date_j')
edate_i = data.get('end_date_i')
edate_j = data.get('end_date_j')
# do expensive stuff and build queryset from all filter name / values
return queryset

您可以尝试使用MultiValueField[Django docs]和SuffixedMultiWidget[Django filter docs]将字段和过滤器组合为一个:

from django import forms
from django_filters import Filter
from django_filters.widgets import SuffixedMultiWidget
class QuadDateTimeWidget(SuffixedMultiWidget):
'''A widget that combines 4 `DateTimeInput` widgets'''
suffixes = ['start_i', 'start_j', 'end_i', 'end_j']

def __init__(self, attrs=None):
widgets = [
forms.DateTimeInput(),
forms.DateTimeInput(),
forms.DateTimeInput(),
forms.DateTimeInput(),
]
super().__init__(widgets, attrs):

def decompress(self, value):
# Need a list of values to be able to pass to children widgets
if value:
value = list(value)
value.extend([None] * (4 - len(value)))
return value
return [None, None, None, None]

class QuadDateTimeField(forms.MultiValueField):
'''A form field that uses 4 `DateTimeField` instances'''
widget = QuadDateTimeWidget

def __init__(self, fields=None, *args, **kwargs):
if fields is None:
fields = (
forms.DateTimeField(),
forms.DateTimeField(),
forms.DateTimeField(),
forms.DateTimeField()
)
super().__init__(fields, *args, **kwargs)

def compress(self, data_list):
# You can change this to a dictionary for simpler use if needed, although remember to change `decompress` in the widget above to return a list of the values in that case
if data_list:
return list(data_list)
return [None, None, None, None]

class QuadDateTimeFilter(Filter):
'''A filter that uses QuadDateTimeField'''
field_class = QuadDateTimeField

def filter(self, qs, value):
# You can also filter here if needed, you can get the `field_name` parameter by using `self.field_name`
raise NotImplementedError("Implement the method on the FilterSet class")
class CityFilter(FilterSet):
date = QuadDateTimeFilter(field_name='dept_date', method='filter_city')

def filter_city(self, queryset, name, value):
print('hi')
sdate_i = value[0]
sdate_j = value[1]
edate_i = value[2]
edate_j = value[3]

# do expensive stuff and build queryset from all filter name / values

return queryset

最新更新