我正在使用 webargs 通过 Marshmallow 解析来自 request.args
的参数,并将它们作为参数传递给 Flask View 。我的客户使用逗号分隔的列表来表示键的多个值:
/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,它会为每个值生成重复的键:
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 失败。
我无法更改客户端生成 URL 的方式,因此我想继续使用 DelimitedField
进行解析。如何让 url_for
生成相同的样式?
最佳答案
There's no standard for specifying multiple values for a key in a query string. Flask、浏览器和许多其他 Web 技术都使用您在 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 或其他方式解析任何传入的逗号分隔值。从您的客户端生成重复键样式可能会更容易。
关于python - 使用 Flask 的 url_for 在 URL 中生成列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48288322/