目录

前文列表

用 Flask 来写个轻博客 (1) — 创建项目

用 Flask 来写个轻博客 (2) — Hello World!

用 Flask 来写个轻博客 (3) — (M)VC_连接 MySQL 和 SQLAlchemy

用 Flask 来写个轻博客 (4) — (M)VC_创建数据模型和表

用 Flask 来写个轻博客 (5) — (M)VC_SQLAlchemy 的 CRUD 详解

用 Flask 来写个轻博客 (6) — (M)VC_models 的关系(one to many)

用 Flask 来写个轻博客 (7) — (M)VC_models 的关系(many to many)

用 Flask 来写个轻博客 (8) — (M)VC_Alembic 管理数据库结构的升级和降级

用 Flask 来写个轻博客 (9) — M(V)C_Jinja 语法基础快速概览

用 Flask 来写个轻博客 (10) — M(V)C_Jinja 常用过滤器与 Flask 特殊变量及方法

视图函数

视图函数: 就是为 Jinja 模板文件中的变量准备数据对象的 Python 函数, 我们一般会在视图函数中准备好需要传递给 Jinja 模板文件的 Python 数据对象, 并应用到 Jinja 文件中的变量代码块中.

现在我们假设需要在 blog 中的每一个页面的右侧边栏(sidebar)中显示 最近发布的 5 篇文件文章数最多的 5 个标签, 我们就需要定义一个视图函数 sidebar_data(), 该函数就会为右侧边栏提供所需要的 Python 数据对象, 并且这些 Python 数据对象是能够从数据库中获取的.

在 views.py 文件中定义视图函数

定义右侧边栏的视图函数

from flask import render_template
from sqlalchemy import func from main import app
from models import db, User, Post, Tag, Comment, posts_tags def sidebar_data():
"""Set the sidebar function.""" # Get post of recent
recent = db.session.query(Post).order_by(
Post.publish_date.desc()
).limit(5).all() # Get the tags and sort by count of posts.
top_tags = db.session.query(
Tag, func.count(posts_tags.c.post_id).label('total')
).join(
posts_tags
).group_by(Tag).order_by('total DESC').limit(5).all()
return recent, top_tags
  • NOTE 1: 由于每个页面都需要右侧边栏的数据, 所以将这些高重用的代码抽象成为一个函数.

  • NOTE 2: sidebar_data() 函数中调用了 sqlalchemy.func 库, func 库提供了一个计数器 count 用于返回 tags 表中值相同的 post_id 列的数量,来得到 post 数最多的 tags。

  • NOTE 3: 因为 views.py 会作为所有视图函数的定义文件, 所以将 main.py 中的视图函数 home() 迁移到该文件中.

    • main.py
from flask import Flask

from config import DevConfig

app = Flask(__name__)
# Import the views module
views = __import__('views') # Get the config from object of DecConfig
app.config.from_object(DevConfig) if __name__ == '__main__':
app.run()
  • NOTE 1: 因为 Flask Server 的 Route 使用 main 模块中查询路由函数(EG. home)的,所以必须将 views 模块中的视图函数(路由函数)导入到 main 模块的全局作用域中。

  • NOTE 2: 因为 views 模块中导入了 main.app 对象,而 main 模块又需要导入 views 模块,所以在 main.py 导入 views.py 之前一定要先生成 main.app 对象,否则会出现 NameError。

为每一张数据表定义视图函数

在设计数据库时, 就将所需要展现的页面和功能模块抽象到一个数据表中, 即每张数据表的数据都会被用于对应的 Jinja 模板中, 所以一般来说会为每张表即每一个不同的 Jinja 模板都定义一个视图函数, 但实际上可以灵活处理. 而且由因为这些视图函数都被 route() 装饰器所装饰,所以同时也充当着路由函数的功能。

  • views.py
