python - Django-filters does not work with the Viewset
问题描述
I have been trying to use django-filters but the objects are not getting filtered. Also, the permission is not working for the partial_update views
I have a Viewset which has the basic actions like - list(), retrieve(), destroy(), partial_update() and few other actions, and trying to apply filter for the same.
After some research I found that since I am creating the queryset via filters I will have to override the get_queryset() method. However, that also doesn't seem to be working. Does the filter works only with ModelViewSet or ListApiView?
ViewSet -
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
Permission -
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
PostFilter -
class PostFilter(filters.FilterSet):
class Meta:
model = Post
fields = ('pet_age', 'pet_gender', 'breed', )
Manager -
class PostManager(models.Manager):
def active(self):
return self.filter(post_status='Active')
Any help will be highly appreciated.
解决方案
好的,所以终于从DRF Docs找到了解决方案。问题是在普通 ViewSet 的情况下,您必须覆盖方法filter_queryset ()并相应地返回适当的查询集。然后使用Aman提到的filter_queryset下的查询集-
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
推荐阅读
- typescript - 在 TypeScript 中,如何定义提供从成员对象返回的值的方法类型?
- html - 使用动态表的静态/粘性标题
- kotlin - 是否需要在 columnInfo 注释中定义名称?
- azure-pipelines - 在每个管道运行中在 Blob 存储中创建和保存新文件
- mysql - Vert.x (Kotlin) 中使用的 MySQLPool
- scala - 如何获得具有下限的 Class[_ <: A]]
- c# - Open Generic的IEnumerable的依赖注入
- javascript - react setState似乎被redux调度取消了?
- javascript - 在 javascript 中,如何将变量用作对象属性名称的一部分
- dc.js - 在箱线图 dc.js 上显示包含数据的交互式工具提示,而不是工具提示标题数据