Django Rest Framework:序列化程序中的get_FOO_display不允许我发布

时间:2017-12-10 21:04:16

标签: python django django-rest-framework

我最近在我的序列化程序中添加了source='get_fieldname_display。它完美地用于获取choices元组的显示值,但现在我无法再使用API​​端点POST数据而不会出现错误:

TypeError: 'get_fieldname_display' is an invalid keyword argument for this function

要明确的是,序列化程序的添加特别是这一行:

fieldName = serializers.CharField(source='fieldName_display')

我知道这一行导致了问题,因为当我发表评论时,我可以毫无问题地发布数据。但是,我需要这一行,所以当我获取数据时,我可以从choices元组中获取显示名称。

我认为如果我使用两个不同的序列化程序可能会解决问题,一个用于GET,另一个用于POST,但我不知道如何执行此操作 - 我在我的视图中使用generics.ListCreateAPIView的.py。

编辑:

我的模型看起来像这样:

class MakeObjects(models.Model):

    FIELD_NAME_CHOICES = (
        ("01", "Choice 1"), 
        ("02", "Choice 2"), 
    )

    fieldname = CharField(choices = FIELD_NAME_CHOICES)

我的序列化器看起来像这样:

class ObjectSerializer(serializers.ModelSerializer): 
       fieldname = serializers.CharField(source='get_fieldname_display')
       class Meta:
           model = MakeObjects
           fields = ('__all__')

2 个答案:

答案 0 :(得分:1)

要实现这一点,您需要自定义序列化器字段。

这是python 3的片段:

class DisplayNameWritableField(serializers.ChoiceField):
    def __init__(self, **kwargs):
        self.html_cutoff = kwargs.pop('html_cutoff', self.html_cutoff)
        self.html_cutoff_text = kwargs.pop('html_cutoff_text', self.html_cutoff_text)

        self.allow_blank = kwargs.pop('allow_blank', False)
        super(ChoiceField, self).__init__(**kwargs)

    def to_representation(self, value):
        return self.choices.get(value, value)

    def bind(self, field_name, parent):
        super().bind(field_name, parent)
        self.choices = parent.Meta.model._meta.get_field(field_name).choices

然后:

class YourModelSerializer(serializers.ModelSerializer):
    your_choiced_model_field = DisplayNameWritableField()

虽然这有点像hacky,所以并非所有的auto-docs引擎都能正确检测到选择,即使这种方法效果很好。

您可能也想https://github.com/encode/django-rest-framework/issues/1755

答案 1 :(得分:0)

您可以尝试在以下位置添加新字段:

read_only_fields = ['fieldName']