原文:http://www.catonlinepy.tech/
声明:原创不易,未经许可,不得转载html
经过学习次日的内容,你将会对模板有所了解,而且知道为何要使用模板,以及使用模板有什么好处。这一天的学习内容涉及到的代码都会托管到github上,猫姐再次强调,在学习本课内容时必定要本身尝试手敲代码,遇到问题再到github上去查看代码,若是实在不知道如何去解决问题,能够在日志下面留言说明具体状况。前端
视图函数主要有两个做用,一个是处理业务逻辑,另外一个是给用户返回相关内容。在大型应用中,若是把业务逻辑和返回响应内容放在一块儿的话,这样会增长代码的复杂度,而且也很差维护。因此模板它就承担了视图函数的另一个做用:返回响应内容。这样就能够实现业务逻辑和响应内容的分离,将全部的html代码都存放到模板中,而视图函数中只须要专心处理好业务逻辑便可。python
下面猫姐经过一个简单的例子来展现为何要引入模板,如下是这个例子的代码组织结构:git
(miao_venv) maojie@Thinkpad:~/flask-plan/flask-course-primary$ tree . ├── day2 │ ├── run.py │ └── template_demo │ ├── __init__.py │ └── routes.py └── README.md
首先来创建次日的代码目录,与第一天的课程相似,先激活虚拟环境miao_venv,建立方法都是同样的:github
# 进入到虚拟环境目录,激活虚拟环境 maojie@Thinkpad:~/flask-plan/$source miao_venv/bin/activate # 再到flask-course-primary目录下建立次日的课程day2目录 (miao_venv) maojie@Thinkpad:~/flask-plan/flask-course-primary$ mkdir day2 # 进入day2目录 (miao_venv) maojie@Thinkpad:~/flask-plan/flask-course-primary$ cd day2 # 新建template_demo目录 (miao_venv) maojie@Thinkpad:~/flask-plan/flask-course-primary/day2$ mkdir template_demo # 进入到template_demo目录 (miao_venv) maojie@Thinkpad:~/flask-plan/flask-course-primary/day2$ cd template_demo/ # 在template_demo目录中新建__init__.py文件 (miao_venv) maojie@Thinkpad:~/flask-plan/flask-course-primary/day2/template_demo$ touch __init__.py # 在template_demo包中新建routes.py路由文件 (miao_venv) maojie@Thinkpad:~/flask-plan/flask-course-primary/day2/template_demo$ touch routes.py # 在day2目录下新建run.py文件 (miao_venv) maojie@Thinkpad:~/flask-plan/flask-course-primary/day2/$ touch run.py
在template_demo包的__init__.py中输入以下代码:web
# 如下是__init__.py文件中的代码,咱们逐行进行解释 from flask import Flask # 从flask包中导入Flask类 app = Flask(__name__) # 经过Flask类建立一个app实例 from template_demo import routes # 从template_demo包中导入routes文件里的全部代码
在routes.py文件中输入以下代码,包括响应内容中的HTML代码:flask
# 从template_demo包中导入app实例 from template_demo import app @app.route('/') def index(): user = {'username':'猫姐'} # 创建一个user字典 # 返回HTML格式的响应内容 return ''' <html> <head> <title>Home Page-模板的使用-喵星在线</title> </head> <body> <h1>Hello,''' + user['username'] + '''!</h1> </body> </html>'''
在第一课中,视图函数返回的字符串是“你好,喵星在线”,而今天的课程,经过扩展,return 语句中呈现了完整的HTML代码。若是你们对HTML语言不熟悉,能够在w3school在线教程中进行学习。浏览器
最后在day2目录下run.py文件中输入以下代码:app
from template_demo import app # 从template_demo包中导入app实例 if __name__ == "__main__": app.run(debug=True) # app实例调用本身的run函数 # 解释:debug=True,每次代码有改动时,后台会自动检测到,避免本身每次中止、重启后台程序
用第一课运行程序的方法(python run.py),将程序运行起来,而后在浏览器中打开网址 http://localhost:5000/,查看结果:框架
这样应用就运行起来了。你们有没有发现,若是我后面还想扩展其余功能,index视图函数里面的代码也会相应的变多,而且应用的视图函数和关联的URL也会相应的增长。若是我还想将HTML里面的布局更改一下的话,那我不得不更改每一个视图函数里面的HTML标签,这样是不利于长久管理以及应用的扩张。
因此,这里就出来了模板的概念,模板有助于实现业务逻辑和响应内容之间的分离,是实际项目开发中必须使用的一个技术。在Flask中,模板文件(即html文件)须要单独存放在包内的templates目录下。
在template_demo包中新建templates目录,用来存放模板文件:
(miao_venv) maojie@Thinkpad:~/flask-plan/flask-course-primary/day2/template_demo$ mkdir templates
建立模板文件index.html,并输入HTML代码:
# 建立模板文件index.html (下面是使用touch命令建立的,你们也能够在ide集成开发环境中建立该文件) (miao_venv) maojie@Thinkpad:~/flask-plan/flask-course-primary/day2/template_demo/templates$ touch index.html # 在index.html中输入以下代码,这里title,html_user变量是从视图函数中传进来的 <html> <head> <title>{{ title }}-模板的使用-喵星在线</title> </head> <body> <h1>Hello,{{ html_user.username }}!</h1> </body> </html>
在上面的HTML代码中,惟一值得关注的就是{{ ... }}里面的内容,这些变量都是从视图函数中传递进来的。
要渲染模板文件,还须要从Flask框架中导入render_template()这个函数,以下:
# 在routes.py文件中,从flask库中导入render_template类 from flask import render_template
在视图函数中调用render_template时,须要传入模板的文件名以及模板参数的变量列表。视图函数中进行以下操做,即可使用模板了:
# routes.py文件中输入以下代码 from flask import render_template # 从flask库中导入render_template对象 from template_demo import app # 从template_demo包中导入app实例 @app.route('/') def index(): user = {'username':'猫姐'} # 创建一个user字典 return render_template('index.html', title='HomePage', html_user=user)
在render_template函数中,index.html表示的是模板的文件名。title,html_user表示在模板文件中须要使用的变量。user表示是视图函数中的user变量,user变量赋值给html_user变量,在模板中渲染的就是user变量的值了。这样,routes.py文件中的代码就好看多了,从而就实现了业务代码和前端html代码分离的效果,并且也更便于管理往后愈加复杂的html代码。
用一样的方式运行程序,效果应用和没有使用模板的状况是同样的,以下图
下面咱们介绍一下模板的其它经常使用知识点,主要包括模板中if条件语句的使用,for循环语句的使用以及模板的继承方法。
说到模板中的条件语句,这里不得不说说Jinja2的概念。它是python下被普遍应用的模板引擎,是一种被设计自动生成文档的简单格式。在模板语言中,须要把变量传给模板,而后替换成模板特定位置上的占位变量名。它的使用方法很简单,须要用到两对大的花括号,{{ ... }},它里面传入的是变量名。
而Jinja2的条件语句,使用方法也很简单,它用到的是一对花括号,里面再加两个百分号,像这样{% %}。而后里面能够写if,else,for等,可是以if,for开头,必须有闭合if,for的标签。以下所示:
# jinja2中 if控制语句的使用 {% if title %} {{ ... }} {% else %} {{ ... }} {% endfor %} # jinja2中 for控制语句的使用 {% for i in username %} {{ ... }} {% endfor %}
下面是在模板index.html文件添加一个条件语句的示例:
<html> <head> {% if title %} <title>{{ title }} -模板的使用-喵星在线</title> {% else %} <title>模板的使用-喵星在线</title> {% endif %} </head> <body> <h1>Hello, {{ html_user.username }}!</h1> </body> </html>
若是视图函数给模板传递了title参数,那么它就会走if语句,若是没有传递参数,则会走else语句,而不是显示一个空的标题。在本例中,没有给render_template函数的title参数传入值,因此它会走else语句,效果以下图所示:
要理解Jinja2中是如何在模板中使用循环的,咱们能够在路由函数中增长一些其它的信息,以下面使用posts列表变量保存了一些假的日志信息,并将posts变量传递给了模板文件中将使用的htm_posts变量:
from flask import render_template from template_demo import app @app.route('/') def index(): user = {'username': '猫姐'} # 日志由一个列表组成,其中里面包含两个字典,里面各有author和content字段 posts = [ { 'author': {'username': '猫姐'}, 'content': 'This day is Beautiful day!' }, { 'author': {'username': '猫哥'}, 'content': 'The flower is beautiful!' } ] return render_template('index.html', title='HomePage', html_user=user, html_posts=posts)
在index.html模板文件中,经过上面介绍的for循环语法,完成对htm_posts列表变量中每一篇日志的渲染:
<!DOCTYPE html> <html lang="en"> <head> {% if title %} <title>{{ title }} -模板的使用-喵星在线</title> {% else %} <title>模板的使用-喵星在线</title> {% endif %} </head> <body> <h1>Hello, {{ html_user.username }}!</h1> {% for post in html_posts %} <!--for循环开始--> <div> <p> {{ post.author.username }} says:<b>{{ post.content }}</b> </p> </div> {% endfor %} <!-- for循环结束--> </body> </html>
打开浏览器URL,效果以下图所示:
咱们在写一个web应用时,随着里面的功能增多,代码也会相应的变多,这时可能会有一些重复的HTML代码,为了去除大量重复的代码,这时候出现了模板继承的概念。它也是Jinja2的特性,它的特色就是将模板中相同的部分代码转移到一个基模板中,后面其它模板要使用的时候,只须要继承基模板就能够了。
在template_demo/templates目录下,新建layout.html文件,而后在layout.html中写入以下代码:
# 在templates目录下新建layout.html文件 (miao_venv) maojie@Thinkpad:~/flask-plan/flask-course-primary/day2/templates$ touch layout.html # layout.html文件中写入以下代码: <html> <head> {% if title %} <title>{{ title }} - 模板的使用-喵星在线</title> {% else %} <title>模板的使用-喵星在线</title> {% endif %} </head> <body> {% block content %} {% endblock %} </body> </html>
在这个layout.html模板中,使用block控制块来肯定子模板插入代码的位置。子模板经过引用block能够在里面添加本身想要的内容。
下面index.html文件,能够直接继承layout.html文件中的内容,而无需重复实现这段代码,这样在能够简化index.html里面的内容:
# index.html中改成以下内容 {% extends "layout.html" %} # 继承基模板里面的内容 {% block content %} # 从新填写content块的内容 <h1>Hi, {{ html_user.username }}!</h1> {% for post in html_posts %} <div> <p>{{ post.author.username }} says: <b>{{ post.content }}</b></p> </div> {% endfor %} {% endblock %}
打开浏览器的URL,效果以下图所示:
学习完次日的教程,咱们掌握了以下技能:
第三天的内容,咱们将会带领你们一块儿了解什么是表单,表单如何建立,次日的内容就到这里,喜欢的同窗们能够在下面点赞留言,或是访问个人博客地址:http://www.catonlinepy.tech/ 加入咱们的QQ群进一步交流学习!
你们能够到github上获取今天教程中的全部代码:https://github.com/miaojie19/...
具体下载代码的命令以下:
# 使用git命令下载flask-course-primary仓库全部的代码 git clone https://github.com/miaojie19/flask-course-primary.git # 下载完成后,进入day2目录下面,便可看到今天的代码 cd flask-course-primary cd day2