Flask-Classy url_for 问题(构建错误)
我在使用Flask-Classy的视图方法时,遇到了在模板中嵌入url_for或者在视图中定义它的问题。
这是我在/app/routes.py中的代码:
class BaseView(FlaskView):
route_base '/'
@route('index', endpoint('index')
def index():
return render_template('index.html')
def resetapp():
db.drop_all()
return redirect(url_for('BaseView:index'))
这是我在/app/crm/accounts/routes.py中的代码:
class AccountView(FlaskView):
route_base '/crm/account/'
@route('create', endpoint='create')
def create():
return render_template('path/to/create.html')
现在在'index.html'里,我有以下内容:
但是我遇到了以下错误:
werkzeug.routing.BuildError
BuildError: ('AccountView.create', {}, None)
如果你看看第一个路由,有一个resetapp
,它使用url_for引用自己作为BaseView:index - 这个是可以工作的!
我也在index.html中尝试了同样的格式 {{ url_for('AccountView:create') }},但还是出现了同样的错误。
有没有什么想法?
3 个回答
问题在于你在路由装饰器中覆盖了端点,但仍然试图从默认端点访问它们。另外,index
是一个 特殊 方法,如果你想让它对应到你的 FlaskView
的根目录,就不需要使用路由装饰器。(你还忘记了 self
参数!)试着把你的代码改成这样:
class BaseView(FlaskView):
route_base '/'
def index(self):
return render_template('index.html')
def resetapp(self):
db.drop_all()
return redirect(url_for('BaseView:index'))
现在 url_for('BaseView:index')
会返回 "/"
看起来你忘了注册视图 BaseView.register(app)
,下面是一个可以正常工作的代码:
from flask import Flask,url_for,redirect,render_template
from flask.ext.classy import FlaskView,route
app = Flask(__name__)
class BaseView(FlaskView):
route_base= '/'
@route('index')
def index(self):
print url_for('BaseView:index')
return render_template("index.html")
@route('reset')
def reset(self):
print url_for('BaseView:reset')
return redirect(url_for('BaseView:index'))
BaseView.register(app)
if __name__ == '__main__':
app.run(debug=True)
好吧,花了我一段时间,但结果发现我让你们白忙活了。问题其实和某个人提到的有点关系,但主要问题是和一个有参数的路由有关……
对于那些想知道怎么做的人,这里是关于Flask-Classy的url_for()的答案。
@route('update/<client_id>', methods=['POST','GET'])
def update(self, client_id=None):
if client_id is None:
return redirect(url_for('ClientView:index'))
在你的模板中:
{{ url_for('YourView:update', client_id=some_var_value, _method='GET') }}
这里有一些你不能做的事情——为了正确使用Flask-Classy。
- 设置一个端点——这是不可以的。一旦你设置了端点,类:方法的路由就会被覆盖。
- 确保你提供了正确数量的查询参数。
- 如果你想使用url_for,不能定义多个路由。
我还特别指定了方法,但这其实不是必要的。
关于第三点——这是因为如果有多个路由,系统怎么知道该用哪一个呢?其实很简单,但这就是我自己绕圈子的原因。我做了所有事情,除了去掉那些多余的路由。