简体   繁体   English

装饰器:flask / flask_login,使用login_required

[英]Decorators: flask/flask_login, using login_required

I want to use my rendering function both with and without the flask login_required decorator. 我想在有和没有烧瓶login_required装饰器的情况下都使用渲染功能。 My attempt was as follows: define the basic function, then assign to a new variable, wrapped with 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)

I then use these in my app.add_url_rule calls: 然后,在我的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'})

But obviously I've got something wrong: 但显然我出了点问题:

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/

Can anyone help me understand this error? 谁能帮助我了解此错误? I assume this is specific to flask and add_url_rule . 我认为这是特定于flask和add_url_rule I know I could just copy the first function code to a second and use the decorator normally, but I want to follow DRY. 我知道我可以将第一个功能代码复制到第二个并正常使用装饰器,但是我想遵循DRY。

Flask registers routes with an endpoint name; Flask使用端点名称注册路由; you use this name in url_for() to generate URLs. 您可以在url_for()使用此名称来生成URL。

By default, Flask uses the name of the function for this, the value of function.__name__ . 默认情况下,Flask为此使用函数名称,即function.__name__的值。 Assigning a function to another name (even when decorated with a properly constructed decorator), does not give the function object a new name. 将函数分配给另一个名称(即使使用正确构造的装饰器进行装饰)也不会为函数对象提供新名称。

You can use the endpoint keyword argument to give your second registration a different name instead: 您可以使用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'})

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM