django orm中的多字段过滤

django orm中的多字段过滤,django,django-rest-framework,Django,Django Rest Framework,我有一些字段可以用来过滤列表。我可以在过滤器查询中使用所有或部分字段。我的观点如下。但是我不能得到一个正确的答案。这意味着我希望已选择的某些记录未被选择 class UserListAPIView(ListAPIView): serializer_class = serializers.UserListSerializer pagination_class = AdminPagination permission_classes = (IsAuthRolePermission,) filte

我有一些字段可以用来过滤列表。我可以在过滤器查询中使用所有或部分字段。我的观点如下。但是我不能得到一个正确的答案。这意味着我希望已选择的某些记录未被选择

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方法或更好的方法,这是常见的做法

现在,在代码中添加过滤器,即使未指定过滤器。假设客户端已经添加了查询参数full_name=foo,那么您的代码会继续将email=、facility_name=、user_state=添加到过滤器中,该过滤器很可能不会返回任何内容,因为数据库中没有这些值的组合。因此,与其这样做,不如只添加指定的查询参数

大概是这样的:

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

再次,您应该考虑将此移到FieldE-QueReSET,因为这是用于过滤的方法。

您能解释一下吗?我想选择的一些记录没有被选中?什么不起作用?