【问题标题】:Django REST Framework filter multiple fieldsDjango REST Framework 过滤多个字段
【发布时间】:2018-10-03 01:21:52
【问题描述】:

型号

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)
)

我怎样才能做到这一点?谢谢。

【问题讨论】:

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


    【解决方案1】:

    您可以像这样使用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)
            )
    

    【讨论】:

    • neverwalkaloner 一如既往的完美回答:)
    • 你有一个Q(),但你的答案或链接的文档似乎都没有解释它是从哪里导入的或者它代表什么。
    • 啊,通过model.objects.filter的正确搜索终于找到了它 - 它是from django.db.models import Q
    【解决方案2】:

    我个人建议使用 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-08-07
      • 2014-11-14
      • 2017-01-15
      • 1970-01-01
      • 2021-03-09
      • 1970-01-01
      • 1970-01-01
      • 2018-04-12
      相关资源
      最近更新 更多