如何从视图中分配DRF序列化程序只读字段

2024-04-16 21:03:43 发布

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

示例代码

# models.py
class Profile(models.Model):
    first_name = models.CharField(max_length=64)
    last_name = models.CharField(max_length=64)
    ...

class Photo(models.Model):
    image = models.ImageField(upload_to='photos')
    profile = models.ForeignKey('Profile', on_delete=models.CASCADE, related_name='photos')
    ...

# serializers.py
class ProfileSerializer(serializers.ModelSerializer):
    photos = serializers.HyperlinkedRelatedField(many=True, view_name='photo-detail', read_only=True)

    class Meta:
        model = Profile
        fields = '__all__'

class PhotoSerializer(serializers.ModelSerializer):
    # How to assign this implicitly from view?
    profile = PrimaryKeyRelatedField(read_only=True)

    class Meta:
        model = Face
        fields = '__all__'

我的解决方案

# views.py
class ProfileViewSet(viewsets.ModelViewSet):
    queryset = Profile.objects.all()
    serializer_class = ProfileSerializer

    @action(methods=['GET', 'POST'], detail=True, serializer_class=FaceSerializer)
    def photos(self, request, *args, **kwargs):
        profile = self.get_object()
        if request.method == 'GET':
            ...
        elif request.method == 'POST':
            serializer = self.get_serializer(data=request.data)
            serializer.is_valid()
            # accessing validated_data
            # explicitly set profile read_only field
            serializer.validated_data['profile'] = profile
            self.perform_create(serializer)
            return Response(serializer.data)

示例呼叫

curl -X POST http://localhost:8000/profiles/4/photos/ --form image=@photo_image.jpg

预期行为

HTTP 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 123,
    "profile": 4,
    "image": "http://localhost:9000/media/photos/photo_image.jpg",
    ....
}

将照片图像传递到端点/profile/<int:pk>/photos/时,照片的(read_only=True)配置文件字段已由提取的<int:pk>视图参数设置

问题

有没有更优雅的方法来实现这一点?我对访问serializer.validated_data并显式设置配置文件值感到不舒服


Tags: nameimageselftrueonlyreaddatamodels
1条回答
网友
1楼 · 发布于 2024-04-16 21:03:43

在序列化程序的save()方法中传递profile值,如下所示

...
elif request.method == 'POST':
    serializer = self.get_serializer(data=request.data)
    serializer.is_valid()
    serializer.save(profile=profile)
    return Response(serializer.data)

相关问题 更多 >