【问题标题】:How to serialize a Marshmallow field under a different name如何以不同的名称序列化 Marshmallow 字段
【发布时间】:2017-11-10 01:52:06
【问题描述】:

我想要一个带有以下输出 json 的棉花糖 Schema -

{
  "_id": "aae216334c3611e78a3e06148752fd79",
  "_time": 20.79606056213379,
  "more_data" : {...}
}

Marshmallow 不会序列化私有成员,所以这是我能得到的最接近的 -

class ApiSchema(Schema):
    class Meta:
        strict = True

    time = fields.Number()
    id = fields.String()

但我确实需要输出 json 中的下划线。

有没有办法告诉 Marshmallow 使用不同的名称对字段进行序列化?

【问题讨论】:

    标签: python json python-2.7 marshmallow


    【解决方案1】:

    https://marshmallow.readthedocs.io/en/2.x-line/quickstart.html#specifying-attribute-names

    即使文档适用于版本 2,这似乎仍然适用于 3.5.1。稳定版 3 文档将没有此示例。

    class ApiSchema(Schema):
      class Meta:
          strict = True
    
      _time = fields.Number(attribute="time")
      _id = fields.String(attribute="id")
    
    【解决方案2】:

    接受的答案(使用attribute)对我不起作用,可能是because

    注意:这只能用于非常特定的用例,例如为单个属性输出多个字段。在大多数情况下,您应该改用 data_key。

    但是data_key 工作得很好:

    class ApiSchema(Schema):
        class Meta:
            strict = True
    
        _time = fields.Number(data_key="time")
        _id = fields.String(data_key="id")
    

    【讨论】:

      【解决方案3】:

      答案在 Marshmallows api reference 中有详细记录。

      我需要使用dump_to

      class ApiSchema(Schema):
          class Meta:
              strict = True
      
          time = fields.Number(dump_to='_time')
          id = fields.String(dump_to='_id')
      

      【讨论】:

      • dump_toload_from 在 Marshmallow 3.0 中被 data_key 替换。
      【解决方案4】:

      您可以在返回序列化对象之前覆盖dump 方法以下划线添加到所选字段:

      class ApiSchema(Schema):
          class Meta:
              strict = True
      
          time = fields.Number()
          id = fields.String()
      
          def dump(self, *args, **kwargs):
              special = kwargs.pop('special', None)
              _partial = super(ApiSchema, self).dump(*args, **kwargs)
              if special is not None and all(f in _partial for f in special):
                  for field in special:
                      _partial['_{}'.format(field)] = _partial.pop(field)
              return _partial
      

      api_schema = ApiSchema(...)
      result = api_schema.dump(obj, special=('id', 'time'))
      

      您也可以在单独的自定义方法上使用 post_dump 装饰器,而不必覆盖 dump,但是,您可能必须将要修改的字段硬编码为类的一部分,这可能不灵活取决于您的用例。

      【讨论】:

        猜你喜欢
        • 2023-02-24
        • 2019-11-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-11-30
        • 1970-01-01
        • 2019-08-10
        相关资源
        最近更新 更多