【发布时间】:2020-10-19 05:42:29
【问题描述】:
当我尝试在视图上使用自定义装饰器时出现错误。据我所知,问题似乎在于没有在装饰函数上使用@wraps,但我这样做了,但似乎仍然得到一个错误,即视图函数映射已经存在。
def logout_required(url="/"):
"""
Redirect a user to a specified location if they are already signed in.
:param url: URL to be redirected to if invalid
:type url: str
:return: Function
"""
def decorator(f):
@wraps(f)
def decorated_function(*args, **kwargs):
if current_user.is_authenticated:
return redirect(url)
return f(*args, **kwargs)
return decorated_function
return decorator
views.py
@blueprint.route("/login")
@logout_required
def login():
return "LOGIN"
@blueprint.route("/logout")
@login_required
def logout():
logout_user()
flash("You have been logged out.", "success")
return redirect(url_for("auth.login"))
@blueprint.route("/register")
@logout_required
def register():
return "REGISTER"
如果有帮助,堆栈跟踪也是如此:
website_1 | [2020-06-29 05:15:03 +0000] [1] [INFO] Starting gunicorn 20.0.4
website_1 | [2020-06-29 05:15:03 +0000] [1] [INFO] Listening at: http://0.0.0.0:8000 (1)
website_1 | [2020-06-29 05:15:03 +0000] [1] [INFO] Using worker: sync
website_1 | [2020-06-29 05:15:03 +0000] [8] [INFO] Booting worker with pid: 8
website_1 | [2020-06-29 05:15:03 +0000] [8] [ERROR] Exception in worker process
website_1 | Traceback (most recent call last):
website_1 | File "/usr/local/lib/python3.7/site-packages/gunicorn/arbiter.py", line 583, in spawn_worker
website_1 | worker.init_process()
website_1 | File "/usr/local/lib/python3.7/site-packages/gunicorn/workers/base.py", line 119, in init_process
website_1 | self.load_wsgi()
website_1 | File "/usr/local/lib/python3.7/site-packages/gunicorn/workers/base.py", line 144, in load_wsgi
website_1 | self.wsgi = self.app.wsgi()
website_1 | File "/usr/local/lib/python3.7/site-packages/gunicorn/app/base.py", line 67, in wsgi
website_1 | self.callable = self.load()
website_1 | File "/usr/local/lib/python3.7/site-packages/gunicorn/app/wsgiapp.py", line 49, in load
website_1 | return self.load_wsgiapp()
website_1 | File "/usr/local/lib/python3.7/site-packages/gunicorn/app/wsgiapp.py", line 39, in load_wsgiapp
website_1 | return util.import_app(self.app_uri)
website_1 | File "/usr/local/lib/python3.7/site-packages/gunicorn/util.py", line 411, in import_app
website_1 | app = app(*args, **kwargs)
website_1 | File "/project/app/app.py", line 27, in create_app
website_1 | register_blueprints(app)
website_1 | File "/project/app/app.py", line 50, in register_blueprints
website_1 | app.register_blueprint(auth.blueprint)
website_1 | File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 98, in wrapper_func
website_1 | return f(self, *args, **kwargs)
website_1 | File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1168, in register_blueprint
website_1 | blueprint.register(self, options, first_registration)
website_1 | File "/usr/local/lib/python3.7/site-packages/flask/blueprints.py", line 256, in register
website_1 | deferred(state)
website_1 | File "/usr/local/lib/python3.7/site-packages/flask/blueprints.py", line 294, in <lambda>
website_1 | self.record(lambda s: s.add_url_rule(rule, endpoint, view_func, **options))
website_1 | File "/usr/local/lib/python3.7/site-packages/flask/blueprints.py", line 86, in add_url_rule
website_1 | **options
website_1 | File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 98, in wrapper_func
website_1 | return f(self, *args, **kwargs)
website_1 | File "/usr/local/lib/python3.7/site-packages/flask/app.py", line 1284, in add_url_rule
website_1 | "existing endpoint function: %s" % endpoint
website_1 | AssertionError: View function mapping is overwriting an existing endpoint function: auth.decorator
【问题讨论】:
-
你必须在装饰函数之前调用
logout_required-@logout_required("/")。您的“装饰器”logout_required实际上是一个接受参数url并返回装饰器的函数 -
修复它。没有意识到无论我是否有参数,我都需要使用带括号的参数的装饰器。谢谢!
标签: python python-3.x flask python-decorators