Как я могу перенаправить после POST в Pyramid?
Я пытаюсь передать свою форму на маршрут, который будет проверять данные, а затем перенаправлять обратно на исходный маршрут.
Например:
- Пользователь загружает страницу website.com/post
- Форма ОТПРАВЛЯЕТ данные на website.com/post-save
- Пользователь перенаправляется обратно на website.com/post
Пирамида дает мне некоторые неприятности, делающие это.
Здесь мои уменьшенные view.py
def _get_link_form(post_data):
""" Returns the initialised form object """
return LinkForm(post_data)
def home_page(request):
form = _get_link_form(request.POST)
return {'form' : form}
def save_post(request):
""" form data is submitted here """"
form = _get_link_form(request.POST)
if not form.validate():
return home_page(request, form)
Это код, с которым я играл. Он не только не работает, но и чувствует себя грязным и взломанным. Наверняка существует более простой способ "перенаправить после POST" в Pyramid?
Ответы
Ответ 1
Ваша проблема легче всего решить, просто POSTing на тот же URL-адрес, что и ваша форма, и просто перенаправлять пользователя на страницу, когда POST успешно. Таким образом, пока форма не будет успешно отправлена, вы не будете изменять URL-адреса.
Если вы просто умираете от POST до другого URL-адреса, вам необходимо сохранить данные с помощью сеансов, так как вы явно обрабатываете данные формы между запросами.
Обычно, если вы хотите обрабатывать ошибки в своих формах, вы должны использовать сеансовые и флэш-сообщения. Для этого вы просто добавляете местоположение флэш-сообщений в базовый шаблон и настраиваете поддержку сеанса, используя что-то вроде pyramid_beaker.
Предполагая, что ваша домашняя страница настроена на "home" named-route:
from pyramid.httpexceptions import HTTPFound
def myview(request):
user = '<default user field value>'
if 'submit' in request.POST:
user = request.POST.get('user')
# validate your form data
if <form validates successfully>:
request.session.flash('Form was submitted successfully.')
url = request.route_url('home')
return HTTPFound(location=url)
return {
# globals for rendering your form
'user': user,
}
Обратите внимание, что если форма не может подтвердить, что вы используете тот же код, который вы сделали для рендеринга формы, и только в случае успешного перенаправления. Этот формат также может обрабатывать заполнение формы со значениями, используемыми в представлении, и значениями по умолчанию.
Вы можете прокручивать флэш-сообщения в выбранном вами шаблоне с помощью request.session.peek_flash()
и request.session.pop_flash()
.
route_url
поддерживает также изменение строки запроса на сгенерированном URL-адресе, если вы хотите пометить свое домашнее представление, чтобы проверить данные сеанса.
Очевидно, вы можете просто передать все в строке запроса на домашнюю страницу, но это довольно большая уязвимость в безопасности, которую сеансы могут защитить.
Ответ 2
Документация Pyramid содержит особенно подробный раздел в следующем примере:
from pyramid.httpexceptions import HTTPFound
def myview(request):
return HTTPFound(location='http://example.com')
Ответ 3
Документация Pyramid содержит информацию о Redirect, дополнительную информацию можно найти по ссылке ниже:
Документация по пирамиде
import pyramid.httpexceptions as exc
raise exc.HTTPFound(request.route_url("section1")) # Redirect
Отредактировано:
На самом деле вы можете сделать это на стороне клиента с помощью Javascript, сначала вы должны отправить конкретный ответ на стороне клиента (либо с миганием некоторых данных, либо с возвратом объекта Response):
window.location = '{{ request.route_path("route_name") }}';
Ответ 4
Предполагая, что ваша домашняя страница является стандартным представлением вашего веб-приложения для пирамиды, вы можете сделать:
def _get_link_form(post_data):
""" Returns the initialised form object """
return LinkForm(post_data)
def home_page(request):
form = _get_link_form(request.POST)
return {'form' : form}
def save_post(request):
form = _get_link_form(request.POST)
if not form.validate():
from pyramid.httpexceptions import HTTPFound
return HTTPFound(location=request.application_url)
В основном вам нужно знать, как "home_page" был добавлен в конфигуратор. Если ваша домашняя страница фактически живет в /few/levels/deep/homepage, перенаправление может выглядеть следующим образом:
return HTTPFound(location=request.application_url + '/few/levels/deep/homepage')
Ответ 5
Я делаю это так:
from pyramid.httpexceptions import HTTPCreated
response = HTTPCreated()
response.location = self.request.resource_url( newResource )
return response
Отправляет HTTP-код, 201
Ответ 6
Чистым способом является использование "перегрузки", предоставляемого пирамидой для разных типов запросов, например, вы можете украсить ваши методы таким образом:
@action(request_method='GET',
renderer='mypackage:/templates/save.mako',
name='save')
def save(request):
''' Fill the template with default values or leave it blank'''
return {}
@action(request_method='POST',
renderer='mypackage:/templates/save.mako',
name='save')
def save_post(request):
""" form data is submitted here """"
# process form
В HTML вы должны вызвать форму действия, например
<form method="POST" id="tform" action="${request.route_url('home', action='save')}">
Таким образом, один метод обрабатывается при использовании метода POST, а другой - при использовании GET. Такое же имя, но две реализации.