django REST API在序列化程序中填充creator_id以用于权限

58wvjzkj  于 2022-12-20  发布在  Go
关注(0)|答案(1)|浏览(46)

我如何在Post请求中填充creator_id,并在权限中使用它?我曾尝试在视图中这样做,并在创建者的列中生成id。但对于权限,它不起作用,因此不允许我删除自己的注解。然后我被告知将此操作移动到serializers.py。目前我有:
Models.py

class Note(models.Model):
    class NoteTypes(models.TextChoices):
        POST = "Post"
        IDEA = "Idea"

    category = models.CharField(
        max_length=4, choices=NoteTypes.choices, default=NoteTypes.POST
    )
    creator = models.CharField(max_length=100)
    content = models.TextField(max_length=500)
    created_date = models.DateTimeField(auto_now_add=True)
    updated_date = models.DateTimeField(auto_now=True)
    uuid = models.UUIDField(default=uuid.uuid4, blank=True, primary_key=True)

    def __str__(self):
        return self.content

    class Meta:
        ordering = ["created_date"]

Views.py

class NotesList(APIView):
    @staticmethod
    def get(request):
        notes = Note.objects.all()
        serializer = NoteSerializer(notes, many=True)
        return Response(serializer.data)

    def post(self, request, format=None):
        serializer = NoteSerializer(data=request.data)
        request.data["creator"] = request.user.id   <------
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        else:
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

Serializers.py

class NoteSerializer(serializers.ModelSerializer):
    creator = serializers.ReadOnlyField(source="creator.id")

    class Meta:
        model = Note
        fields = ["uuid","category", "creator", "content", "created_date", updated_date]

Permissions.py

class IsCreatorOrReadOnly(BasePermissions):
        def has_object_permission(self, request,view,obj):
            if request.method in permissions.SAFE_METHODS:
                return True

            return obj.creator.id == request.user.id

我试过在views.pycreator字段中填充创建者的id,它起作用了,例如"creator": "2",但是我无法删除或更新注解。我目前正在尝试将此操作移动到serializers.py以自动填充此字段。

1yjd4xko

1yjd4xko1#

首先要做的是使creator字段引用user模型中的外键:

# other imports .....
# import user model if it's not in the same app

class Note(models.Model):
    class NoteTypes(models.TextChoices):
        POST = "Post"
        IDEA = "Idea"

    category = models.CharField(
        max_length=4, choices=NoteTypes.choices, default=NoteTypes.POST
    )
    creator = models.ForeignKey(User, on_delete=models.CASCADE) # new 
    content = models.TextField(max_length=500)
    created_date = models.DateTimeField(auto_now_add=True)
    updated_date = models.DateTimeField(auto_now=True)
    uuid = models.UUIDField(default=uuid.uuid4, blank=True, primary_key=True)

    def __str__(self):
        return self.content

    class Meta:
        ordering = ["created_date"]

然后在你的serializers.py中,我注意到有一个字段不在" "中。所以如下所示修复它。除此之外,其他一切看起来都很好。

class NoteSerializer(serializers.ModelSerializer):
    creator = serializers.ReadOnlyField(source="creator.id")

    class Meta:
        model = Note
        fields = ["uuid", "category", "creator", "content", "created_date", "updated_date"]

现在,我们将通过重写perform_create()方法,将每个注解绑定到其在views.py中的创建者,并检查权限:

from rest_framework import generics

class NotesList(generics.ListCreateAPIView):
    queryset = Note.objects.all()
    serializer_class = NoteSerializer

    permission_classes = [IsCreatorOrReadOnly]

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

对于permissions.py

from rest_framework import permissions

class IsCreatorOrReadOnly(permissions.BasePermission):
        def has_object_permission(self, request,view,obj):
            if request.method in permissions.SAFE_METHODS:
                return True

            return obj.creator == request.user #new

相关问题