这次给大家带来flask
模板是一个包含响应文本的文件,其中包含用占位变量表示的动态部分,其具体值只在请求的上下文中才能知道。使用真实值替换变量,再返回最终得到的响应字符串,这一过程称为渲染。为了渲染模板,Hask使用了一个名为 Jinja2的强大模板引擎。
1.Jinja2模板引擎
形式最简单的 Jinja2模板就是一个包含响应文本的文件
我们先来看一写一个demo
我们先在我们项目的根目录下创建一个名为templates的文件夹
接着我们在templates里面下创建一个index.html的html文件就是我们所说的模板
index.html代码:
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Title</title>
- </head>
- <body>
- <h1>Hello World</h1>
- </body>
- </html>
这是一标准的html5代码,我们在body中放入一个<h1>标签用来输入Hello World,然后我们在去编写python代码在这里我的demo2.py文件和templates文件夹处于同一目录
python 代码:
- #在项目中导入flask
- from flask import Flask,render_template
- app = Flask(__name__)
- @app.route('/')
- def index():
- return render_template('index.html')
- if __name__== '__main__':
- #使用run方法来启动Flask集成的开发Web服务器
- app.run(debug=True)
接着我们来启动项目在浏览器中输入http://127.0.0.1:5000/ 来访问我们的项目,准确的说是访问我们index()的视图函数
可以看到浏览器已经输出了我们的index.html的html内容,在这里index.html就是我们的模板,默认情况下,Fask在程序文件夹中的 templates子文件夹中寻找模板,也就是在demo2.py中index()视图函数里面的render_template()方法根据模板名称去程序文件夹中的 templates子文件夹中寻找模板
刚刚我这边强调了我的demo2.py问价和templates文件是存放在同一目录也就是根目录下面的请看下图
如果我们的demo2.py项目(里面主要编写路由和视图函数)文件和templates问价夹不在同一目录下面会发生什么?接下来我们看一下
首先我在项目根目录下新建一个文件夹取名src,然后在src文件夹下创建一个demo.py的文件里面内容和之前演示的demo2.py文集内容一样然后我么来启动demo.py文件看看运行结果
首先创建src和demo.py文件
demo.py文件内容和之前的demo2.py文件内容一致
接下来我们运行demo.py文件可以看出在pycharm的控制台一切启动正常
接下来打开浏览器访问http://127.0.0.1:5000/ 结果
我们可以看到浏览器并没有返回给我想要的index.html模板页面,而是抛给我们一个错误,从错误的字面意思可以看出是因为找不到我们定义的模板
以后随着我们项目的业务增大肯定不可以将所有的业务路由什么的都写在一个文件里面,我们要根据业务的不同区划分我们的项目文件,如果我们将所有的视图函数和路由文件都放在根文件夹下面,可读性会非常差,维护起来也不方便,至于解决方案,百度上面可以看到很多,我这里比较喜欢这种
我们将demo.py文件内容改为:
- #在项目中导入flask
- from flask import Blueprint,render_template
- demo= Blueprint('demo', __name__, template_folder='pages')
- @demo.route('/')
- def index():
- return render_template('index.html')
然后我再在项目根文件夹下面新建一个run.py文件用他来启动我们的项目
run.py代码:
- from flask import Flask
- from src.demo import demo
- app = Flask(__name__)
- app.register_blueprint(demo, url_prefix='/')
- app.run()
OK!可以看到浏览器成功访问到我们的index.html模板了
具体实现原因和方式的详解在这里,我这边怕讲不好也就不再陈述了点击打开链接,这篇博客是英文的,如果英文不好的朋友可以使用谷歌浏览器打开然后选择翻译成中文即可
接下来我们在回到刚刚的demo2的实例,然后我么可以通过视图函数来给我们的模板进行参数,变量的传递与接收
我们来新建一个user.html的html模板页
user.html页面代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>Hello {{ name }}!</h1>
</body>
</html>
用{{name}}表示传入的变量,{{}}里面放入将要传入变量的名称来获取变量
dome2.py新增一个路由和视图函数
@app.route('/user/<name>')
def yourname(name):
return render_template('user.html',name = name)
路由使用<>的方式来获取地址上的参数
Hask提供的 render template函数把 Jinja2模板引擎集成到了程序中。 render_template函
数的第一个参数是模板的文件名。随后的参数都是键值对,表示模板中变量对应的真实
值。在这段代码中,第二个模板收到一个名为nane的变量
前例中的nane=nane是关键字参数,这类关键字参数很常见,左边的“name”表示参数名,就是模板中使用的占位符;右边的“name”是当前作用域中的变量,表示同名参数的值。
我们来运行一下看下结果在浏览器上访问我们的user路由传入我们参数
{{nane}}结构表示一个变量,它是一种特殊的占位符,告诉模板引擎这个位置的值从渲染模板时使用的数据中获取。Jnja2能识别所有类型的变量,甚至是一些复杂的类型,例如列表、字典和对象。在模板中使用变量的一些示例如下:
<p>A value from a dictionary:{{mydict['key']}}.</p>
<p>A value from a list: {{mylist[3]}}.</p>
<p>A value from a list, with a variable index: {{ mylist[myintvar]}}.</p>
<p>A value from an object's method: {{ myobj.somemethod()}}.</p>
可以使用过滤器修改变量,过滤器名添加在变量名之后,中间使用竖线分隔。例如,下述
模板以首字母大写形式显示变量nane的值,我们来修改user.html
<body>
<h1>Hello {{ name }}!</h1>
<hr>
<h1>Hello,{{name|capitalize}}!</h1>
</body>
我们可以看到传入的参数首字母大写了,下面是Jinja2变量过滤器
控制结构
接下来我们来看一下基本的条件控制语句
我们先来改造一下/user路由的视图函数
@app.route('/user')
def yourname():
name = 'hahah'
return render_template('user.html',name = name)
我们再来改造user.html
<body>
{% if name %}
Hello , {{name}}!
{% else %}
Hello , Stranger!
{% endif %}
</body>
来运行我们的项目
我们将视图函数的name='hahah'改成name='',在来运行我们的项目
这是浏览器就进入else处理块中
另一种常见需求是在模板中渲染一组元素。下例展示了如何使用for循环实现这一需求
<ul>
{% for comment in comments %}
<li>{{ comment }}</li>
{% endfor}
</ul>
Jnja2还支持宏。宏类似于 Python代码中的函数。例如:我们先来改造/user的视图函数
@app.route('/user')
def yourname():
name = [1,2,3,'sss']
return render_template('user.html',name = name)
user.html代码:
<body>
{% macro render_comment(comment)%}
<li>{{comment}}</li>
{% endmacro %}
<ul>
{% for comment in name%}
{{render_comment(comment)}}
{% endfor %}
</ul>
</body>
运行结果
为了重复使用宏,我们可以将其保存在单独的文件中,然后在需要使用的模板中导入
{% include ‘common.html’}
另一种重复使用代码的方式就是模板继承,它类似于python代码中的类继承。
首先我们来定义一个layout.html
模板,这个模板中定义了一个简单的 HTML 文档骨架,您可以 将这个骨架用作一个简单的双栏页面。而子模板负责将空白的块填充上内容:
<!doctype html>
<html>
<head>
{% block head %}
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
<title>{% block title %}{% endblock %} - My Webpage</title>
{% endblock %}
</head>
<body>
<div id="content">{% block content %}{% endblock %}</div>
<div id="footer">
{% block footer %}
© Copyright 2010 by <a href="http://domain.invalid/">you</a>.
{% endblock %}
</div>
</body>
在这个例子中,使用 {% block %}
标签定义了四个子模板可以重载的块。 block 标签所做的的所有事情就是告诉模板引擎: 一个子模板可能会重写父模板的这个部分。
编写子模板:
{% extends "layout.html" %}
{% block title %}Index{% endblock %}
{% block head %}
{{ super() }}
<style type="text/css">
.important { color: #336699; }
</style>
{% endblock %}
{% block content %}
<h1>Index</h1>
<p class="important">
Welcome on my awesome homepage.
{% endblock %}
{% extends %}
标签是这里的关键,它通知模板引擎这个模板继承了另外的模板,当 模板系统解析模板时,他首先找到父模板。 extends
标签必须是模板中的第一个标签。 为了在一个中块显示父模板中定义的对应块的内容,使用 {{ super() }}
。
使用Flask-Bootstrap
这里给大家分享两个链接我就不陈述了 点击打开链接, 点击打开链接如果遇到问题的话可以加我qq讨论一下 1311353736