Django REST Framework 过滤多个字段
Django REST Framework filter multiple fields
Models
class Task(Model):
employee_owner = ForeignKey(Employee, on_delete=CASCADE)
employee_doer = ForeignKey(Employee, on_delete=CASCADE)
Views
class TaskViewSet(ModelViewSet):
serializer_class = TaskSerializer
queryset = Task.objects.all()
filter_class = TaskFilter
Filter
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'
}
Endpoints
http://localhost:8000/api/tasks?owner_id=1&doer_id=1
(仅分配 owner
和 doer
是同一员工的任务)
http://localhost:8000/api/tasks?owner_id=1
(仅分配 owner
是特定员工而 doer
是任何人的任务)
http://localhost:8000/api/tasks?doer_id=1
(仅分配 doer
是特定员工而 owner
是任何人的任务)
What I want
我想要这样的端点:
http://localhost:8000/api/tasks?both_id=1
(这会给我以上 3 个端点的所有结果)
我希望django-filter
像这样进行过滤:
Task.objects.filter(
Q(employee_owner__id=1) | Q(employee_doer__id=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)
)
我个人建议使用 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
Models
class Task(Model):
employee_owner = ForeignKey(Employee, on_delete=CASCADE)
employee_doer = ForeignKey(Employee, on_delete=CASCADE)
Views
class TaskViewSet(ModelViewSet):
serializer_class = TaskSerializer
queryset = Task.objects.all()
filter_class = TaskFilter
Filter
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'
}
Endpoints
http://localhost:8000/api/tasks?owner_id=1&doer_id=1
(仅分配 owner
和 doer
是同一员工的任务)
http://localhost:8000/api/tasks?owner_id=1
(仅分配 owner
是特定员工而 doer
是任何人的任务)
http://localhost:8000/api/tasks?doer_id=1
(仅分配 doer
是特定员工而 owner
是任何人的任务)
What I want
我想要这样的端点:
http://localhost:8000/api/tasks?both_id=1
(这会给我以上 3 个端点的所有结果)
我希望django-filter
像这样进行过滤:
Task.objects.filter(
Q(employee_owner__id=1) | Q(employee_doer__id=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)
)
我个人建议使用 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