如何在 Django REST 框架中为多对多字段定义“IsOwner”自定义权限?

Posted

技术标签:

【中文标题】如何在 Django REST 框架中为多对多字段定义“IsOwner”自定义权限?【英文标题】:How to define a 'IsOwner' custom permission for a many-to-many field in Django rest framework? 【发布时间】:2021-09-19 14:15:53 【问题描述】:

我是 Django 的新手,尤其是 Django-rest-framework。 所以在我的这个项目练习中。 我想要一个对象级别的权限,一个 IsOwner 自定义权限,其中 只有作者可以修改它。

我的模型如下所示:

#imports

class Book(models.Model):

    title = models.CharField(max_length=100)
    description = models.CharField(max_length=400)
    publisher = models.CharField(max_length=400)
    release_date = models.DateField()
    authors = models.ManyToManyField('Author', related_name='authors', blank=True)

    def __str__(self):
        return self.title
    
    

class Author(models.Model):

    user= models.ForeignKey(
        User, on_delete=models.CASCADE, default=1)
    biography  = models.TextField()
    date_of_birth = models.DateField()
    #books = models.ManyToManyField('Book', related_name='authors', blank=True)

    def __str__(self):
        return self.user.username

这是序列化器

#imports here

class BookSerializer(serializers.ModelSerializer):
    
    class Meta:
        ordering = ['-id']
        model = Book
        fields = ("id", "title", "description", "publisher", "release_date", "authors")
        extra_kwargs = 'authors': 'required': False

class AuthorSerializer(serializers.ModelSerializer):
    books = BookSerializer(many=True, read_only=True)
    class Meta:
        ordering = ['-id']
        model = Author
        fields = ("id", "user", "biography", "date_of_birth", "books")
        extra_kwargs = 'books': 'required': False

views.py是这样的:

#imports here

class IsAnAuthor(BasePermission):
    message = 'Editing book is restricted to the authors only.'

    def has_object_permission(self, request, view, obj):
        
        if request.method in SAFE_METHODS:
            return True
        # I need to filter who can only edit book in this part but
        # obj.authors when print is none
        return obj.authors == request.user

class BookViewSet(viewsets.ModelViewSet):
    """
    List all workkers, or create a new worker.
    """
    permission_classes=[IsAnAuthor]
    queryset = Book.objects.all()
    serializer_class = BookSerializer
    filter_backends = [filters.OrderingFilter]
    ordering_fields = ['release_date']

class AuthorViewSet(viewsets.ModelViewSet):
    """
    List all workers, or create a new worker.
    """
    #permission_classes=[IsAuthenticatedOrReadOnly]
    queryset = Author.objects.all()
    serializer_class = AuthorSerializer

我想要实现的是与作者和书籍的多对多关系,并对其实施自定义所有者权限。

【问题讨论】:

怎么样:return obj.authors.filter(id=request.user.id).exists() 或类似的东西。 obj.authors 是关系名称对吗?因此需要使用查询集进行检查,而不是与== 进行比较。 self.request.user 是一个用户实例 第一个确实返回了一些东西,但我仍然需要修复我的模型,我将覆盖默认用户模型并将其用作作者表。非常感谢您的帮助。 【参考方案1】:

我认为应该是这样的:

class IsAnAuthor(BasePermission):
    message = 'Editing book is restricted to the authors only.'

    def has_object_permission(self, request, view, obj):
        
        if request.method in SAFE_METHODS:
            return True
        # I need to filter who can only edit book in this part but
        # obj.authors when print is none
        if request.user in obj.authors :
            return True

        return False

【讨论】:

您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center。

以上是关于如何在 Django REST 框架中为多对多字段定义“IsOwner”自定义权限?的主要内容,如果未能解决你的问题,请参考以下文章

在 Django 中为多对多字段冲突反向访问器和查询?

如何在 Rails 中为多对多关系(和中间表)做一个选择字段?

如何使用 django rest 框架保存多对多字段对象

如何在 Django 中向多对多关系中添加字段?

如何在 Rails 4.2 中为多对多关联创建表单

如何在 Rails 4 中为多对多关联制作带有子表单的表单?