Django REST Framework过滤多个字段

时间:2018-04-23 04:49:46

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

  

模型

class Task(Model):
    employee_owner = ForeignKey(Employee, on_delete=CASCADE)
    employee_doer = ForeignKey(Employee, on_delete=CASCADE)
  

浏览

class TaskViewSet(ModelViewSet):
    serializer_class = TaskSerializer
    queryset = Task.objects.all()
    filter_class = TaskFilter
  

过滤

class TaskFilter(FilterSet):
    owner_id = NumberFilter(name='employee_owner__id')
    doer_id = NumberFilter(name='employee_doer__id')

    class Meta:
        model = Task
        fields = {
            'owner_id',
            'doer_id'
        }
  

端点

http://localhost:8000/api/tasks?owner_id=1&doer_id=1

(仅提供ownerdoer为同一员工的任务)

http://localhost:8000/api/tasks?owner_id=1

(仅提供owner为特定员工且doer为任何人)的任务

http://localhost:8000/api/tasks?doer_id=1

(仅提供doer为特定员工且owner为任何人)的任务

  

我想要什么

我想要一个端点,如:

http://localhost:8000/api/tasks?both_id=1

(这将给我以上3个端点的所有结果)

我希望django-filter完全按照以下方式进行过滤:

Task.objects.filter(
    Q(employee_owner__id=1) | Q(employee_doer__id=1)
)

我怎样才能实现这一目标?谢谢。

2 个答案:

答案 0 :(得分:6)

您可以使用method参数自定义过滤器,如下所示:

class TaskFilter(FilterSet):
    owner_id = NumberFilter(name='employee_owner__id')
    doer_id = NumberFilter(name='employee_doer__id')
    both_id = NumberFilter(method='filter_both')

    class Meta:
        model = Task
        fields = {
            'owner_id',
            'doer_id',
            'both_id' 
        }

    def filter_both(self, queryset, name, value):
        return queryset.filter(
            Q(employee_owner__id=value) | Q(employee_doer__id=value)
        )

答案 1 :(得分:0)

我个人建议使用DjangoFilterBackend进行过滤

from django_filters.rest_framework import DjangoFilterBackend

之后

class TaskViewSet(ModelViewSet):
    serializer_class = TaskSerializer
    queryset = Task.objects.all()
    filter_backends = (DjangoFilterBackend,)
    filterset_fields = ['owner_id', 'doer_id']# pass query through params