装饰器:flask / flask_login,使用login_required

时间:2015-10-24 13:29:04

标签: python flask flask-login

我想使用带有和没有烧瓶login_required装饰器的渲染功能。我的尝试如下:定义基本函数,然后分配一个新的变量,包含login_required

import pymongo
from flask import render_template
from flask_login import login_required

def base_page(collection='posts'):
    db = pymongo.MongoClient().www
    title = collection.capitalize()
    page = db[collection].find().sort("created", pymongo.DESCENDING)
    return render_template('home/home.html', **locals())

base_page_login_required = login_required(base_page)

然后我在我的app.add_url_rule电话中使用这些:

app.add_url_rule('/blog', view_func=base_page, defaults={'collection': 'posts'})
app.add_url_rule('/users', view_func=base_page_login_required, defaults={'collection': 'users'})

但显然我犯了错误:

Traceback (most recent call last):\r, referer: http://localhost/
   File "C:/www/flask/wsgi.py", line 26, in <module>\r, referer: http://localhost/
     app.add_url_rule('/users', view_func=base_page_login_required, defaults={'collection': 'users'})\r, referer: http://localhost/
   File "C:\\bin\\Python34\\lib\\site-packages\\flask\\app.py", line 62, in wrapper_func\r, referer: http://localhost/
     return f(self, *args, **kwargs)\r, referer: http://localhost/
   File "C:\\bin\\Python34\\lib\\site-packages\\flask\\app.py", line 984, in add_url_rule\r, referer: http://localhost/
     'existing endpoint function: %s' % endpoint)\r, referer: http://localhost/
 AssertionError: View function mapping is overwriting an existing endpoint function: base_page\r, referer: http://localhost/

任何人都可以帮我理解这个错误吗?我认为这是烧瓶和add_url_rule特有的。我知道我可以将第一个功能代码复制到第二个并正常使用装饰器,但我想跟随DRY。

1 个答案:

答案 0 :(得分:1)

Flask使用端点名称注册路由;您在url_for()中使用此名称来生成网址。

默认情况下,Flask使用函数的名称,即function.__name__的值。将函数分配给另一个名称(即使使用正确构造的装饰器进行修饰)也不会为函数对象赋予新名称。

您可以使用endpoint关键字参数为您的第二个注册添加不同的名称:

app.add_url_rule('/blog', view_func=base_page, 
                 defaults={'collection': 'posts'})
app.add_url_rule('/users', view_func=base_page_login_required,
                 endpoint='users',
                 defaults={'collection': 'users'})