python - 如何使用 Django Filters 过滤同一字段的多个值?
问题描述
嗨,我正在尝试使用 django 过滤器进行过滤,我可以进行如下过滤
# function to do filter
class EmailFilter(django_filters.FilterSet):
email_ml_recommendation = filters.CharFilter(method='filter_by_decision')
email_broker = django_filters.CharFilter(field_name="email_broker",
lookup_expr='icontains')
class Meta:
model = submission
fields = '__all__'
def filter_by_decision(self, qs, name, value):
if ',' in value:
# filter for multiple selection
if value.count(',') == 1:
print('inside --')
v_1 = value.split(',')[0]
v_2 = value.split(',')[1]
return qs.filter(
Q(email_ml_recommendation__icontains=v_1) | Q(email_ml_recommendation__icontains=v_2)
)
elif value.count(',') == 2:
v_1 = value.split(',')[0]
v_2 = value.split(',')[1]
v_3 = value.split(',')[2]
return qs.filter(
Q(email_ml_recommendation__icontains=v_1) | Q(email_ml_recommendation__icontains=v_2)|
Q(email_ml_recommendation__icontains=v_3)
)
else:
return qs.filter(
Q(email_ml_recommendation__icontains=value)
)
并在下面的课程中调用我的过滤器
class SUBMISSIONFILTERVIEWSET(viewsets.ModelViewSet):
queryset = submission.objects.all().filter(email_today_mail=1).order_by('-email_last_updated')
serializer_class = SubmissionsSerializer
filter_backends = (DjangoFilterBackend, OrderingFilter, SearchFilter,)
filterset_class = EmailFilter
OrderingFilter()
# ordering_fields = ('broker_name')
ordering = ('-email_last_updated') # default ordering can be overridden using ordering fields
问题是我可以过滤同一字段上的多个值但为此我需要增加我的 Q 参数我的意思是为了对同一字段进行多值过滤(email_ml_recommendation)我必须创建一个自定义方法 filter_by_decision 和里面我必须使用 Q 参数与我用 comman 分隔的值相同的次数,问题是我不知道有多少值可以来自客户端,有没有更好的方法来做到这一点。
解决方案
我想与您分享我为过滤带有逗号分隔值的字段而制作的解决方案:
class ListFilterField(Filter):
""" This is a custom FilterField to enable a behavior like:
?id=1,2,3,4 ...
"""
def filter(self, queryset, value):
# If no value is passed, just return the
# initial queryset
if not value:
return queryset
self.lookup_expr = 'in' # Setting the lookupexpression for all values
list_values = value.split(',') # Split the incoming querystring by comma
if not all([item.isdigit() for item in list_values]): # In this case, I check on isdigit()
raise serializers.ValidationError(
'All values in {}s are not integer.'.format(str(list_values))
)
return super(ListFilterField, self).filter(queryset, list_values) # If everything is fine, I just pass the execution to the Filter-class
您可以修改此解决方案并使用此字段,如下所示:
class EmailFilter(django_filters.FilterSet):
email_ml_recommendation = ListFilterField(field_name='your_field_name')
email_broker = django_filters.CharFilter(field_name="email_broker",
lookup_expr='icontains')
class Meta:
model = submission
fields = '__all__'
推荐阅读
- javascript - 检查用户是否有 Internet 过滤器 (https://netfree.link/)
- python-3.x - 在 Matplotlib 中为 value_counts().plot 添加值文本
- node.js - 完成状态码:Firebase 函数上的 204 并没有发生任何事情
- automation - Gitlab Runner Automation/如何将最新文件本地下载到计算机
- javascript - 检查所有相关子数组是否符合条件
- mysql - 如何清除mysql中的空闲事务?
- android - android Espresso-toast 消息断言不适用于 sdk 30
- reactjs - 如何在 React Table v7 中使用 className 属性?
- snowflake-cloud-data-platform - 从现有表创建表而不复制雪花中的数据
- angular - nativescript/angular webview 外部链接打开应用程序。如何停止打开应用程序