目录

前文列表

用 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 风格.

用 Flask 来写个轻博客 (11) — M(V)C_创建视图函数的更多相关文章

  1. 用 Flask 来写个轻博客 (15) — M(V)C_实现博文页面评论表单

    目录 目录 前文列表 实现 post 视图函数 在 posthtml 中添加表单 效果 前文列表 用 Flask 来写个轻博客 (1) - 创建项目 用 Flask 来写个轻博客 (2) - Hell ...

  2. 用 Flask 来写个轻博客 (14) — M(V)C_实现项目首页的模板

    Blog 项目源码:https://github.com/JmilkFan/JmilkFan-s-Blog 目录 目录 前文列表 实现所需要的视图函数 实现 home.html 模板 代码分析 实现效 ...

  3. 用 Flask 来写个轻博客 (12) — M(V)C_编写和继承 Jinja 模板

    Blog 项目源码:https://github.com/JmilkFan/JmilkFan-s-Blog 目录 目录 前文列表 扩展阅读 使用 Bootstrap 编写 Jinja 模板文件 继承一 ...

  4. 用 Flask 来写个轻博客 (13) — M(V)C_WTForms 服务端表单检验

    目录 目录 前文列表 WTForms WTF 的基础使用 常用的字段类型 fieldsDateField fieldsIntegerField fieldsFloatField fieldsStrin ...

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

    Blog 项目源码:https://github.com/JmilkFan/JmilkFan-s-Blog 目录 目录 前文列表 Jinja 中常用的过滤器 default float int len ...

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

    #目录 前文列表 扩展阅读 Jinja 变量名 注释 控制语句 if 语句 循环 过滤器 无参数调用 带参数调用 宏 定义宏 调用宏 结果 兼容 JavaScript 前文列表 用 Flask 来写个 ...

  7. 用 Flask 来写个轻博客

    用 Flask 来写个轻博客 用 Flask 来写个轻博客 (1) — 创建项目 用 Flask 来写个轻博客 (2) — Hello World! 用 Flask 来写个轻博客 (3) — (M)V ...

  8. 用 Flask 来写个轻博客 (37) — 在 Github 上为第一阶段的版本打 Tag

    Blog 项目源码:https://github.com/JmilkFan/JmilkFan-s-Blog 目录 目录 前文列表 第一阶段结语 打 Tag 前文列表 用 Flask 来写个轻博客 (1 ...

  9. 用 Flask 来写个轻博客 (36) — 使用 Flask-RESTful 来构建 RESTful API 之五

    目录 目录 前文列表 PUT 请求 DELETE 请求 测试 对一条已经存在的 posts 记录进行 update 操作 删除一条记录 前文列表 用 Flask 来写个轻博客 (1) - 创建项目 用 ...

随机推荐

  1. STM32串口USART1的使用方法和程序

    通用同步异步收发器(USART)提供了一种灵活的方法来与使用工业标准NR 异步串行数据格式的外部设备之间进行全双工数据交换. USART利用分数波特率发生器提供宽范围的波特率选择,支持同步单向通信和半 ...

  2. jenkins实现手动选择分支构建项目-Git Paramater

    先下载插件: Git Paramater 参照: jenkins-参数化构建(三)插件:Git Parameter https://www.cnblogs.com/zhaojingyu/p/98624 ...

  3. Python笔记(九)_切片、列表生成式

    切片 mylist[:3] 取前3位元素,0可省略不写 mylist[-4:] 取后4位元素,0可省略不写 mylist[2:4] 从第2个开始取,取到第4个,但第4个不取,取的元素值为4-2=2 m ...

  4. 详解 CSS 绝对定位

    基本定义和用法 在 CSS 中,position 属性指定一个元素(静态的,相对的,绝对或固定,以及粘性定位)的定位方法的类型. 当设置 position 属性的值为 absolute 时,生成绝对定 ...

  5. Moco 框架以及其在 Web 集成测试的应用

    转自:https://www.ibm.com/developerworks/cn/web/1405_liugang_mocowebtest/ Moco 框架以及其在 Web 集成测试的应用 我们往往将 ...

  6. [Java 教程 03] 我的第一个Java程序

    现在,大家应该都已经安装好jdk环境了吧!是不是已经跃跃欲试,按耐不住心中的小激动了?那我们现在就来写我们java学习生涯中的第一个java程序. 文件相关设置 为了方便后面大家的学习呢?有一点大家还 ...

  7. Springboot2.x整合Redis(一)

    备注: springboto整合redis依赖于spring-boot-starter-data-redis这个jar 一,项目环境和依赖 1.POM.xml配置 <parent> < ...

  8. SSM+Maven使用PageHelper插件分页

    官方网站: https://pagehelper.github.io/docs/howtouse/#2-%E9%85%8D%E7%BD%AE%E6%8B%A6%E6%88%AA%E5%99%A8%E6 ...

  9. 五、通过密码访问API

    通过密码访问API 一.客户端 图: 客户端请求代码: static void Main(string[] args) { Console.WriteLine("确定三个项目都已经启动&qu ...

  10. go语言从例子开始之Example7.switch分支结构

    switch ,方便的条件分支语句 package main import "fmt" import "time" func main() { 一个基本的 sw ...