django Q对象ValueError:解压缩的值太多(预期2)

时间:2017-12-17 21:16:20

标签: django django-rest-framework django-views

我正在尝试动态构建Q对象。这是我的代码:

class StudentiRicerche(ListAPIView):

    serializer_class = StudentiLista

    def get_queryset(self):

        query_params = self.request.query_params

        q_objects = Q()
        for k, v in query_params.items():
            param = '{0}__icontains={1}'.format(k, v) # k and v are dynamic values
            q_objects &= Q(param)

        queryset = Studenti.objects.filter(q_objects) # Here i get an error
        return queryset

使用此代码,我在使用过滤器

的行上获得了ValueError

我还试图以这种方式直接使用Q对象的Q对象列表:

class StudentiRicerche(ListAPIView):

    serializer_class = StudentiLista

    def get_queryset(self):

        query_params = self.request.query_params
        q_list = []

        for k, v in query_params.items():
            param = '{0}__icontains={1}'.format(k, v)
            q_list.append(Q(param)) # Q with 'and' condition

        queryset = Studenti.objects.filter(*q_list) # here I get an error also
        return queryset

但是我在这里又犯了同样的错误!有什么想法??

1 个答案:

答案 0 :(得分:1)

简化。你不需要使用Q:

class StudentiRicerche(ListAPIView):

    serializer_class = StudentiLista

    def get_queryset(self):

        query_params = self.request.query_params
        queryset = Studenti.objects.filter(**{'{}__icontains'.format(k):v for k,v in query_params.items() })
        return queryset

说明:

  1. .filterQ()的参数是字典,而不是列表
  2. .filterQ()使用命名参数,例如:.filter(name__icontains='Ivan', email__icontains='mail.com')
  3. 但你可以使用** kwargs:.filter(**{'name__icontains':'Ivan', 'email__icontains': 'mail.com')
  4. 例如:.filter(**{'{}__icontains'.format(k):v for k,v in query_params.items() })
  5. 如果您想动态Q(),则必须使用字典:Q(**{'{}__icontains'.format(k):v for k,v in query_params.items() })
  6. 另外

    1. 您可以使用命名参数和** kwargs的组合,例如.filter(is_active__isnull=False, **{'{}__icontains'.format(k):v for k,v in query_params.items() })