Создайте список в URL с помощью URL-адреса Flask

Я использую webargs для анализа параметров из request.args с Зефиром и передать их в качестве аргументов для представления Flask. Мой клиент использует разделенный запятыми список для представления нескольких значений ключа:

/queues/generate?queue_id=4&include_ids=1,2,3

Для разбора этого я использую Зефир 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):
    ...

Однако, если я сгенерирую URL с помощью Flask's 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 поле правильно фиксирует значения снова. Так что либо мои URL-адреса Flask не работают, либо URL-адреса моих клиентов не работают.

Я не могу изменить то, как мой клиент генерирует URL-адреса, поэтому я бы хотел использовать синтаксический анализ, используя DelimitedField, Как я могу сделать url_for генерировать тот же стиль?

1 ответ

Там нет стандарта для указания нескольких значений для ключа в строке запроса. 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 понимает только стиль ключа повтора, поэтому вам придется анализировать с помощью веб-аргументов или иным образом любые входящие значения, разделенные запятыми. Может быть проще вместо этого сгенерировать стиль ключа повтора из вашего клиента.

Другие вопросы по тегам