django - 在 django orm 中使用多字段进行过滤
问题描述
我有一些字段可以用来过滤列表。我可以在过滤查询中使用所有这些字段或其中一些字段。我的观点如下。但我无法得到正确的答案。这意味着我期望被选中的一些记录没有被选中。
class UserListAPIView(ListAPIView):
serializer_class = serializers.UserListSerializer
pagination_class = AdminPagination
permission_classes = (IsAuthRolePermission,)
filter_backends = (filters.OrderingFilter,)
ordering_fields = '__all__'
def get_queryset(self):
full_name = self.request.query_params.get('full_name', '')
email = self.request.query_params.get('email', '')
facility_name = self.request.query_params.get('facility_name', '')
user_state = self.request.query_params.get('user_state', '')
if full_name or email or facility_name or user_state:
queryset = User.objects.filter(full_name__icontains=full_name,
email__icontains=email,
facility_name__icontains=facility_name,
user_state__icontains=user_state) \
.annotate(facility=F('facility_name'),
state=F('user_state'),
last_access=F('lastAccess')) \
.order_by('-id').distinct()
else:
queryset = User.objects.all()\
.annotate(facility=F('facility_name'),
state=F('user_state'),
last_access=F('lastAccess'))\
.order_by('-id')
return queryset
解决方案
你做错了。首先,让我建议这种过滤应该在filter_queryset
方法中完成,而不是get_queryset
方法或更好,使用django-filter 中的 DjangoFilterBackend这是常见的做法。
Now pertaining your code, you add the filters even when they are not specified. Assuming the client has added the query param full_name=foo
, your code goes on to add email="",facility_name="",user_state=""
to the filter which will most likely not return anything as there will be no combination of those values in the database. So rather, than doing that, add only the query params specified.
Something like this:
def get_queryset(self):
filter_fields = ['full_name', 'email', 'facility_name', 'user_state']
params = {'{}__icontains'.format(k): v for k,v in self.request.query_params.items() if k in filter_fields}
queryset = User.objects.filter(**params) \
.annotate(facility=F('facility_name'),
state=F('user_state'),
last_access=F('lastAccess')) \
.order_by('-id').distinct()
return queryset
Again, you should consider moving this to filter_queryset
as that is the method meant for filtering.
推荐阅读
- php - header('Content-Type: image/jpeg') 使网站变成黑色
- python-3.x - 我们如何知道模型在训练用于对象分类/检测的神经网络时收敛?
- javascript - 如何在反应的选择标签中填充编辑模式下的值?
- php - php 服务器 - 新文件上的 500 错误消息
- ios - 依次运行 3 个 observable,使用最后一个中的第一个结果
- python - 如何在python中使字符串启动一个函数
- python - 在 Python 中导入数据表
- c# - 如何使 JSON 消息序列化的 C# 和 C++ 项目保持同步?
- mysql - ALL 运算符的 MySQL 问题
- azure-devops - Azure DevOps 设置 - 单一解决方案下的多个项目/WebJobs