为了账号安全,请及时绑定邮箱和手机立即绑定

允许在 Django Rest Framework 序列化器字段名称中使用连字符

允许在 Django Rest Framework 序列化器字段名称中使用连字符

慕桂英3389331 2021-12-29 20:53:44
鉴于我正在编写代码的 OpenAPI 规范要求在请求正文中使用连字符大小写(又名 kebab-case)变量名称,在使用 Django Rest Framework 时应如何处理?例如,POST /thing创建事物的请求具有以下主体:{    "owner-type": "platform"}但是在Python,owner-type不是有效的变量名(“语法错误:无法分配给经营者”),这样反而Thing有owner_type在模型中定义:class Thing(models.Model):    owner_type = models.CharField(max_length=8)但现在ThingSerializer有问题,因为再次owner-type是一个非法名称。这是不允许的:    owner-type = serializers.CharField(...)我试图ModelSerializer通过尝试调整由 生成的字段名称来覆盖名称的生成方式get_fields(),但它失败了。这是我的序列化程序:class ThingSerializer(serializers.ModelSerializer):    class Meta:        model = Thing        fields = [            'owner_type',        ]    def get_fields(self):        fields = super().get_fields()        out_fields = OrderedDict()        for field_name, field in fields.items():            out_fields[field_name.replace('_', '-')] = field        return out_fields和错误:../venv/lib/python3.6/site-packages/rest_framework/fields.py:453: in get_attribute    return get_attribute(instance, self.source_attrs)../venv/lib/python3.6/site-packages/rest_framework/fields.py:101: in get_attribute    instance = getattr(instance, attr)E   AttributeError: 'Thing' object has no attribute 'owner-type'所以我的问题 - 如何配置 DRF 模型序列化器以允许包含下划线的模型字段被序列化/反序列化,以便 API 客户端看到连字符而不是下划线?这将是上面示例的通用解决方案,其中Thing.owner_type应该通过"owner-type"在 JSON 正文中传递字段来读取/写入。我在 Python 3.6 上使用最新的 Django 和 DRF。编辑 1:澄清理想情况下,这将是将下划线转换为连字符的通用解决方案。
查看完整描述

3 回答

?
幕布斯7119047

TA贡献1794条经验 获得超8个赞

您可以使用连字符定义字段名称,fields并通过定义source属性将其映射到正确的 Django 模型字段extra_kwargs- 请参阅https://www.django-rest-framework.org/api-guide/serializers/#additional-keyword-arguments


要回答您的问题,您定义ThingSerializer如下:


class ThingSerializer(serializers.ModelSerializer):

    class Meta:

        model = Thing

        fields = [

            'owner-type',

        ]

        extra_kwargs = {

            'owner-type': {'source': 'owner_type'},

        }


查看完整回答
反对 回复 2021-12-29
?
沧海一幻觉

TA贡献1824条经验 获得超5个赞

您可以使用to_internal_valueDjango 的(参见 DJango Serializer 字段)来获取带连字符的密钥并重命名它。


例子:


class Thing(models.Model):

    owner_type = models.CharField(max_length=8)

    

    def to_internal_value(self, data):

        data['owner_type'] = data['owner-type']

        data.pop('owner-type', None)

        return data


查看完整回答
反对 回复 2021-12-29
?
斯蒂芬大帝

TA贡献1827条经验 获得超8个赞

这在使用模型时没有用,但回答字段中连字符的使用,更改序列化程序如下



class ThingSerializer(serializers.Serializer):

   def __init__(self, *args, **kwargs):

        super().__init__(*args, **kwargs)

        self.fields.update({"owner-type": serializers.CharField(write_only=True)})


查看完整回答
反对 回复 2021-12-29
  • 3 回答
  • 0 关注
  • 163 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信