Условное перенаправление в Пирамиде - PullRequest
1 голос
/ 30 ноября 2011

Я ищу способ перенаправления пользователей на разные маршруты / шаблоны, совместимый с использованием @ view_config.

У меня есть функция, которая читает загруженный файл и пытается создать новую модель на основесодержимое файла.Мне было интересно, существует ли чистый способ, которым я могу перенаправить пользователя на один из двух URL-адресов, в зависимости от того, было ли создание новой модели успешным или произошла ошибка.

Если создание модели прошло успешно,Я хочу перенаправить пользователя на страницу модели.Если есть ошибка, я хочу перенаправить пользователя на страницу ошибки.Тем не менее, у меня возникли проблемы с разрывом view_config оригинальной функции (load_model) при отображении страницы ошибки.

@view_config(renderer="error.mak")
@view_config(renderer="model.mak",
        route_name='load_model_route')
def load_model(self):
   ...
   model = Model.find_model(model_name)
   if model:
      #redirect to model_route
   else:
      #redirect to model_error_route

Каждый маршрут будет иметь @view_config, который связывает его с функцией.

Ответы [ 2 ]

5 голосов
/ 30 ноября 2011

Вы спрашиваете не «Как перенаправить», а «Как изменить рендерер в функции просмотра». Чтобы ответить быстро, я думаю, вы могли бы использовать:

request.override_renderer = 'other-renderer.mak'

Но я не думаю, что это хорошая идея. Вот обычный шаблон, который используется большую часть времени для обработки отправки формы:

from pyramid.httpexceptions import HTTPFound, HTTPNotFound
from pyramid.url import route_url
from your_app import Model, some_stuff, save_to_db

@view_config(route_name='new_model',
        renderer='model/new.mak', request_method='GET')
def new(request):
    """Shows the empty form."""
    return {'model': Model(), 'errors': {}}

@view_config(route_name='create_model',
        renderer='model/new.mak', request_method='POST')
def create(request):
    """Receives submitted form."""
    model = some_stuff()
    if len(model.errors) = 0: # is valid
        # do your stuff, then redirect
        save_to_db(model)
        return HTTPFound(route_url('show_model', request, model_id=model.id))
    # is invalid
    return {'model': model, 'errors': model.errors}

@view_config(route_name='show_model',
    renderer='model/show.mak', request_method='GET')
def show(request):
    """Shows details of one model."""
    model = Model.find(request.matchdict['model_id'])
    if model is None:
        return HTTPNotFound()
    return {'model': model}

Короче говоря:

  • Вы показываете пустую форму, когда у вас есть GET на маршруте для новой модели.
  • Вы обрабатываете отправку формы (POST) в другой функции просмотра
    • Если данные верны, вы делаете свое дело, тогда вы перенаправляете с HTTPFound
    • Если данные недействительны, вы возвращаете запрос на повторное отображение формы с ошибками на этот раз
  • Вы используете один и тот же рендерер в GET и POST, но тот, что в POST, используется только в случае неверных данных (в противном случае вы перенаправляете).
  • У вас есть другая функция просмотра, чтобы показать созданную модель.
2 голосов
/ 30 ноября 2011

Антуан показал более общее решение, но вот попытка придерживаться вашего основного формата.

Идея состоит в том, что вы хотите выполнить некоторую обработку, а затем перенаправить пользователя на страницу успеха или сбоя. Вы можете перенаправить на страницу сбоя, если вы хотите точно так же, как вы перенаправили на страницу успеха, но я покажу другую версию, где вы просто показываете страницу ошибки при загрузке, но если загрузка работает, вы перенаправляете на модель.

config.add_route('show_model', '/models/{id}')
config.add_route('load_model', '/load_model')

@view_config(route_name='load_model', renderer='error.mak')
def load_model(self):
    # ...
    model = Model.find_model(model_name)
    if model:
        return HTTPFound(self.request.route_url('show_model', id=model.id))
    return {} # some dict of stuff required to render 'error.mak'

@view_config(route_name='show_model', renderer='model.mak')
def show_model(self):
    id = request.matchdict['id']
    model = Model.get_model_by_id(id)
    # be aware model could fail to load in this new request
    return {'model': model} # a dict of stuff required to render 'model.mak'
...