【问题标题】:Inheritance of permission between the related models in DRFDRF中相关模型之间的权限继承
【发布时间】:2019-03-05 03:14:48
【问题描述】:

我有 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 继承权限。

【问题讨论】:

  • 可以添加IsCurrentUserOwnerOrReadOnly权限类吗?
  • 我想过这个,但它也有更大的缺陷。因为用户首先创建一个帖子,然后一个一个地添加图像,这意味着图像的所有者是创建图像的人,而不是创建propertpost的人。我想说的是在创建图像时,因为每个人都对其他人的帖子具有只读权限,因此他们可以将图像分配给任意帖子。 IsCurrentUserOwnerOrReadOnly 唯一的好处是,一旦创建了它,就没有人可以编辑/删除它。它不保证图像是为所有者的同一个帖子。
  • 如果没有所有者字段,如何识别图像的所有者?
  • 我复制了你的答案,看起来很接近。 request.user == obj.prop_post.owner 差不多。 request.user 是尝试添加图片的人,而 obj.prop_post.owner 是帖子的所有者。也许我需要图片的所有者,因为目前状态仍在添加图片
  • 这就是我要问的,你怎么能得到imahe的主人?

标签: django django-rest-framework


【解决方案1】:

好的,希望有更简单的解决方案,但这是我解决它的方法。我在这里尝试不为图像模型创建所有者,因为图像模型将 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 的所有者。

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

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)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-28
    • 1970-01-01
    • 2016-08-30
    相关资源
    最近更新 更多