【问题标题】:How to assign DRF serializer read_only fields from views如何从视图中分配 DRF 序列化程序只读字段
【发布时间】:2020-04-19 15:05:36
【问题描述】:

示例代码

# 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 并明确设置配置文件值感到不舒服...

【问题讨论】:

    标签: python django django-rest-framework


    【解决方案1】:

    在序列化器的save()方法中传递profile值,如

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-24
      • 2019-02-19
      • 2018-04-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多