原文:https://blog.csdn.net/u014793102/article/category/9285123
在开始之前,先来看下项目的整体结构。
1 flask/
2 ├── app
3 │ ├── forms.py
4 │ ├── __init__.py
5 │ ├── models.py
6 │ ├── routes.py
7 │ └── templates
8 │ ├── base.html
9 │ ├── index.html
10 │ ├── login.html
11 │ ├── register.html
12 │ └── test.html
13 ├── config.py
14 ├── migrations
15 │ ├── alembic.ini
16 │ ├── env.py
17 │ ├── README
18 │ ├── script.py.mako
19 │ └── versions
20 │ ├── 063e1979f08c_questions.py
21 ├── question.py
登录模块完成了,接下来做一做用户个人资料页的显示。
app/routes.py : 添加用户方法
1 @app.route('/user/<username>')
2 @login_required
3 def user(username):
4
5 user = User.query.filter_by(username=username).first_or_404()
6 posts = [
7 {'author':user,'body':'测试Post #1号'},
8 {'author':user,'body':'测试Post #2号'}
9 ]
10
11 return render_template('user.html',user=user,posts=posts)
既然添加了方法,肯定要添加对应的模板了。
app/templates/user.html : 用户个人中心模板
1 {% extends "base.html" %}
2
3 {% block content %}
4 <h1>用户: {{ user.username }}</h1>
5 <hr>
6 {% for post in posts %}
7 <p>
8 {{ post.author.username }} 说: <b>{{ post.body }}</b>
9 </p>
10 {% endfor %}
11 {% endblock %}
对基类模板进行小小的改动,当用户是未登录状态看不到用户中心的超链接,登录后看到。这会很有感意思。
app/templates/base.html : 完善基类模板
1 <div>博客 :
2 <a href="{{ url_for('index') }}">首页</a>
3 {% if current_user.is_anonymous %}
4 <a href="{{ url_for('login') }}">登录</a>
5 {% else %}
6 <a href="{{ url_for('user', username=current_user.username) }}">用户中心</a>
7 <a href="{{ url_for('logout') }}">退出</a>
8 {% endif %}
9 </div>
好了,现在登录看看效果吧!
用户头像,我使用的是Gravatar来提供,使用这个网站生成头像是https:// s.gravatar.com/avatar/(hash) 这种格式,会把邮箱地址用md5加密拼接在后面。如果感兴趣可以去上传一个玩一玩,如果不想去的话可以直接使用我提供的。https://www.gravatar.com/avatar/6b541a0a667f5558208aad7309c22936,默认像素是80x80,但是你可以在这个地址后面添加参数?s=128,会变成128x128像素,当然你可以尝试改成更大的数字也可以,很是方便。可以根据你的需求改变大小。接下来就来驶入它吧!
app/models.py : 添加avatar地址
1 from hashlib import md5
2 # ...
3
4 class User(UserMixin, db.Model):
5 # ...
6 def avatar(self, size):
7 digest = md5(self.email.lower().encode('utf-8')).hexdigest()
8 return 'https://www.gravatar.com/avatar/{}?d=identicon&s={}'.format(
9 digest, size)
方法写好了,接下来就修改模板,在网页中显示吧!
app/templates/user.html : 显示用户头像
1 {% extends "base.html" %}
2
3 {% block content %}
4 <table>
5 <tr valign="top">
6 #可以更改用户头像的大小
7 <td><img src="{{ user.avatar(128) }}"></td>
8 <td><h1>用户: {{ user.username }}</h1></td>
9 </tr>
10 </table>
11 <hr>
12 {% for post in posts %}
13 <table>
14 <tr valign="top">
15 <td><img src="{{ post.author.avatar(36) }}"></td>
16 <td>{{ post.author.username }} 说:<br>{{ post.body }}</td>
17 </tr>
18 </table>
19 {% endfor %}
20 {% endblock %}
现在用户个人资料页面设计好了,这样用户写的帖子以及他们的头像都可以显示出来。 现在我想让首页也有类似的布局,但是复制/粘贴处理这种方法显然不太合适,因此新建模板用来被调用。
app/templates/_post.html : 用来放posts里面的内容
1 <table>
2 <tr valign="top">
3 <td><img src="{{ post.author.avatar(36) }}"></td>
4 <td>{{ post.author.username }} 说:<br>{{ post.body }}</td>
5 </tr>
6 </table>
app/templates/user.html : 在用户模板中被调用。
1 {% extends "base.html" %}
2
3 {% block content %}
4 <table>
5 <tr valign="top">
6 <td><img src="{{ user.avatar(128) }}"></td>
7 <td><h1>User: {{ user.username }}</h1></td>
8 </tr>
9 </table>
10 <hr>
11 {% for post in posts %}
12 {% include '_post.html' %}
13 {% endfor %}
14 {% endblock %}
把格式完善的更丰满些。
app/models.py : 增加新的字段
1 class User(UserMixin, db.Model):
2 # ...
3 about_me = db.Column(db.String(140))
4 last_seen = db.Column(db.DateTime, default=datetime.utcnow)
修改了模型,还记得大明湖畔的migrate吗?
1 (venv) duke@coding:~/flask_tutorial/flask$ flask db migrate -m 'User增加新的字段'
2 INFO [alembic.runtime.migration] Context impl MySQLImpl.
3 INFO [alembic.runtime.migration] Will assume non-transactional DDL.
4 INFO [alembic.autogenerate.compare] Detected added column 'users.about_me'
5 INFO [alembic.autogenerate.compare] Detected added column 'users.last_seen'
6 Generating /home/duke/prequestion/migrations/versions/cb586afdff6a_user增加新的字段.py ... done
继续下一步,写入数据库中!
1 (venv) duke@coding:~/flask_tutorial/flask$ flask db upgrade
2 INFO [alembic.runtime.migration] Context impl MySQLImpl.
3 INFO [alembic.runtime.migration] Will assume non-transactional DDL.
4 INFO [alembic.runtime.migration] Running upgrade 063e1979f08c -> cb586afdff6a, User增加新的字段
好的,现在user模型又新增了字段,那么模板也要相应的改变啦。
app/templates/user.html : 添加字段
1 {% extends "base.html" %}
2
3 {% block content %}
4 <table>
5 <tr valign="top">
6 <td><img src="{{ user.avatar(128) }}"></td>
7 <td>
8 <h1>User: {{ user.username }}</h1>
9 {% if user.about_me %}<p>{{ user.about_me }}</p>{% endif %}
10 {% if user.last_seen %}<p>最近登录: {{ user.last_seen }}</p>{% endif %}
11 </td>
12 </tr>
13 </table>
14 ...
15 {% endblock %}
模型、模板都改了,那中间最重要的视图部分当然也要修改啦。
app/routes.py : 添加对应的方法
1 #...
2 from datetime import datetime
3
4 @app.before_request
5 def before_request():
6 if current_user.is_authenticated:
7 current_user.last_seen = datetime.utcnow()
8 db.session.commit()
9
10 #...
刚才在User模型添加了2个字段,上面完成了一个最近登录,还有一个关于我about_me,首先要在forms.py进行设计。
1 from wtforms import StringField, TextAreaField, SubmitField
2 from wtforms.validators import DataRequired, Length
3
4 # ...
5
6 class EditProfileForm(FlaskForm):
7 username = StringField('用户名', validators=[DataRequired(message='请输入用户名!')])
8 about_me = TextAreaField('关于我', validators=[Length(min=0, max=140)])
9 submit = SubmitField('提交')
既然forms里进行修改,那么就要新增加一个专门的编辑个人资料的页面更合适些。
app/templates/edit_profile.html : 个人资料编辑
1 {% extends "base.html" %} 2 3 {% block content %} 4 <h1>个人资料编辑</h1> 5 <form action="" method="post"> 6 {{ form.hidden_tag() }} 7 <p> 8 {{ form.username.label }}<br> 9 {{ form.username(size=32) }}<br> 10 {% for error in form.username.errors %} 11 <span color: #800000;">"color: red;">[{{ error }}]</span> 12 {% endfor %} 13 </p> 14 <p> 15 {{ form.about_me.label }}<br> 16 {{ form.about_me(cols=50, rows=4) }}<br> 17 {% for error in form.about_me.errors %} 18 <span color: #800000;">"color: red;">[{{ error }}]</span> 19 {% endfor %} 20 </p> 21 <p>{{ form.submit() }}</p> 22 </form> 23 {% endblock %}
这些都完成差不多了,接下来就是增加视图函数了。
app/routes.py : 编辑个人资料的视图函数
1 from app.forms import EditProfileForm
2 # ....
3
4 @app.route('/edit_profile', methods=['GET', 'POST'])
5 @login_required
6 def edit_profile():
7 form = EditProfileForm()
8 if form.validate_on_submit():
9 current_user.username = form.username.data
10 current_user.about_me = form.about_me.data
11 db.session.commit()
12 flash('你的提交已变更.')
13 return redirect(url_for('edit_profile'))
14 elif request.method == 'GET':
15 form.username.data = current_user.username
16 form.about_me.data = current_user.about_me
17 return render_template('edit_profile.html', title='个人资料编辑',
18 form=form)
在用户界面添加一个可以点击的超链接,就完成个人资料编辑的页面啦。
app/templates/user.html : 编辑页面的链接
1 <td>
2 <h1>用户名: {{ user.username }}</h1>
3 {% if user.about_me %}<p>{{ user.about_me }}</p>{% endif %}
4 {% if user.last_seen %}<p>最近登录: {{ user.last_seen }}</p>{% endif %}
5 {% if user == current_user %}
6 <p><a href="{{ url_for('edit_profile') }}">个人资料编辑</a></p>
7 {% endif %}
8 </td>
当当当~,最后对整个的显示如下。