Flask从入门到做出一个博客的大型教程(五)

在开始之前,先来看下项目的整体结构。

flask/
├── app
│   ├── forms.py
│   ├── __init__.py
│   ├── models.py
│   ├── routes.py
│   └── templates
│       ├── base.html
│       ├── index.html
│       ├── login.html
│       ├── register.html
│       └── test.html
├── config.py
├── migrations
│   ├── alembic.ini
│   ├── env.py
│   ├── README
│   ├── script.py.mako
│   └── versions
│       ├── 063e1979f08c_questions.py
├── question.py

6 用户个人资料页

登录模块完成了,接下来做一做用户个人资料页的显示。

app/routes.py : 添加用户方法

@app.route('/user/<username>')
@login_required
def user(username):user = User.query.filter_by(username=username).first_or_404()posts = [{'author':user,'body':'测试Post #1号'},{'author':user,'body':'测试Post #2号'}]return render_template('user.html',user=user,posts=posts)

既然添加了方法,肯定要添加对应的模板了。

app/templates/user.html : 用户个人中心模板

{% extends "base.html" %}{% block content %}<h1>用户: {{ user.username }}</h1><hr>{% for post in posts %}<p>{{ post.author.username }} 说: <b>{{ post.body }}</b></p>{% endfor %}
{% endblock %}

对基类模板进行小小的改动,当用户是未登录状态看不到用户中心的超链接,登录后看到。这会很有感意思。

app/templates/base.html : 完善基类模板

  <div>博客 :<a href="{{ url_for('index') }}">首页</a>{% if current_user.is_anonymous %}<a href="{{ url_for('login') }}">登录</a>{% else %}<a href="{{ url_for('user', username=current_user.username) }}">用户中心</a><a href="{{ url_for('logout') }}">退出</a>{% endif %}</div>

好了,现在登录看看效果吧!

用户头像,我使用的是Gravatar来提供,使用这个网站生成头像是https:// s.gravatar.com/avatar/(hash) 这种格式,会把邮箱地址用md5加密拼接在后面。如果感兴趣可以去上传一个玩一玩,如果不想去的话可以直接使用我提供的。https://www.gravatar.com/avatar/6b541a0a667f5558208aad7309c22936,默认像素是80x80,但是你可以在这个地址后面添加参数?s=128,会变成128x128像素,当然你可以尝试改成更大的数字也可以,很是方便。可以根据你的需求改变大小。接下来就来驶入它吧!

app/models.py : 添加avatar地址

from hashlib import md5
# ...class User(UserMixin, db.Model):# ...def avatar(self, size):digest = md5(self.email.lower().encode('utf-8')).hexdigest()return 'https://www.gravatar.com/avatar/{}?d=identicon&s={}'.format(digest, size)

方法写好了,接下来就修改模板,在网页中显示吧!

app/templates/user.html : 显示用户头像

{% extends "base.html" %}{% block content %}<table><tr valign="top">#可以更改用户头像的大小<td><img src="{{ user.avatar(128) }}"></td><td><h1>用户: {{ user.username }}</h1></td></tr></table><hr>{% for post in posts %}<table><tr valign="top"><td><img src="{{ post.author.avatar(36) }}"></td><td>{{ post.author.username }} 说:<br>{{ post.body }}</td></tr></table>{% endfor %}
{% endblock %}


现在用户个人资料页面设计好了,这样用户写的帖子以及他们的头像都可以显示出来。 现在我想让首页也有类似的布局,但是复制/粘贴处理这种方法显然不太合适,因此新建模板用来被调用。

app/templates/_post.html : 用来放posts里面的内容

 <table><tr valign="top"><td><img src="{{ post.author.avatar(36) }}"></td><td>{{ post.author.username }} 说:<br>{{ post.body }}</td></tr></table>

app/templates/user.html : 在用户模板中被调用。

{% extends "base.html" %}{% block content %}<table><tr valign="top"><td><img src="{{ user.avatar(128) }}"></td><td><h1>User: {{ user.username }}</h1></td></tr></table><hr>{% for post in posts %}{% include '_post.html' %}{% endfor %}
{% endblock %}

把格式完善的更丰满些。

app/models.py : 增加新的字段

class User(UserMixin, db.Model):# ...about_me = db.Column(db.String(140))last_seen = db.Column(db.DateTime, default=datetime.utcnow)

修改了模型,还记得大明湖畔的migrate吗?

