Skip to main content
 首页 » 编程设计

python之Django 休息框架 : get_FOO_display in serializer not letting me POST

2025年01月19日38zhenyulu

我最近在我的序列化程序中添加了一个 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 在我的 views.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__') 

请您参考如下方法:

为此,您需要自定义序列化程序字段。

这是 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,所以并不是所有的自动文档引擎都能正确检测到选择,尽管它工作得很好。

您可能还喜欢 https://github.com/encode/django-rest-framework/issues/1755