【问题标题】:Django Rest Framework + django_filter: filter for name or none if nothing is providedDjango Rest Framework + django_filter:过滤名称或不提供任何内容
【发布时间】:2017-04-02 04:57:20
【问题描述】:

我将 Django rest 框架与 django_filters 一起使用。 (我尽量简化/减少这里的代码)

如果请求中没有指定约束,我如何强制 django_filters 过滤约束__name=None(或约束=None)?

假设我有这个模型:

class Resource(models.Model):
    constraints = models.ManyToManyField(Feature, related_name='constraint+', blank=True)

class Feature(models.Model):
    name = models.CharField(max_length=255, blank=False, unique=True)

还有这个视图和过滤器:

class ResourceFilter(FilterSet):
    constraints = django_filters.CharFilter(name='constraints__name')

    class Meta:
        model = Resource
        fields = ['constraints']


class ResourceViewSet(viewsets.ModelViewSet):
    serializer_class = ResourceSerializer
    filter_class = ResourceFilter
    filter_backends = (filters.DjangoFilterBackend,)

/api/resource/?constraints=testconstraint 工作正常,但我希望 /api/resource/ 只返回没有约束的资源。

我可以减少查询集,但感觉 django_filters 可以解决一些问题。是吗?:

def get_queryset(self):
    if 'constraints' not in self.request.query_params:
        return Resource.objects.filter(constraints=None)
    else:
        return Resource.objects.all()

【问题讨论】:

    标签: python django django-rest-framework django-filter


    【解决方案1】:

    您可以覆盖 FilterSet 子类上的 qs 属性,您可以在其中操作过滤后的查询并访问请求对象:

    试试这个:

    class ResourceFilter(FilterSet):
    
        constraints = django_filters.CharFilter(name='constraints__name')
    
        class Meta:
            model = Resource
            fields = ['constraints']
    
        @property
        def qs(self):
            parent_qs = super(ResourceFilter, self).qs
            if 'constraints' in self.request.query_params:
                return parent_qs
            else:
                return parent_qs.filter(constraints=None)
    

    【讨论】:

      【解决方案2】:

      子类CharFilter覆盖filter

      class OrNoneCharFilter(CharFilter):   
          def filter(self, qs, value):
             if value is None: 
                 return qs.filter(constraints=None)
      
             return super().filter(qs, value)   
      

      【讨论】:

        猜你喜欢
        • 2017-11-09
        • 1970-01-01
        • 1970-01-01
        • 2021-12-02
        • 1970-01-01
        • 2015-09-02
        • 2018-07-23
        • 2021-06-25
        • 2013-05-21
        相关资源
        最近更新 更多