使用 List 参数调用经过棉花糖验证的 GET 端点
Call marshmallow validated GET endpoint with List parameter
我有一个像这样的棉花糖模式验证:
class MyFilterSchema(Schema):
ids = fields.List(fields.Str(validate=non_empty), required=True)
然后在我的端点调用模式验证:MyFilterSchema().load(flask.request.args)
现在我尝试调用使用此验证的 HTTP GET 端点。但是我得到 'ids': ['Not a valid list.']
我尝试了不同的方法:
/myendpoint?ids=1,2,3
/myendpoint?ids=1&ids=2
/myendpoint?ids=[1,2]
但运气不好。必须如何调用端点才能使 marshmallow 将我的 GET 参数识别为列表?
一种方法是使用验证字段的自定义实现而不是集成列表字段。
class DelimitedListField(fields.List):
def _deserialize(self, value, attr, data, **kwargs):
try:
return value.split(",")
except AttributeError:
raise exceptions.ValidationError(
f"{attr} is not a delimited list it has a non string value {value}."
)
这可以在如下模式中使用:
class MyFilterSchema(Schema):
ids = DelimitedListField(fields.Str(validate=non_empty), required=True)
并且会接受以下格式的呼叫:
/myendpoint?ids=1,2,3
要基于 Eisen 的答案,支持 Mashmallow 的所有验证和反序列化,您需要做更多的事情:
class DelimitedListField(fields.List):
def __init__(self, cls_or_instance: typing.Union[fields.Field, type], **kwargs):
super().__init__(cls_or_instance, **kwargs)
def _deserialize(self, value, attr, data, **kwargs) -> typing.List[typing.Any]:
try:
logger.info(f"value={value}")
list = value.split(",")
logger.info(f"list={list}")
return super()._deserialize(list, attr, data, **kwargs)
except AttributeError:
raise marshmallow.exceptions.ValidationError(
f"{attr} is not a delimited list it has a non string value {value}."
)
我有一个像这样的棉花糖模式验证:
class MyFilterSchema(Schema):
ids = fields.List(fields.Str(validate=non_empty), required=True)
然后在我的端点调用模式验证:MyFilterSchema().load(flask.request.args)
现在我尝试调用使用此验证的 HTTP GET 端点。但是我得到 'ids': ['Not a valid list.']
我尝试了不同的方法:
/myendpoint?ids=1,2,3
/myendpoint?ids=1&ids=2
/myendpoint?ids=[1,2]
但运气不好。必须如何调用端点才能使 marshmallow 将我的 GET 参数识别为列表?
一种方法是使用验证字段的自定义实现而不是集成列表字段。
class DelimitedListField(fields.List):
def _deserialize(self, value, attr, data, **kwargs):
try:
return value.split(",")
except AttributeError:
raise exceptions.ValidationError(
f"{attr} is not a delimited list it has a non string value {value}."
)
这可以在如下模式中使用:
class MyFilterSchema(Schema):
ids = DelimitedListField(fields.Str(validate=non_empty), required=True)
并且会接受以下格式的呼叫:
/myendpoint?ids=1,2,3
要基于 Eisen 的答案,支持 Mashmallow 的所有验证和反序列化,您需要做更多的事情:
class DelimitedListField(fields.List):
def __init__(self, cls_or_instance: typing.Union[fields.Field, type], **kwargs):
super().__init__(cls_or_instance, **kwargs)
def _deserialize(self, value, attr, data, **kwargs) -> typing.List[typing.Any]:
try:
logger.info(f"value={value}")
list = value.split(",")
logger.info(f"list={list}")
return super()._deserialize(list, attr, data, **kwargs)
except AttributeError:
raise marshmallow.exceptions.ValidationError(
f"{attr} is not a delimited list it has a non string value {value}."
)