首页 > 解决方案 > DRF:只有作者可以创建或更新图书权限

问题描述

所以,我有两个简单的模型:

class User(AbstractUser, models.Model):
    username = models.CharField(
        'Username', max_length=255,
        db_index=True, unique=True
    )
    email = models.EmailField(
        'Email', max_length=255, db_index=True,
        blank=True, null=True, unique=True
    )

    objects = UserManager()

    USERNAME_FIELD = 'username'
    REQUIRED_FIELDS = ('email', 'password',)


class Book(models.Model):
    title = models.CharField(max_length=255)
    author = models.ForeignKey(User, on_delete=models.CASCADE)

和这样的序列化程序:

class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Book
        fields = ['title', 'author']

    def validate_author(self, author): # < --- it doesn't work
        if author != serializers.CurrentUserDefault():
            raise serializers.ValidationError(
                'You cant update other authors book'
            )


    author = serializers.PrimaryKeyRelatedField(
        default=serializers.CurrentUserDefault(),
        queryset=models.User.objects.all()
    )

以及具有一些权限的视图:

class IsAuthorOrReadOnly(permissions.BasePermission):

    def has_object_permission(self, request, view, obj):
        if request.method in permissions.SAFE_METHODS:
            return True
        return obj.author == request.user


class BookViewSet(viewsets.ModelViewSet):
    queryset = models.Book.objects.all()
    serializer_class = serializers.BookSerializer
    permission_classes = [IsAuthenticatedOrReadOnly & IsAuthorOrReadOnly]

那么,如何确保用户可以获得所有书籍,但不能创建或更新不属于他的书籍?

标签: pythondjangodjango-rest-framework

解决方案


如果您想允许经过身份验证的用户有请求并且只有作者对和SAFE_METHODS有额外的权限,则此代码可能很有用。未经身份验证的用户甚至没有任何权限。当然,您应该使用视图中的继承类。PUTDELETEGETgenerics.RetrieveUpdateDestroyAPIView

class IsAuthorOrIsAuthenticated(permissions.BasePermission):

def has_object_permission(self, request, view, obj):
    if request.method in permissions.SAFE_METHODS:
        return bool(request.user and request.user.is_authenticated)
    return obj.author == request.user

对我来说有趣的部分是匿名用户没有任何权限,但GET OPTIONS PUTDELETE按钮可用!(但是这些按钮对他/她不起作用!)

如果有人告诉我应该怎么做才能删除匿名用户的按钮,我将不胜感激。

我将在此处附上我的在线项目以查看结果...


推荐阅读