如何定义外键关系对象级权限

问题描述 投票:0回答:1

我在定义我的ModelViewSet外键关系对象级权限的麻烦。我不知道这是否是完全有可能是我想要做的,或者如果有一个更好的解决方案,但在正确的方向任何暗示将不胜感激。我已经缩短了型号和序列化的简洁起见。

我有以下型号:

class Team(models.Model):
    name = models.CharField(max_length=50)

class CustomUser(AbstractUser):
    teams = models.ManyToManyField(Team)

class Client(models.Model):
    name = models.CharField(max_length=50)
    owner = models.ForeignKey(Team, on_delete=models.CASCADE)

class FinancialAccount(models.Model):
    account_name = models.CharField(max_length=50)
    client = models.ForeignKey(Client, on_delete=models.CASCADE)

然后,我有以下串行:

class ClientSerializer(serializers.ModelSerializer):
    class Meta:
        model = Client
        fields = ('name', 'owner')

class FinancialAccountSerializer(serializers.ModelSerializer):
    owner = serializers.SerializerMethodField()

    class Meta:
        model = FinancialAccount
        fields = ('name', 'client', 'owner')

    def get_owner(self, obj):
        return client.owner.name

然后我试图定义我可以在我所有的ModelViewSets的使用许可。我想这是有些动态,因为我有很多比上面那些都是Client甚至低于FinancialAccount相关的多个模型。权限和视图集中如下:

class IsOwnerTeam(permissions.BasePermission):
    def has_object_permission(self, request, view, obj):
        teams = request.user.teams.values_list('name', flat=True)
        return obj.owner in teams

class FinancialAccountViewSet(viewsets.ModelViewSet):
    serializer_class = FinancialAccountSerializer
    permission_classes = (IsOwnerTeam, )

    def get_queryset(self):
        teams = self.request.user.teams.all()
        clients = Client.objects.filter(owner__in=teams)
        return FinancialAccount.objects.filter(account__in=accounts)

所以,现在我收到此错误:'FinancialAccount' object has no attribute 'owner',这是有道理的,因为我没有FinancialAccount对象的所有者字段。但是,我想,如果我在串行所有者场(放所有者场在每个序列化的)我能找回这种方式。任何帮助,将不胜感激!

django permissions django-rest-framework serializer
1个回答
0
投票

你可以这样做:

class IsOwnerTeam(permissions.BasePermission):
    def has_object_permission(self, request, view, obj):
        if hasattr(obj, 'client'):
            owner = obj.client.owner
        else:
            owner = obj.owner
        teams = request.user.teams.values_list('name', flat=True)
        return owner in teams
© www.soinside.com 2019 - 2024. All rights reserved.