如何在 DRF 中为 read_only 和 write_only 使用不同的同名序列化器?

Mic*_*ter 5 django serialization django-rest-framework

在 DRF 的 CreateAPI 中创建 Django 对象后,您将获得状态 201 创建,并且该对象将使用与创建 Django 对象相同的序列化器返回。

需要:创建时:Serializer.comments = Textfield(write_only=True) 和创建时(201状态)Serializer.comments = 评论列表

我知道可以通过重写 CreateAPIView.create 函数来实现。但是,我想知道是否可以通过使用序列化器字段的write_only=True属性read_only=True来实现。

目前我认为这是不可能的,因为他们都有相同的名字。我希望使用假 kwarg 名称做这样的事情actual_name

class CreateEventSerializer(serializers.ModelSerializer):
    comments_readonly = serializers.SerializerMethodField(read_only=True, actual_name='comments')

class Meta:
    model = Event
    fields = ('id', 'comments', 'comments_readonly')

def __init__(self, *args, **kwargs):
    super(CreateEventSerializer, self).__init__(*args, **kwargs)
    self.fields['comments'].write_only = True

def get_comments_readonly(self, obj):
    comments = obj.comments.replace('\r', '\n')
    return [x for x in comments.split('\n') if x != '']
Run Code Online (Sandbox Code Playgroud)

但这样,返回的 JSON 仍然包含键“comments_readonly”,而不是所需的键“comments”。

使用最新的DRF,3.7.1

换句话说:是否可以创建一个基于读取和写入而表现不同的序列化器字段(仅使用 1 个序列化器类)?

Mic*_*ter 1

这似乎可以解决 JSON 响应的问题,但感觉有点 hacky,因为 DRF HTML 表单现在在注释文本区域字段中显示一个 python 列表。

class CreateEventSerializer(serializers.ModelSerializer):

    class Meta:
        model = Event
        fields = ('id', 'comments')

    def get_comments(self, obj):
        comments = obj.comments.replace('\r', '\n')
        return [x for x in comments.split('\n') if x != '']

    def to_representation(self, instance):
        data = super(CreateEventSerializer, self).to_representation(instance)
        data['comments'] = self.get_comments(instance)
        return data
Run Code Online (Sandbox Code Playgroud)