(venv) duke@coding:~/flask_tutorial/flask$ flask db migrate -m 'User增加新的字段'
INFO  [alembic.runtime.migration] Context impl MySQLImpl.
INFO  [alembic.runtime.migration] Will assume non-transactional DDL.
INFO  [alembic.autogenerate.compare] Detected added column 'users.about_me'
INFO  [alembic.autogenerate.compare] Detected added column 'users.last_seen'Generating /home/duke/prequestion/migrations/versions/cb586afdff6a_user增加新的字段.py ... done

继续下一步,写入数据库中!

(venv) duke@coding:~/flask_tutorial/flask$ flask db upgrade
INFO  [alembic.runtime.migration] Context impl MySQLImpl.
INFO  [alembic.runtime.migration] Will assume non-transactional DDL.
INFO  [alembic.runtime.migration] Running upgrade 063e1979f08c -> cb586afdff6a, User增加新的字段

好的,现在user模型又新增了字段,那么模板也要相应的改变啦。

app/templates/user.html : 添加字段

{% extends "base.html" %}{% block content %}<table><tr valign="top"><td><img src="{{ user.avatar(128) }}"></td><td><h1>User: {{ user.username }}</h1>{% if user.about_me %}<p>{{ user.about_me }}</p>{% endif %}{% if user.last_seen %}<p>最近登录: {{ user.last_seen }}</p>{% endif %}</td></tr></table>...
{% endblock %}

模型、模板都改了,那中间最重要的视图部分当然也要修改啦。

app/routes.py : 添加对应的方法

#...
from datetime import datetime@app.before_request
def before_request():if current_user.is_authenticated:current_user.last_seen = datetime.utcnow()db.session.commit()#...


刚才在User模型添加了2个字段,上面完成了一个最近登录,还有一个关于我about_me,首先要在forms.py进行设计。

from wtforms import StringField, TextAreaField, SubmitField
from wtforms.validators import DataRequired, Length# ...class EditProfileForm(FlaskForm):username = StringField('用户名', validators=[DataRequired(message='请输入用户名!')])about_me = TextAreaField('关于我', validators=[Length(min=0, max=140)])submit = SubmitField('提交')

既然forms里进行修改,那么就要新增加一个专门的编辑个人资料的页面更合适些。

app/templates/edit_profile.html : 个人资料编辑

{% extends "base.html" %}{% block content %}<h1>个人资料编辑</h1><form action="" method="post">{{ form.hidden_tag() }}<p>{{ form.username.label }}<br>{{ form.username(size=32) }}<br>{% for error in form.username.errors %}<span style="color: red;">[{{ error }}]</span>{% endfor %}</p><p>{{ form.about_me.label }}<br>{{ form.about_me(cols=50, rows=4) }}<br>{% for error in form.about_me.errors %}<span style="color: red;">[{{ error }}]</span>{% endfor %}</p><p>{{ form.submit() }}</p></form>
{% endblock %}

这些都完成差不多了,接下来就是增加视图函数了。

app/routes.py : 编辑个人资料的视图函数

from app.forms import EditProfileForm
# ....@app.route('/edit_profile', methods=['GET', 'POST'])
@login_required
def edit_profile():form = EditProfileForm()if form.validate_on_submit():current_user.username = form.username.datacurrent_user.about_me = form.about_me.datadb.session.commit()flash('你的提交已变更.')return redirect(url_for('edit_profile'))elif request.method == 'GET':form.username.data = current_user.usernameform.about_me.data = current_user.about_mereturn render_template('edit_profile.html', title='个人资料编辑',form=form)

在用户界面添加一个可以点击的超链接,就完成个人资料编辑的页面啦。

app/templates/user.html : 编辑页面的链接

<td><h1>用户名: {{ user.username }}</h1>{% if user.about_me %}<p>{{ user.about_me }}</p>{% endif %}{% if user.last_seen %}<p>最近登录: {{ user.last_seen }}</p>{% endif %}{% if user == current_user %}<p><a href="{{ url_for('edit_profile') }}">个人资料编辑</a></p>{% endif %}
</td>

当当当~,最后对整个的显示如下。

