我在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
然后,我试图定义一个可以在所有ModelViewSet中使用的权限。我希望它具有一定的动态性,因为我拥有的模型要多于与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
对象上没有所有者字段。但是,我想如果我在序列化程序中有一个owner字段(并在每个序列化程序中都放置一个owner字段),我可以用这种方式检索它。任何帮助将不胜感激!
答案 0 :(得分: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