Django-filters 不适用于 Viewset
Django-filters does not work with the Viewset
我一直在尝试使用 django-filters,但对象没有得到过滤。此外,该权限不适用于 partial_update 视图
我有一个视图集,它具有基本操作,例如 - list()、retrieve()、destroy()、partial_update() 和其他一些操作,并尝试对其应用过滤器。
经过一些研究,我发现由于我是通过过滤器创建查询集,所以我将不得不覆盖 get_queryset() 方法。但是,这似乎也不起作用。过滤器是否仅适用于 ModelViewSet 或 ListApiView?
视图集-
class PostViewSet(viewsets.ViewSet):
"""
The Endpoint to list, retrieve, create and delete Posts.
"""
filter_backends = (DjangoFilterBackend, )
# filterset_class = PostFilter
filter_fields = ('pet_age', 'pet_gender', 'breed')
def get_permissions(self):
if self.action == 'partial_update' or self.action == 'update':
permission_classes = [IsPostAuthor, ]
elif self.action == 'create' or self.action == 'destroy':
permission_classes = [IsAuthenticated, ]
else:
permission_classes = [AllowAny, ]
return[permission() for permission in permission_classes]
def get_queryset(self):
return Post.objects.active() # This is implemented via custom Manager
def list(self, request, *args, **kwargs):
"""
Method for Post listing. It can be accessed by anyone.
"""
serializer = PostListSerializer(self.get_queryset(), many=True, context={"request": request})
return Response(serializer.data)
# REST CODE TRUNCATED
权限-
class IsPostAuthor(permissions.BasePermission):
"""
Object-level permission to only allow owners of an object to edit it.
"""
def has_object_permission(self, request, view, obj):
if request.user.is_authenticated:
if view.action in ['partial_update', 'update']:
return obj.user.id == request.user.id
return False
return False
后置过滤器-
class PostFilter(filters.FilterSet):
class Meta:
model = Post
fields = ('pet_age', 'pet_gender', 'breed', )
经理-
class PostManager(models.Manager):
def active(self):
return self.filter(post_status='Active')
任何帮助将不胜感激。
您已经覆盖了列表方法,因此无法调用 filter_queryet 方法。
def list(self, request, *args, **kwargs):
"""
Method for Post listing. It can be accessed by anyone.
"""
serializer = PostListSerializer(self.filter_queryset(self.get_queryset()), many=True, context= .
{"request": request})
return Response(serializer.data)
好的,所以终于找到了 DRF Docs. The issue was that in case of normal ViewSet you have to override the method filter_queryset() and return the appropriate queryset accordingly. Then use the queryset under filter_queryset as mentioned by Aman 的解决方案 -
serializer = PostListSerializer(self.filter_queryset(self.get_queryset()), many=True, context={"request": request})
下面是代码,供遇到问题的朋友参考 -
filter_queryset -
def filter_queryset(self, queryset):
filter_backends = (DjangoFilterBackend, )
# Other condition for different filter backend goes here
for backend in list(filter_backends):
queryset = backend().filter_queryset(self.request, queryset, view=self)
return queryset
我一直在尝试使用 django-filters,但对象没有得到过滤。此外,该权限不适用于 partial_update 视图
我有一个视图集,它具有基本操作,例如 - list()、retrieve()、destroy()、partial_update() 和其他一些操作,并尝试对其应用过滤器。
经过一些研究,我发现由于我是通过过滤器创建查询集,所以我将不得不覆盖 get_queryset() 方法。但是,这似乎也不起作用。过滤器是否仅适用于 ModelViewSet 或 ListApiView?
视图集-
class PostViewSet(viewsets.ViewSet):
"""
The Endpoint to list, retrieve, create and delete Posts.
"""
filter_backends = (DjangoFilterBackend, )
# filterset_class = PostFilter
filter_fields = ('pet_age', 'pet_gender', 'breed')
def get_permissions(self):
if self.action == 'partial_update' or self.action == 'update':
permission_classes = [IsPostAuthor, ]
elif self.action == 'create' or self.action == 'destroy':
permission_classes = [IsAuthenticated, ]
else:
permission_classes = [AllowAny, ]
return[permission() for permission in permission_classes]
def get_queryset(self):
return Post.objects.active() # This is implemented via custom Manager
def list(self, request, *args, **kwargs):
"""
Method for Post listing. It can be accessed by anyone.
"""
serializer = PostListSerializer(self.get_queryset(), many=True, context={"request": request})
return Response(serializer.data)
# REST CODE TRUNCATED
权限-
class IsPostAuthor(permissions.BasePermission):
"""
Object-level permission to only allow owners of an object to edit it.
"""
def has_object_permission(self, request, view, obj):
if request.user.is_authenticated:
if view.action in ['partial_update', 'update']:
return obj.user.id == request.user.id
return False
return False
后置过滤器-
class PostFilter(filters.FilterSet):
class Meta:
model = Post
fields = ('pet_age', 'pet_gender', 'breed', )
经理-
class PostManager(models.Manager):
def active(self):
return self.filter(post_status='Active')
任何帮助将不胜感激。
您已经覆盖了列表方法,因此无法调用 filter_queryet 方法。
def list(self, request, *args, **kwargs):
"""
Method for Post listing. It can be accessed by anyone.
"""
serializer = PostListSerializer(self.filter_queryset(self.get_queryset()), many=True, context= .
{"request": request})
return Response(serializer.data)
好的,所以终于找到了 DRF Docs. The issue was that in case of normal ViewSet you have to override the method filter_queryset() and return the appropriate queryset accordingly. Then use the queryset under filter_queryset as mentioned by Aman 的解决方案 -
serializer = PostListSerializer(self.filter_queryset(self.get_queryset()), many=True, context={"request": request})
下面是代码,供遇到问题的朋友参考 -
filter_queryset -
def filter_queryset(self, queryset):
filter_backends = (DjangoFilterBackend, )
# Other condition for different filter backend goes here
for backend in list(filter_backends):
queryset = backend().filter_queryset(self.request, queryset, view=self)
return queryset