Flask从入门到做出一个博客的大型教程(五)相关推荐

  1. Flask从入门到做出一个博客的大型教程(四)

    Flask从入门到做出一个博客的大型教程(四) 在开始之前,先来看下项目的整体结构. flask ├── app │ ├── forms.py │ ├── __init__.py │ ├── mode ...

  2. Flask从入门到做出一个博客的大型教程(一)

    Flask从入门到做出一个博客的大型教程(一) 本项目全部在虚拟环境中运行,因此请参照前面的文章,链接为https://blog.csdn.net/u014793102/article/details ...

  3. Flask从入门到做出一个博客的大型教程

    https://blog.csdn.net/u014793102/article/category/7661475

  4. hexo 环境变量_小白使用 Github + Hexo 从 0 搭建一个博客

    最近有几位同学在公众号后台留言问我的博客站是怎么建站的,思来想去,还是写一篇从 0 开始吧. 前置准备 我们先聊一下前置准备,可能很多同学一听说要自己搭一个博客系统,直接就望而却步.不得有台服务器么, ...

  5. 个人博客建站教程wordpress+wdcp(小白入门首选)

    原文链接:个人博客建站教程 前言: 如何搭建个人博客,以及网站呢? 今天带领大家从小白完成搭建个人博客,以及网站. 如果你不知道,请不要觉得麻烦,跟着步骤很简单就会完成. 那么准备好了,我们就开始建站 ...

  6. 【FastAPI 03】FastAPI快速搭建一个博客系统

    标题:FastAPI快速搭建一个博客系统 大家好,我是Kuls. 这是<小白学FastAPI>系列的第三篇文章. 今天我们主要讲的是FastAPI快速搭建一个博客系统. 这里可能有些小伙伴 ...

  7. 最近做了一个博客 玩玩而已 运城搜搜 www.lenovoyh.com

    最近做了一个博客 玩玩而已 运城搜搜 www.lenovoyh.com  用了以前一个没用的域名做的  现在还没排名 等待吧 呵呵 转载于:https://www.cnblogs.com/kiah/a ...

  8. 运用BT在centos下搭建一个博客论坛

    在日常的工作和学习中,我们都很希望有自己的工作站,就是自己的服务器,自己给自己搭建一个博客或者是论坛,用于自己来写博客和搭建网站论坛.现在我们就用一个简单的方法来教大家如何30分钟内部署一个博客网站. ...

  9. Docker学习总结(6)——通过 Docker 化一个博客网站来开启我们的 Docker 之旅

    2019独角兽企业重金招聘Python工程师标准>>> 通过 Docker 化一个博客网站来开启我们的 Docker 之旅 这篇文章包含 Docker 的基本概念,以及如何通过创建一 ...

最新文章

  1. Ubuntu 14.04 64bit上升级Intel官方集显更新驱动程序
  2. 【java】兴唐第二十一节(LinkedList和泛型)
  3. 理解mipi协议【转】
  4. redis入门系列(一)redis安装部署
  5. 2016-2017-2 《Java程序设计》预备作业1 总结
  6. getmenuiteminfo无法读取内存_笔记本内存加装教程,看完包会!为了这篇文章,我把电脑都拆了!...
  7. 推荐一个好用的Chrome扩展,专门处理xml的,名叫XML Tree
  8. apache camel_使用Java的Apache Camel入门
  9. 机器学习之KNN算法学习笔记
  10. 你的目的是什么是谁指使你_零基础是一种回归初心的思考:写作的目的是什么?怎么写?写谁?...
  11. 闪耀在UNIX传奇往事中的启示,UNIX见证者带你一览究竟
  12. spark Drive 与Executor
  13. 多线程NSInvocationOperation(NSOperationQueue)的基本用法
  14. videojs创建control-bar组件,实现点击播放下一视频
  15. 电容滤波器和电感滤波器详解(工作原理,设计详解,典型电路图)
  16. python-生成xlsx表格
  17. 助过网:一个月时间怎么科学有效复习公务员考试?
  18. android读取wlan信息,Android判断Wlan信号强弱及wlan管理信息
  19. webService序列化xml 以及去掉删除<string xmlns =“http://tempuri.org/”>
  20. suricata UT测试用例中使用的几个重要的辅助函数

热门文章

  1. 【华为云会议开发指南】最佳实践
  2. 嘉杰项目JSP不编译问题
  3. Redis五种基本数据类型
  4. PHP替代JavaScript的 js charCodeAt() 方法
  5. 人在东瀛——赴日工作两年收获分享(转)
  6. html纵向滚动条隐藏,css隐藏滚动条(横向,坚向)
  7. 面对银发经济的崛起,品牌如何开展营销?
  8. 程序员学习及练习的七个网站
  9. 弱势求职者如何打造超强简历
  10. 知识图谱:小小的入门级综合应用