简体   繁体   English

如何在 DRF ModelViewSet 中为单独的请求方法设置权限?

[英]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权限, PUTPATCH需要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方法。

See this link .请参阅此链接

Hope it helped.希望它有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM