Django Rest Framework + django_filter:如果没有提供,则过滤名称或无

时间:2016-11-18 11:02:07

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

我正在使用Django rest Framework和django_filters。 (我试图尽可能地简化/减少代码)

如果请求中没有指定约束,我如何强制django_filters过滤constraints__name = None(或constraints = 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()

2 个答案:

答案 0 :(得分:2)

您可以覆盖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)

答案 1 :(得分: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)