条件重定向金字塔

时间:2011-11-30 01:32:04

标签: python redirect view pyramid

我正在寻找一种方法将用户重定向到与使用@view_config兼容的不同路由/模板。

我有一个函数可以读入上传的文件,并尝试根据文件内容创建新模型。我想知道是否有一种干净的方式可以将用户重定向到两个网址之一,具体取决于新模型的创建是成功还是存在错误。

如果模型创建成功,我想将用户重定向到模型页面。如果出现错误,我想将用户重定向到错误页面。但是,在呈现错误页面时,我无法分解原始函数(load_model)的view_config。

@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 个答案:

答案 0 :(得分:5)

您要问的不是“如何重定向”,而是“如何在视图功能中更改渲染器”。为了快速回答,我认为你可以使用:

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重定向
    • 如果数据无效,则返回一个dict以再次显示该表单,此次出现错误
  • 您在GETPOST中使用相同的渲染器,但POST中的渲染器仅用于无效数据(否则,您重定向)。
  • 您有另一个视图功能来显示创建的模型。

答案 1 :(得分:2)

Antoine展示了更为通用的解决方案,但这是尝试坚持您的基本格式。

您的想法是,您希望进行一些处理,然后将用户重定向到成功或失败页面。如果您想要重定向到成功页面的方式,则可以重定向到失败页面,但是我将显示一个不同的版本,您只需在加载中显示错误页面,但如果加载工作,您将重定向到模型。

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'