Yur*_*aha 6 django-filters django-rest-framework
我有一个简单的过滤器:
class ContentFilter(filters.FilterSet):
app = filters.UUIDFilter(required=True)
...
Run Code Online (Sandbox Code Playgroud)
我在简单的 ModelViewSet 上使用了它
class ContentView(ModelViewSet):
"""View for Content"""
serializer_class = ContentSerializer
filterset_class = ContentFilter
Run Code Online (Sandbox Code Playgroud)
但是当我尝试 get /contents/:id/ 时出现错误:
{
"app": [
"This field is required."
]
}
Run Code Online (Sandbox Code Playgroud)
那么,我的问题。我怎样才能required=True只设置我的list动作?
我的解决方案是:
def filter_queryset(self, queryset):
"""We need display filter only on list request, otherwise we get error on /id/ requests about app is required"""
if self.action != 'list':
self.filterset_class = None
return super().filter_queryset(queryset)
Run Code Online (Sandbox Code Playgroud)
什么是更好的解决方案,也许我可以在过滤器类中配置它?
我知道这是一个老问题,但也许有人想以不同的方式来做。我想出了重写filterset_class作为属性,并根据操作选择是否要使用filterset_class。我在代码中这样做是为了单一职责(filter_queryset 应该过滤,而不是选择一个filterset_class)。
我的代码:
from typing import Type
from django_filters import rest_framework as filters
from rest_framework.mixins import ListModelMixin, RetrieveModelMixin
from rest_framework.viewsets import GenericViewSet
from .filters import FooFilter
class FooViewSet(RetrieveModelMixin, ListModelMixin, GenericViewSet):
filter_backends = (filters.DjangoFilterBackend,)
@property
def filterset_class(self) -> Type[filters.FilterSet] | None:
if self.action == 'list':
return FooFilter
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1786 次 |
| 最近记录: |