我使用webargs解析来自request.args
的Marshmallow参数,并将它们作为参数传递给Flask视图。我的客户端使用逗号分隔列表来表示键的多个值:
/queues/generate?queue_id=4&include_ids=1,2,3
要解析这个,我使用Marshmallow的DelimitedList
字段。
from marshmallow import Schema, fields
from webargs import use_args
from webargs.fields import DelimitedList
class GenerationParamsSchema(Schema):
queue_id = fields.Integer(required=True)
include_ids = DelimitedList(fields.Integer(), required=False)
@queues.route('/generate_content', methods=['GET'])
@use_args(GenerationParamsSchema(strict=True))
def generate_content_count(generation_params):
...
但是,如果我使用Flask' url_for
生成网址,则会为每个值生成重复的密钥:
url_for('queues.generate', queue_id=4, include_ids=[1, 2, 3])
/queues/generate?queue_id=4&include_ids=1&include_ids=2&include_ids=3
使用DelimitedList
字段解析此字段仅捕获第一个值。更改为List
字段会再次正确捕获值。因此,我的Flask URL失败,或者我的客户端URL失败。
我无法更改客户端生成网址的方式,因此我希望坚持使用DelimitedField
进行解析。如何让url_for
生成相同的样式?
答案 0 :(得分:1)
There's no standard for specifying multiple values for a key in a query string. Flask,浏览器和许多其他网络技术使用"重复键"您使用url_for
和request.args
看到的样式。您的客户选择使用不同的风格。
如果您希望url_for
生成分隔的样式,则需要预先处理传递给url_for
的值。在url_for
周围写一个包装,然后使用它。
from flask import url_for as _url_for
@app.template_global()
def url_for(endpoint, **values):
for key, value in values.items():
if isinstance(value, (tuple, list)):
values[key] = ','.join(value)
return _url_for(endpoint, **values)
请注意,requests.args
只能理解重复键样式,因此您必须使用webargs或其他方式解析任何传入的逗号分隔值。可能更容易从客户端生成重复键样式。