【问题标题】:Generate a list in a URL with Flask's url_for使用 Flask 的 url_for 在 URL 中生成列表
【发布时间】:2018-06-25 13:54:10
【问题描述】:

我正在使用 webargs 使用 Marshmallow 解析来自 request.args 的参数,并将它们作为参数传递给 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,它会为每个值生成重复的键:

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 生成相同的样式?

【问题讨论】:

    标签: python flask query-string marshmallow webargs


    【解决方案1】:

    There's no standard for specifying multiple values for a key in a query string. Flask、浏览器和许多其他 Web 技术使用您在 url_forrequest.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 或其他方式解析任何传入的逗号分隔值。相反,从您的客户端生成重复键样式可能更容易。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-11-20
      • 2015-08-08
      • 1970-01-01
      • 1970-01-01
      • 2023-03-28
      • 1970-01-01
      • 2022-11-12
      • 1970-01-01
      相关资源
      最近更新 更多