[英]How can I set permission for seperate request methods in DRF ModelViewSet?
I'm fairly new to Django and Django Rest Framework and I can't figure out why my code isn't working.我对 Django 和 Django Rest 框架相当陌生,我不知道为什么我的代码不起作用。 I have a Biz model that has a few fields:
我有一个 Biz model 有几个字段:
class Biz(models.Model):
uuid = models.UUIDField(default=uuid.uuid4, editable=False)
title = models.CharField(max_length=200)
description = models.TextField()
address = models.CharField(max_length=255, blank=True)
city = models.CharField(max_length=100)
phone = PhoneNumberField()
which I serializer using ModelSerializer:我使用 ModelSerializer 进行序列化:
class BizSerializer(serializers.ModelSerializer):
class Meta:
model = Biz
fields = "__all__"
And I use ModelViewSet to have an endpoint for it:我使用 ModelViewSet 为其设置一个端点:
class BizViewSet(viewsets.ModelViewSet):
queryset = Biz.objects.all()
authentication_classes = (authentication.TokenAuthentication,)
permission_classes = [HasGroupPermission]
required_groups = {
"GET": ["__all__"],
"POST": ["member", "biz_post"],
"PUT": ["member", "biz_edit"],
"PATCH": ["member", "biz_edit"],
}
serializer_class = BizSerializer
You probably noticed HasGroupPermission
.您可能注意到
HasGroupPermission
。 It is a custom permission I made to confirm the requesting user is in required group(s) the code is:这是我确认请求用户在所需组中的自定义权限,代码为:
def is_in_group(user, group_name):
"""
Takes a user and a group name, and returns `True` if the user is in that group.
"""
try:
return Group.objects.get(name=group_name).user_set.filter(id=user.id).exists()
except Group.DoesNotExist:
return None
class HasGroupPermission(permissions.BasePermission):
"""
Ensure user is in required groups.
"""
def has_permission(self, request, view):
# Get a mapping of methods -> required group.
required_groups_mapping = getattr(view, "required_groups", {})
# Determine the required groups for this particular request method.
required_groups = required_groups_mapping.get(request.method, [])
# Return True if the user has all the required groups or is staff.
return all(
[
is_in_group(request.user, group_name)
if group_name != "__all__"
else True
for group_name in required_groups
]
) or (request.user and request.user.is_staff)
However, when I make a GET request, the permission function works like it's supposed to and allows everyone to make the request, and when i make a POST request, the permission function also works perfectly (if user isn't in both "member" and "biz_post" groups the request is denied).但是,当我发出 GET 请求时,权限 function 就像它应该的那样工作并允许每个人发出请求,当我发出 POST 请求时,权限 function 也可以正常工作(如果用户不在两个“成员”中和“biz_post”分组请求被拒绝)。 The problem arises when I try other methods such as PUT, PATCH, and DELETE.
当我尝试 PUT、PATCH 和 DELETE 等其他方法时,就会出现问题。 Why is this issue happening?
为什么会出现这个问题? Half the methods work and the other half (sorta) don't.
一半的方法有效,而另一半(排序)则无效。 My knowledge in DRF is limited at the moment, and I can't seem to solve the issue.
目前我对 DRF 的了解有限,似乎无法解决问题。
I realized my problem which I found very silly.我意识到我觉得很愚蠢的问题。 My BizViewSet is actually a ViewSet and I didn't realize that I have to make PATCH, PUT, and DELETE requests to the object link (as in localhost:8000/api/biz/$id).
我的 BizViewSet 实际上是一个 ViewSet,我没有意识到我必须对 object 链接(如 localhost:8000/api/biz/$id)发出 PATCH、PUT 和 DELETE 请求。 Since my User serializer isn't a ViewSet I thought the patch method works the same way which was I pass a primary key in JSON along with the data I wanted to patch but ViewSets are different and I didn't know that.
由于我的用户序列化程序不是 ViewSet,我认为补丁方法的工作方式与我传递 JSON 中的主键以及我想要修补的数据的方式相同,但 ViewSet 不同,我不知道。 Silly.
愚蠢的。
Hi you can use DjangoModelPermissions instead of HasGroupPermission嗨,您可以使用 DjangoModelPermissions 而不是 HasGroupPermission
(at the first you must import it) (首先你必须导入它)
from rest_framework.permissions import DjangoModelPermissions
This permission check that user have permission for PUT, POST and DELETE此权限检查用户是否具有 PUT、POST 和 DELETE 权限
All user have GET permission所有用户都有 GET 权限
You must set permission for user in admin or set permission for group of user您必须在管理员中为用户设置权限或为用户组设置权限
I hope it helps you希望对你有帮助
has_permission
method not provide object-level
permission and PUT
and PATCH
need object-level
permission. has_permission
方法不提供object-level
权限, PUT
和PATCH
需要object-level
权限。
You must create object-level
permissions, that are only run against operations that affect a particular object instance by using has_object_permission
method of permissions.BasePermission
class.您必须创建
object-level
权限,这些权限仅针对影响特定 object 实例的操作运行,方法是使用permissions.BasePermission
class 的has_object_permission
方法。
Hope it helped.希望它有所帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.