Мы используем Werkzeug и Flask для создания REST API. В этом контексте нам не нужно автоматическое добавление завершающих слэшей, поскольку это приводит к асимметрии между GET и другими запросами, и здесь приемлемо быть строгим.
В настоящее время для этого нам нужно использовать собственный класс правил, который подключается к внутренним компонентам ( Rule.match
и RequestSlash
).
Имеет ли смысл добавить это как вариант конфигурации первого порядка? Что-то вроде append_slash
(для параллельного использования эквивалентной опции Django) на картах URL-адресов?
app.url_map.strict_slashes = False
- это все, что вам нужно, чтобы этого избежать.
Это фактически приводит к совпадению маршрута при отсутствии косой черты. Хочу на 404.
Текущее поведение:
| Правило имеет косую черту в конце | В конце пути есть косая черта | strict_slashes
| Результат |
| - | - | - | - |
| N | N | True
| (совпадение) |
| N | N | False
| (совпадение) |
| N | Y | True
| 404 |
| N | Y | False
| 404 |
| Y | N | True
| 301 |
| Y | N | False
| (совпадение) |
| Y | Y | True
| (совпадение) |
| Y | Y | False
| (совпадение) |
Я хочу 404, когда в правиле есть завершающая косая черта, а в пути нет. Прямо сейчас я делаю это через:
class StrictRule(Rule):
def match(self, path, method=None):
try:
result = super(StrictRule, self).match(path, method)
except RequestSlash:
return None
return result
Но я бы предпочел не вдаваться в подробности.
Использование специального правила было бы правильным способом сделать это во Flask. Мы решили изнутри не пытаться создать все для всех в правилах. Если вам нужно правило, выходящее за рамки стандартного, вам нужно его указать. Для Flash вы должны установить url_rule_class
в новый класс. Дополнительную информацию см. В документации Flask. http://flask.pocoo.org/docs/1.0/api/?highlight=rule#flask.Flask.url_rule_class
@aenglander
Согласно https://github.com/pallets/werkzeug/issues/1246#issuecomment -362099342, проблема здесь в реализации настраиваемого правила. RequestSlash
явно помечено как внутреннее исключение на https://github.com/pallets/werkzeug/blob/a220671d66755a94630a212378754bb432811158/src/werkzeug/routing.py#L259 -L260, поэтому справиться с этим довольно неудобно. код пользователя.
И хотя я, безусловно, согласен с тем, что базовые правила не должны поддерживать все возможные варианты использования, отсутствие сопоставления по отсутствующей косой черте является очень распространенным вариантом использования. Для предшествующего уровня техники этот шаблон является одним из немногих, которые явно представлены в конфигурации Django через APPEND_SLASH
: https://docs.djangoproject.com/en/dev/ref/settings/#append -slash.
«Внутренний» в данном случае означает «обрабатывается внутри», а не «только для внутреннего использования». Показанный вами код подходит для использования.
@davidism Спасибо за разъяснения. Тогда я пойду дальше и сделаю это.
Самый полезный комментарий
app.url_map.strict_slashes = False
- это все, что вам нужно, чтобы этого избежать.