Pyramid中的条件重定向

2 投票
2 回答
2460 浏览
提问于 2025-04-17 07:21

我想找一种方法,可以把用户引导到不同的页面或模板,而且这个方法要能和@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 个回答

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'
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 进行重定向。
    • 如果数据无效,你会返回一个字典,重新显示表单,并且这次会显示错误信息。
  • GETPOST 中使用相同的渲染器,但 POST 中的渲染器只在数据无效时使用(如果数据有效,就会重定向)。
  • 你还需要另一个视图函数来显示创建好的模型。

撰写回答