问题描述
我正在尝试使用 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