Django Rest Framework 中的对象权限

问题描述

我正在尝试使用 Django Rest Framework 和对象权限来做一些看起来很简单的事情,但似乎没有一种简单的方法解决它。

以下是我正在谈论的(简化的)模型:-

class Team(models.Model):
    owner = models.ForeignKey(settings.AUTH_USER_MODEL,on_delete=models.CASCADE)

class Player(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL,on_delete=models.CASCADE)
    team = models.ForeignKey(Team,on_delete=models.CASCADE)

class Invitation(models.Model):
    team = models.ForeignKey(Team,on_delete=models.CASCADE)

我想:-

a) 允许任何经过身份验证的用户创建团队,但禁止任何人 但该用户无法更改或删除该团队 b) 允许该球队的任何球员为该球队创建邀请,但不允许任何人 否则能够

我决定使用 DjangoObjectPermissions 来实现 a).

所以我的第一个问题似乎是,为了允许任何人创建团队,我需要给所有用户 add_team 权限,这对我来说似乎有点不必要。然后,我需要授予我在该团队上创建 view_team 权限的任何“普通”玩家,但只有所有者才能获得该团队的 change_team 和 delete_team 权限。哪个没问题。

但更大的问题是当我尝试为邀请模型制定权限时。

我无法为特定团队的用户授予 add_invitation 权限,因为在团队对象上没有名为 add_invitation 的权限。 (顺便说一句,add_invitation 在应用于特定邀请时意味着是什么?!)那么我如何将可以为团队创建邀请的用户限制为该团队中的用户?我是否使用 view_team 权限并假设“如果您拥有 view_team 权限,您可以为该团队创建邀请”?

这对我来说似乎不对,但我想不出更好的方法

解决方法

好吧,我对 django-guardian 了解不多,但如果你想

允许任何经过身份验证的用户创建团队

创建不是对象级权限,因为还没有对象。

阻止除该用户之外的任何人更改或删除该团队

对我来说听起来像是普通的 DRF 权限。将此用于 permission_classes 中的 viewset

class TeamPermission(BasePermission):
    def has_permission(self,request,view) -> bool:
        return request.user and request.user.is_authenticated

    def has_object_permission(self,view,obj) -> bool:
        if request.method in SAFE_METHODS:
            return True
        return obj.owner == request.user

允许该团队的任何玩家为该团队创建邀请,但其他人不能

这是您在序列化程序中所做的事情。

class CreateInvitationSerializer(serializers.ModelSerializer):
    class Meta:
        model = Invitation
        fields = ['id','team']
        
    def validate_team(self,team):
        request = self.context['request']
        user = request.user
        # even if it's working you will probably have to adjust a few things
        # but that's the way it can be done
        if not team.player_set.filter(user=user).exists():
            raise serializers.ValidationError("blah")
        return team