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