【问题标题】:How to have different serializers for read_only & write_only with the same name in DRF?如何在 DRF 中为 read_only 和 write_only 使用相同名称的不同序列化程序?
【发布时间】:2025-11-24 14:35:01
【问题描述】:

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

通缉: 创建:Serializer.cmets = Textfield(write_only=True) 并在创建(201 状态)Serializer.cmets = 评论列表

我知道可以通过重写 CreateAPIView.create 函数来实现。 但是,我想知道是否可以通过将write_only=Trueread_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 != '']

但是这样一来,返回的 JSON 仍然包含键“cmets_readonly”而不是想要的键“cmets”。

使用最新的 DRF,3.7.1

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

【问题讨论】:

    标签: django django-rest-framework serialization


    【解决方案1】:

    这似乎对 JSON 响应起到了作用,但感觉有点 hacky,因为 DRF HTML 表单现在在 cmets textarea 字段中显示一个 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
    

    【讨论】:

      最近更新 更多