Обход пирамиды для запросов PUT


Я пытаюсь создать пирамидальный маршрут для запроса PUT в RESTful API для создания нового ресурса. Мое приложение использует обход, который отлично работает для GET и POST:

config.add_route('myroute', '/resources/*traverse')

Поскольку PUT должно иметь новое имя ресурса в URL-адресе, это, очевидно, не работает с PUT, так как в конце есть неизвестный ресурс, поэтому обход не выполняется. Я попытался создать новый маршрут для PUT, используя гибридный подход отправки URL и обхода:

config.add_route('myroute_put', '/resources/{path}/{new}', traverse='/{path}', request_method='PUT')

Это отлично работает тогда и только тогда, когда есть только сегмент пути для прохождения. Имя нового ресурса доступно как request.matchdict['new'] Если мы находимся на корневом уровне, нам нечего пересекать, мы все еще можем заставить это работать, создав вспомогательный маршрут:

config.add_route('myroute_put_root', '/resources/{new}', reqeust_method='PUT')

Однако это не реальное решение, потому что myroute_put все еще не совпадает, если существует более одного сегмента пути, который необходимо пройти, например, для URL: /resources/path1/path2/new_resource

1 2

1 ответ:

Этот вопрос переполнения стека: обход пирамиды HTTP, помещенный в URI, который не существует, предлагает решение для создания другого типа контекста NewResource для представления новых ресурсов. Метод __getitem__() классаResource может затем всегда возвращатьNewResource , если он не может найти запрошенного дочернего элемента. Затем можно настроить конфигурацию представления для контекстаNewResource и PUT request_method.

Это почти работает, за исключением всегда возвращая NewResource , когда ребенок не найден вместо того, чтобы поднять KeyError, он нарушает возможность использовать именованные представления в качестве подчиненных URL. Например, URL: /resources/path1/path2/my_view ошибочно возвращает контекстNewResource для my_view вместо того, чтобы использовать его в качестве имени вида, если он существует.

Лучшим решением этой проблемы, которое я нашел до сих пор, было создание пользовательского алгоритма обхода пирамиды, который сначала использует алгоритм обхода по умолчанию, но затем, если это не удается, он проверяет если request.method - это PUT. Если это так, то он возвращает контекст NewResource, в противном случае он возвращает результаты обхода как есть.