我目前正在学习Miguel Grinberg编写的flask with flask mega教程。我没有验证用户的新用户名来测试自定义错误页面。问题是服务器无法返回500个错误代码的自定义错误页面,但它可以处理404错误代码。在回溯中,我注意到Jinja2的current_user存在问题。结果,服务器返回了标准500错误页面。
用户加载器:
@login.user_loader
def load_user(user_id):
cur_user = User.query.get(int(user_id))
return cur_user
用户模型:
class User(UserMixin,db.Model):
id = db.Column(db.Integer,primary_key=True)
username = db.Column(db.String(64),index=True,unique=True)
email = db.Column(db.String(120),unique=True)
password_hash = db.Column(db.String(128))
about_me = db.Column(db.String(140))
last_seen = db.Column(db.DateTime,default=datetime.utcnow)
查看功能:
@app.route('/edit_profile',methods=['GET','POST'])
def edit_profile():
form = EditProfileForm()
if form.validate_on_submit():
current_user.username = form.username.data
current_user.about_me = form.about_me.data
db.session.add(current_user)
db.session.commit()
flash('Your changes have been saved')
return redirect(url_for('edit_profile'))
elif request.method == 'GET':
form.username.data = current_user.username
form.about_me.data = current_user.about_me
return render_template('edit_profile.html',title='Edit Profile',form=form)
错误处理程序:
@app.errorhandler(500)
def internal_error(error):
return render_template('500.html'),500
500.html
{% extends 'base.html' %}
{% block content %}
<h1>An unexpected error has occurred.</h1>
<p>The administrator has been notified. Sorry for the inconvenience.</p>
<p><a href="{{ url_for('index') }}">Back</a></p>
{% endblock %}
base.html
<html>
<head>
{% if title %}
<title>{{ title }} - microblog</title>
{% else %}
<title>Welcome to microblog</title>
{% endif %}
</head>
<body>
<div>
microblog:
<a href="{{ url_for('index') }}">Home</a>
{% if current_user.is_anonymous %}
<a href="{{ url_for('login') }}">Login</a>
{% else %}
<a href="{{ url_for('user',username=current_user.username) }}">Profile</a>
<a href="{{ url_for('logout') }}">Logout</a>
{% endif %}
</div>
<hr>
{% with messages = get_flashed_messages() %}
{% if messages %}
<ul>
{% for message in messages %}
<li>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
{% endwith %}
{% block content %}{% endblock %}
</body>
</html>
跟踪:
Traceback (most recent call last):
File "C:\Users\Georgiy\PycharmProjects\flask_microblog\venv\lib\site-packages\werkzeug\serving.py",line 303,in run_wsgi
execute(self.server.app)
File "C:\Users\Georgiy\PycharmProjects\flask_microblog\venv\lib\site-packages\werkzeug\serving.py",line 291,in execute
application_iter = app(environ,start_response)
File "C:\Users\Georgiy\PycharmProjects\flask_microblog\venv\lib\site-packages\flask\app.py",line 2463,in __call__
return self.wsgi_app(environ,line 2449,in wsgi_app
response = self.handle_exception(e)
File "C:\Users\Georgiy\PycharmProjects\flask_microblog\venv\lib\site-packages\flask\app.py",line 1878,in handle_exception
server_error = handler(server_error)
File "C:\Users\Georgiy\PycharmProjects\flask_microblog\app\errors.py",line 12,in internal_error
return render_template('500.html'),500
File "C:\Users\Georgiy\PycharmProjects\flask_microblog\venv\lib\site-packages\flask\templating.py",line 140,in render_template
ctx.app,File "C:\Users\Georgiy\PycharmProjects\flask_microblog\venv\lib\site-packages\flask\templating.py",line 120,in _render
rv = template.render(context)
File "C:\Users\Georgiy\PycharmProjects\flask_microblog\venv\lib\site-packages\jinja2\asyncsupport.py",line 76,in render
return original_render(self,*args,**kwargs)
File "C:\Users\Georgiy\PycharmProjects\flask_microblog\venv\lib\site-packages\jinja2\environment.py",line 1008,in render
return self.environment.handle_exception(exc_info,True)
File "C:\Users\Georgiy\PycharmProjects\flask_microblog\venv\lib\site-packages\jinja2\environment.py",line 780,in handle_exception
reraise(exc_type,exc_value,tb)
File "C:\Users\Georgiy\PycharmProjects\flask_microblog\venv\lib\site-packages\jinja2\_compat.py",line 37,in reraise
raise value.with_traceback(tb)
File "C:\Users\Georgiy\PycharmProjects\flask_microblog\app\templates\500.html",line 1,in top-level template code
{% extends 'base.html' %}
File "C:\Users\Georgiy\PycharmProjects\flask_microblog\app\templates\base.html",line 16,in top-level template code
<a href="{{ url_for('user',username=current_user.username) }}">Profile</a>
File "C:\Users\Georgiy\PycharmProjects\flask_microblog\venv\lib\site-packages\jinja2\environment.py",line 430,in getattr
return getattr(obj,attribute)
File "C:\Users\Georgiy\PycharmProjects\flask_microblog\venv\lib\site-packages\sqlalchemy\orm\attributes.py",line 282,in __get__
return self.impl.get(instance_state(instance),dict_)
File "C:\Users\Georgiy\PycharmProjects\flask_microblog\venv\lib\site-packages\sqlalchemy\orm\attributes.py",line 705,in get
value = state._load_expired(state,passive)
File "C:\Users\Georgiy\PycharmProjects\flask_microblog\venv\lib\site-packages\sqlalchemy\orm\state.py",line 660,in _load_expired
self.manager.deferred_scalar_loader(self,toload)
File "C:\Users\Georgiy\PycharmProjects\flask_microblog\venv\lib\site-packages\sqlalchemy\orm\loading.py",line 979,in load_scalar_attributes
only_load_props=attribute_names,File "C:\Users\Georgiy\PycharmProjects\flask_microblog\venv\lib\site-packages\sqlalchemy\orm\loading.py",line 208,in load_on_ident
identity_token=identity_token,in load_on_pk_identity
return q.one()
File "C:\Users\Georgiy\PycharmProjects\flask_microblog\venv\lib\site-packages\sqlalchemy\orm\query.py",line 3292,in one
ret = self.one_or_none()
File "C:\Users\Georgiy\PycharmProjects\flask_microblog\venv\lib\site-packages\sqlalchemy\orm\query.py",line 3261,in one_or_none
ret = list(self)
File "C:\Users\Georgiy\PycharmProjects\flask_microblog\venv\lib\site-packages\sqlalchemy\orm\query.py",line 3334,in __iter__
return self._execute_and_instances(context)
File "C:\Users\Georgiy\PycharmProjects\flask_microblog\venv\lib\site-packages\sqlalchemy\orm\query.py",line 3356,in _execute_and_instances
querycontext,self._connection_from_session,close_with_result=True
File "C:\Users\Georgiy\PycharmProjects\flask_microblog\venv\lib\site-packages\sqlalchemy\orm\query.py",line 3371,in _get_bind_args
mapper=self._bind_mapper(),clause=querycontext.statement,**kw
File "C:\Users\Georgiy\PycharmProjects\flask_microblog\venv\lib\site-packages\sqlalchemy\orm\query.py",line 3349,in _connection_from_session
conn = self.session.connection(**kw)
File "C:\Users\Georgiy\PycharmProjects\flask_microblog\venv\lib\site-packages\sqlalchemy\orm\session.py",line 1124,in connection
execution_options=execution_options,File "C:\Users\Georgiy\PycharmProjects\flask_microblog\venv\lib\site-packages\sqlalchemy\orm\session.py",line 1130,in _connection_for_bind
engine,execution_options
File "C:\Users\Georgiy\PycharmProjects\flask_microblog\venv\lib\site-packages\sqlalchemy\orm\session.py",line 408,in _connection_for_bind
self._assert_active()
File "C:\Users\Georgiy\PycharmProjects\flask_microblog\venv\lib\site-packages\sqlalchemy\orm\session.py",line 295,in _assert_active
code="7s2a",sqlalchemy.exc.InvalidRequestError: This Session's transaction has been rolled back due to a previous exception during flush. To begin a new transaction with this Session,first issue Session.rollback(). Original exception was: (sqlite3.IntegrityError) UNIQUE constraint failed: user.username
[SQL: UPDATE user SET username=?,about_me=? WHERE user.id = ?]
[parameters: ('admin',"hello my name is Georgiy. I'm learning programming.",2)]
(Background on this error at: http://sqlalche.me/e/gkpj) (Background on this error at: http://sqlalche.me/e/7s2a)