@app.route('/')
@app.route('/<int:page>')
def home(page=1):
"""View function for home page""" posts = Post.query.order_by(
Post.publish_date.desc()
).paginate(page, 10) recent, top_tags = sidebar_data() return render_template('home.html',
posts=posts,
recent=recent,
top_tags=top_tags) @app.route('/post/<string:post_id>')
def post(post_id):
"""View function for post page""" post = db.session.query(Post).get_or_404(post_id)
tags = post.tags
comments = post.comment.order_by(Comment.date.desc()).all()
recent, top_tags = sidebar_data() return render_template('post.html',
post=post,
tags=tags,
comments=comments,
recent=recent,
top_tags=top_tags) @app.route('/tag/<string:tag_name>')
def tag(tag_name):
"""View function for tag page""" tag = db.session.query(Tag).filter_by(name=tag_name).first_or_404()
posts = tag.posts.order_by(Post.publish_date.desc()).all()
recent, top_tags = sidebar_data() return render_template('tag.html',
tag=tag,
posts=posts,
recent=recent,
top_tags=top_tags) @app.route('/user/<string:username>')
def user(username):
"""View function for user page"""
user = db.session.query(User).filter_by(username=username).first_or_404()
posts = user.posts.order_by(Post.publish_date.desc()).all()
recent, top_tags = sidebar_data() return render_template('user.html',
user=user,
posts=posts,
recent=recent,
top_tags=top_tags)
  • NOTE 1: 定义视图函数时, 一般会按照下面几点来处理:

    • 获取主要的数据表对象, EG. posts
    • 获取与该表由关联的数据表对象, EG. posts 与 comments 是 one to many 的关系, posts 与 tags 是 many to many 的关系, 所以会 通过 posts 对象来获取 tags 对象和 comments 对象.
    • 最后会补充获取这一 Jinja 模板中仍需要的数据对象, EG. recent/top_tags
  • NOTE 2: flask 提供的 render_template() 函数, 就是将视图函数和 Jinja 模板文件关联起来的桥梁, 该函数的第一个参数就是 Jinja 模板文件的名称字符串, 之后的命名参数就是要传入该模板文件的数据对象, 而这些数据对象就会替代 Jinja 模板中的变量代码块.

  • NOTE 3: 为了提高代码的重用, 将每一个 Jinja 模板文件都会用到的右侧边栏所需要的数据抽象成一个函数.

  • NOTE 4: 在 app.route() 函数中可以定义多样的 URL 路由规则, 也可以为一个视图函数定义多条 URL 路由规则, 在这个 Blog 项目中的 URL 设计应该遵循 RESLful 风格.

最新文章

  1. 一堆LCT板子
  2. docker入门-学习笔记
  3. OracleConnection is obsolete
  4. 浅谈php中使用websocket
  5. redis入侵
  6. Spring web.xml配置文件解析
  7. windows 系统中打开一个数字证书所经历的过程
  8. SQL 2008配置管理工具服务显示 远程过程调用失败0x800706be
  9. 浅谈Redis及其安装配置
  10. SQL常用函数
  11. [原]性能优化之Hibernate缓存讲解、应用和调优
  12. BZOJ 1631: [Usaco2007 Feb]Cow Party
  13. Linux command not found 问题解释
  14. 201521123076 《Java程序设计》第13周学习总结
  15. idea在Terminal中使用maven指令
  16. MySQL基本操作命令
  17. token是干啥子的
  18. WCF Data Services 5.0 for OData V3
  19. MyBatis别名
  20. minimal sparse ruler problem 最少尺子刻度问题

热门文章

  1. JVM调优(三)——基于Btrace的监控调试
  2. phpstorm中sass编译时目录或内容包含中文字符报错
  3. 109、TensorFlow计算张量的值
  4. spring controller使用了@ResponseBody却返回xml
  5. 将js/css脚本放到png图片中的实践。
  6. 如何消去delphi Stringgrid重绘时产生重影
  7. 3天教你掌握Python必备常用英语词汇
  8. DNS 放大
  9. [已解决]报错: Could not install packages due to an EnvironmentError: [Errno 13] Permission denied: &#39;/Users/mac/Ana
  10. CentOS中svn的搭建