提问人:Mario Berg 提问时间:11/16/2023 更新时间:11/16/2023 访问量:19
我的 Django 端点无法访问 has_object_permission 方法
My Django endpoint does not access the has_object_permission method
问:
这是我有一个视图类:
from rest_framework.views import APIView
class MyView(APIView):
permission_classes = [CustomAccessPermission]
def get(self, request, id: int) -> Response:
object = get_object_or_404(MyObjectClass, id)
serializer = MySerializer(object)
return Response(serializer.data)
def delete(self, request, id: int):
object = get_object_or_404(MyObjectClass, id)
object.status = MyObjectClass.Status.DELETED
object.save()
return Response(status=status.HTTP_200_OK, data=id)
这是我的自定义访问权限类:
from rest_framework import permissions
from django.core.exceptions import PermissionDenied
class CustomAccessPermission(permissions.BasePermission):
message = "You cannot access objects created by other users."
def has_object_permission(self, request, view, obj):
if obj.user_id != request.user.id:
raise PermissionDenied(self.message)
return True
因此,在我的对象中,我存储了包含创建此对象的用户 ID 的user_id。我想检查请求中的id是否等于该user_id,如果用户可以看到此对象。因此,例如,当我运行 GET:http://localhost:8050/api/objects/4 时,我想获取 id=4 的对象user_id,如果它等于 request.user.id 那么我们将允许用户看到它,否则我们应该拒绝。与 DELETE 请求相同,应首先根据对象的user_id检查它们。
上面的这段代码不起作用,它无法访问我的权限类中的 has_object_permission() 方法。 我应该修改什么?
答:
1赞
willeM_ Van Onsem
11/16/2023
#1
它不是因为你自己实现,并使用一个.就像 Django 的一样,an 只实现了处理 API 请求的视图的基础知识。它有一个可以检查对象权限的权限,但您需要自己执行此操作。get
delete
APIView
View
APIView
.check_object_permissions(…)
这就是为什么人们几乎总是从提供更多功能开始的原因。事实上GenericAPIView
from rest_framework.views import GenericAPIView
class MyView(GenericAPIView):
permission_classes = [CustomAccessPermission]
queryset = MyObjectClass.objects.all()
serializer_class = MySerializer
lookup_url_kwarg = 'id'
def get(self, request, id: int) -> Response:
object = self.get_object()
serializer = MySerializer(object)
return Response(serializer.data)
def delete(self, request, id: int):
object = self.get_object()
object.status = MyObjectClass.Status.DELETED
object.save()
return Response(status=status.HTTP_200_OK, data=id)
但是,我们仍然可以减少样板代码的数量,并让 Django REST 框架自己实现方法:
from rest_framework.generics import RetrieveDestroyAPIView
class MyView(RetrieveDestroyAPIView):
permission_classes = [CustomAccessPermission]
queryset = MyObjectClass.objects.all()
serializer_class = MySerializer
lookup_url_kwarg = 'id'
def perform_destroy(self, instance):
instance.status = MyObjectClass.Status.DELETED
instance.save()
就是这样。如果在模型本身上实现“软删除”:即重写 MyObjectClass
本身的方法,则无需重写 。.delete()
perform_destroy
评论
1赞
Mario Berg
11/16/2023
非常感谢您的示例和解释!它帮助我解决了这个问题!
评论
get
delete