Django REST框架对象级别权限 [英] Django REST framework object level permissions
问题描述
我正在使用Django REST Framework访问资源用户".
I am using Django REST Framework to access a resource 'user'.
由于用户信息是个人信息,因此我不希望GET请求列出系统上的每个用户,除非他们是管理员.
As user information is personal, I do not want a GET request to list every user on the system, UNLESS they are an admin.
如果用户指定了他们的ID并已登录,我希望他们能够查看其详细信息并根据需要进行修改(PUT POST DELETE).
If the user specifies their id, and they are logged in, I would like them to be able to view their details and amend them (PUT POST DELETE) if required.
因此,总而言之,对于不是管理员的任何人都禁止使用GET方法,并且在查看其信息时允许已登录用户的GET POST DELETE PUT.
So in summary, dis-allow GET method for anyone who isn't an admin and allow GET POST DELETE PUT on logged in users when viewing their information.
所以我创建了自定义权限类:
so I created the custom permission class:
class UserPermissions(permissions.BasePermission):
"""
Owners of the object or admins can do anything.
Everyone else can do nothing.
"""
def has_permission(self, request, view):
# if admin: True otherwise False
def has_object_permission(self, request, view, obj):
# if request.user is the same user that is contained within the obj then allow
这不起作用.经过一些调试后,我发现它首先检查has_permission,然后检查has_object_permission.因此,如果我们没有超越第一个障碍GET/user/,那么它甚至都不会考虑下一个GET/user/id.
This didn't work. After some debugging I found that it checks has_permission first, THEN checks has_object_permission. So if we don't get past that first hurdle GET /user/, then it won't even consider the next GET /user/id.
所以总而言之,有人知道我将如何使它正常工作吗?
so In summary, does anyone know how I would go about getting this to work?
谢谢:)
我使用的是ModelViewSets,确实存在我所描述的问题.
I was using ModelViewSets, which do have this problem as I described.
但是,如果您将列表功能与详细信息分开,则可以给他们单独的权限类别:
But if you split the List functionality with the Detail then you can give them separate permission classes:
class UserList(generics.ListCreateAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
permission_classes=(UserPermissionsAll,)
class UserDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
permission_classes=(UserPermissionsObj,)
class UserPermissionsAll(permissions.BasePermission):
"""
Owners of the object or admins can do anything.
Everyone else can do nothing.
"""
def has_permission(self, request, view):
if request.user.is_staff:
return True
else:
return False
class UserPermissionsObj(permissions.BasePermission):
"""
Owners of the object or admins can do anything.
Everyone else can do nothing.
"""
def has_object_permission(self, request, view, obj):
if request.user.is_staff:
return True
return obj == request.user
推荐答案
I have done this in the past using a custom permission and overridden has_object_permission
like the following:
from rest_framework import permissions
class MyUserPermissions(permissions.BasePermission):
"""
Handles permissions for users. The basic rules are
- owner may GET, PUT, POST, DELETE
- nobody else can access
"""
def has_object_permission(self, request, view, obj):
# check if user is owner
return request.user == obj
您可以执行一些更详细的操作,例如拒绝特定的请求类型(例如,允许所有用户执行GET请求):
You can do some more detailed things such as deny specific request types (for instance to allow a GET requests for all users):
class MyUserPermissions(permissions.BasePermission):
def has_object_permission(self, request, view, obj):
# Allow get requests for all
if request.method == 'GET':
return True
return request.user == obj
然后在您的视图中,告诉它使用权限类:
Then in your view you tell it to use the permissions class:
from my_custom_permissions import MyUserPermissions
class UserView(generics.ListCreateAPIView):
...
permission_classes = (MyUserPermissions, )
...
这篇关于Django REST框架对象级别权限的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!