DRF:只有作者才能创建或更新图书权限

2024-03-28 11:10:50 发布

您现在位置:Python中文网/ 问答频道 /正文

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

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]

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


Tags: truedbmodelobjectsmodelsrequestusernamelength
1条回答
网友
1楼 · 发布于 2024-03-28 11:10:50

试试这个

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


# views.py
from rest_framework.permissions import IsAuthenticated


class BookViewSet(viewsets.ModelViewSet):
    serializer_class = serializers.BookSerializer
    permission_classes = [IsAuthenticated]

    def get_queryset(self):
        if self.request.method == 'GET':
            return models.Book.objects.all()
        else:
            return models.Book.objects.filter(author=self.request.user)

    def perform_create(self, serializer):
        serializer.save(author=self.request.user)

参考文献 1Specifying read only fields - DRF doc
2^{} method of APIView

相关问题 更多 >