DRF中相关模型之间的权限继承

时间:2019-03-05 03:14:48

标签: django django-rest-framework

我有3个类似波纹管的模型:

class CustomUser(AbstractUser):
    pass


class PropertyPost(models.Model):
    owner = models.ForeignKey(
        get_user_model(),
        related_name='posts4thisowner',
        on_delete=models.CASCADE)


class Image(models.Model):
    prop_post = models.ForeignKey(
        PropertyPost,
        related_name='images4thisproperty',
        on_delete=models.CASCADE)

这里的想法是用户可以发布许多PropertyPost,而每个PropertyPost可以包含许多图像。

一切正常。我的问题是在许可中。我为PropertyPostDetail视图设置了一组权限,但对ImageDetail视图没有设置权限:

class PropertyPostDetail(generics.RetrieveUpdateDestroyAPIView):
 ...
    permission_classes = (
        permissions.IsAuthenticatedOrReadOnly,
        custompermission.IsCurrentUserOwnerOrReadOnly,
        )

class ImageList(generics.ListCreateAPIView):
    queryset = Image.objects.all()
    serializer_class = ImageSerializer
    name = 'image-list'

class ImageDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = Image.objects.all()
    serializer_class = ImageSerializer
    name = 'image-detail'

这意味着只有帖子所有者才能弄乱其帖子。

现在,因为图像模型用于PropertyPost,所以我希望该权限也可以延续到图像上。但是显然,任何用户都可以编辑任何图像,这显然是一个缺陷。 我的问题是如何设置图像视图从其父对象PropertyPost继承权限。

1 个答案:

答案 0 :(得分:0)

好的,希望能有更简单的解决方案,但这是我解决的方法。我在这里尝试不为图像模型创建所有者,因为图像模型具有PropertyPost作为其父级,该父级具有所有者。因此,Image应该继承该所有者:

class Image(models.Model):

    prop_post = models.ForeignKey(
        PropertyPost,
        related_name='images4thisproperty',
        on_delete=models.CASCADE)
    prop_post_owner=models.CharField(max_length=150,null=True,blank=True)

这将是序列化器:

class ImageSerializer(serializers.HyperlinkedModelSerializer):
    prop_post = serializers.SlugRelatedField(queryset=PropertyPost.objects.all(),
                                             slug_field='pk')
    prop_post_owner = serializers.ReadOnlyField(source='prop_post.owner.username')
    class Meta:
        model = Image
        fields = (
            'pk',
            'url',
            'prop_post',
            'prop_post_owner'
       )

这样,我的图像模型就有了一个来自PropertyPost的所有者。

现在,在列表级别,用户可以创建一个对象,并且由于尚不清楚用户将选择哪个对象,因此自定义权限将失败。最后,这就是我防止非所有者为属性创建图像字段的方法:

class ImageList(generics.ListCreateAPIView):
    queryset = Image.objects.all()
    serializer_class = ImageSerializer
    name = 'image-list'
    ....
    def perform_create(self, serializer):
        obj=PropertyPost.objects.get(pk=int(self.request.data['prop_post']))
        if self.request.user!=obj.owner:
            raise ValidationError('you are not the owner')
        serializer.save(prop_post_owner=self.request.user)