为了账号安全,请及时绑定邮箱和手机立即绑定

Django 休息框架视图集 get_queryset() 不返回正确的查询集

Django 休息框架视图集 get_queryset() 不返回正确的查询集

holdtom 2022-07-12 10:30:09
我正在使用 Django Rest Framework Filter 来访问我的数据。我为我的一个模型编写了一个自定义视图集,以处理对某些特定字段的逻辑“或”操作,以请求带有 url 的请求。这是我的 ViewSet 类(打印仅用于我的调试)class CustomViewSet(viewsets.ModelViewSet):    permission_classes = (IsAuthenticated,)    queryset = appart.MyModel.objects.order_by('pk')    serializer_class = MyModelSerializer    filter_class = MyModelFilter    def get_queryset(self):        # getting param        query = dict(self.request.query_params)        print(query)        ct_query = query['caracteristique_text__icontains'][0].split('|')        cl_query = query['caracteristique__libelle__in'][0].split(',')        # writting request syntax        ct = 'Q(caracteristique__libelle__in=' + str(cl_query) + ')&('        print(ct)        for value in ct_query:            ct += "Q(caracteristique_text__icontains='" + value + "')|"        ct = ct[0:len(ct) - 1]        ct += ')'        print(ct)        filtre_text = "global filtre; filtre = " + ct        # creating the request        exec(filtre_text)        #running the request        self.queryset = self.queryset.filter(filtre)        print(self.queryset)        return self.queryset # doesn't return what I see when running print(self.queryset)和 MyModelFilter 类:class MyModelFilter(ModelFilterSet):    class Meta:        model = appart.MyModel        fields = ('id', 'libelle', 'locataire_appart', 'bien_appart',                     'adresse', 'loyer_appart', 'caracteristique', 'caracteristique_text',                     'date_creation', 'derniere_maj')这段代码运行良好,可以做我想做的事。他获取 url 参数,动态创建请求语法并返回我正在寻找的数据。唯一的问题是最后的返回结果与我在代码中打印的结果不同。他仍在尝试根据给定的 url 执行 GET 请求,并且当语法不遵循 django_filter 规则时不返回任何内容。任何人都可以帮助我防止我的视图集出现这种行为吗?
查看完整描述

2 回答

?
尚方宝剑之说

TA贡献1788条经验 获得超4个赞

好的,所以我终于解决了我的问题,代码中没有错误。这是由于filter_class = MyModelFilter. 我刚刚评论了这条线,一切都开始起作用了。老实说,我不知道为什么,但如果有人知道原因,我将不胜感激。


我还查看了exec@schillingt 正在谈论的内容,这是那些试图做同样事情或遇到同样问题的人的结果。


class CustomViewSet(viewsets.ModelViewSet):


    permission_classes = (IsAuthenticated,)

    queryset = models.MyModel.objects.order_by('pk')

    serializer_class = MyModelSerializer

    filter_class = MyModelFilter


    def get_queryset(self):


        query = dict(self.request.query_params)


        ct = self.request.query_params.get('caracteristique_text__icontains', None)

        cl = self.request.query_params.get('caracteristique__libelle__in', None)


        if ct is not None and cl is not None:


            self.filter_class = None


            ct_query = query['caracteristique_text__icontains'][0].split(',')

            cl_query = query['caracteristique__libelle__in'][0].split(',')


            full_query = Q(caracteristique__libelle__in=cl_query)


            ct = Q()


            for value in ct_query:

                ct_part = Q(caracteristique_text__icontains=value)

                ct |= ct_part


            full_query &= ct


            self.queryset = self.queryset.filter(full_query)


            return self.queryset


    return models.MyModel.objects.order_by('pk')


这篇文章也可以是有用的过滤器或条件


查看完整回答
反对 回复 2022-07-12
?
catspeake

TA贡献1111条经验 获得超0个赞

您需要使用 Django 过滤器指定一些过滤器。我想你只需要 BaseInFilter: https ://django-filter.readthedocs.io/en/master/ref/filters.html#baseinfilter


class MyModelFilter(ModelFilterSet):

    caracteristique_text = BaseInFilter(field_name='caracteristique_text', lookup_exp='icontains')

    libelle = BaseInFilter(field_name='libelle', lookup_exp='in')


    class Meta:

        model = appart.MyModel

        fields = ('id', 'libelle', 'locataire_appart', 'bien_appart', 

                    'adresse', 'loyer_appart', 'caracteristique', 'caracteristique_text', 

                    'date_creation', 'derniere_maj')


查看完整回答
反对 回复 2022-07-12
  • 2 回答
  • 0 关注
  • 148 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信