2

我想指定一个模式字段,它接受一个或多个资源。但是,我似乎只能指定一种行为或另一种行为。

>>> class Resource(marshmallow.Schema):
...     data = marshmallow.fields.Dict()
... 
>>> class ContainerSchema(marshmallow.Schema):
...     resource = marshmallow.fields.Nested(ResourceSchema, many=True)
... 
>>> ContainerSchema().dump({'resource': [{'data': 'DATA'}]})
MarshalResult(data={'resource': [{'data': 'DATA'}]}, errors={})

在上面的示例中,必须定义一个列表。但是我不希望:

>>> ContainerSchema().dump({'resource': {'data': 'DATA'}})
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/lib64/python3.6/site-packages/marshmallow/schema.py", line 513, in dump
    **kwargs
  File "/lib64/python3.6/site-packages/marshmallow/marshalling.py", line 147, in serialize
    index=(index if index_errors else None)
  File "/lib64/python3.6/site-packages/marshmallow/marshalling.py", line 68, in call_and_store
    value = getter_func(data)
  File "/lib64/python3.6/site-packages/marshmallow/marshalling.py", line 141, in <lambda>
    getter = lambda d: field_obj.serialize(attr_name, d, accessor=accessor)
  File "/lib64/python3.6/site-packages/marshmallow/fields.py", line 252, in serialize
    return self._serialize(value, attr, obj)
  File "/lib64/python3.6/site-packages/marshmallow/fields.py", line 448, in _serialize
    schema._update_fields(obj=nested_obj, many=self.many)
  File "/lib64/python3.6/site-packages/marshmallow/schema.py", line 760, in _update_fields
    ret = self.__filter_fields(field_names, obj, many=many)
  File "/lib64/python3.6/site-packages/marshmallow/schema.py", line 810, in __filter_fields
    obj_prototype = obj[0]
KeyError: 0

我可以有一个允许单个项目或多个项目的架构吗?

4

1 回答 1

2

将参数作为列表给出的关键——无论是一个还是多个——是这样架构知道如何在任何一种情况下处理它。要使架构处理不同格式的参数,例如不在列表中,您需要向架构添加预处理器,如下所示:

class ContainerSchema(marshmallow.Schema):
    resource = marshmallow.fields.Nested(ResourceSchema, many=True)
    @pre_dump
    def wrap_indata(self, indata):
        if type(indata['resource']) is dict:
            indata['resource'] = [indata['resource']] 
于 2017-07-16T13:08:22.050 回答