flask系列三之Jinja2模板
1、如何渲染模板
- 模板在‘templates’文件夹下(htnl页面)
- 从flask中导入render_template函数---渲染html模板
- 在视图函数中,使用render_template 函数渲染模板。注意:只需要填写模板的名字,不需要填写templates这个文件夹的路径,若在templates下面建立文件夹,则需要填写路径名称。
@app.route('/') def index(): return render_template('index.html')
2、模板传参
(1)如果只有一个或者少量参数,直接在render_template
函数中添加关键字参数就可以了。
(2)如果有多个参数的时候,那么可以先把所有的参数放在字典中,然后在render_template
中, 使用两个星号,把字典转换成关键参数传递进去,这样的代码更方便管理和使用。
(1)变量语法
在HTML文件中
{{ params }}
(2)较少的参数(直接传参数)
<p>你好:{{ username }}</p>
selfprojectName.py中:
@app.route('/') def index(): return render_template('index.html',username='你好') # 模板文件中只有一个变量,直接把参数传进去
(3)很多的参数(特殊的方法传参)
(1)如果只有一个或者少量参数,直接在render_template
函数中添加关键字参数就可以了。
(2)如果有多个参数的时候,那么可以先把所有的参数放在字典中,然后在render_template
中,使用两个星号,把字典转换成关键参数传递进去,这样的代码更方便管理和使用。
index.html中:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>index</title> </head> <body> <p>这是一个模板文件</p> <p>用户名:{{ username }}</p> <p>年龄:{{ age }}</p> <p>性别:{{ gender }}</p> </body> </html>
selfprojectName.py中:
from flask import Flask,render_template app = Flask(__name__) @app.route('/') def index(): context = { 'username' : '站长', 'age' : '18', 'gender' : '男' } return render_template('index.html' , **context) # 定义一个字典,双星号把字典转换成关键参数传递进去 if __name__ == '__main__': app.run(debug=True)
(4)模板中访问模型(类)中的属性和访问字典中的元素
访问模型中的属性或者是字典,可以通过{{params.property}}
的形式,或者是使用{{params['age']}}
index.html中:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>index</title> </head> <body> <p>这是一个模板文件</p> <p>用户名:{{ username }}</p> <p>年龄:{{ age }}</p> <p>性别:{{ gender }}</p> <hr> <p>访问模型(类)</p> <p>用户名:{{ person['name'] }}</p> <p>年龄:{{ person.age }}</p> <hr> <p>访问字典</p> <p>百度:{{ websites.baidu }}</p> <p>谷歌:{{ websites.google }}</p> </body> </html>
selfprojectName.py中:
from flask import Flask,render_template app = Flask(__name__) @app.route('/') def index(): # 定义一个类 class Person(object): name = '老头' age = 22 p = Person() # 实例化对象 context = { 'username' : '站长', 'age' : '18', 'gender' : '男', 'person' : p, # 把模型对象作为参数传进去 # 将一个字典嵌套传参数进去 'websites' : { 'baidu' : 'www.baidu.com', 'google' : 'www.google.com' } } return render_template('index.html' , **context) # 定义一个字典,双星号把字典转换成关键参数传递进去 if __name__ == '__main__': app.run(debug=True)
3、过滤器
过滤器简单理解:
例如:过滤器的作用就是,如果有头像就显示头像,没有头像就显示默认的头像(无头像)
过滤器的作用对象是变量
(1)语法
{{ avatar|default('xxx') }}
(2)default过滤器
实例一(没有过滤器):
selfprojectName.py中:
#encoding: utf-8 from flask import Flask,render_template app = Flask(__name__) @app.route('/') def index(): return render_template('index.html', avatar='http://avatar.csdn.net/9/0/4/3_ly123963.jpg') if __name__ == '__main__': app.run(debug=True)
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>index</title> </head> <body> <p>过滤器模板文件</p> <img src="{{ avatar }}"> </body> </html>
实例二(加上过滤器):
selfprojectName.py中:
from flask import Flask,render_template app = Flask(__name__) @app.route('/') def index(): return render_template('index.html') # 后端不上传图片,前端将加载默认的图片 if __name__ == '__main__': app.run(debug=True)
前端加上过滤器之后。
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>index</title> </head> <body> <p>过滤器模板文件</p> <img src="{{ avatar | default('http://noavatar.csdn.net/B/3/F/3_lighting_miaoxingren.jpg') }}"> </body> </html>
(3)length过滤器
length过滤器主要用于求列表或者字符串或者字典或者元组的长度。比如统计一篇文章评论的总数,一般都是使用过滤器完成的。
实例:
selfprojectName.py中:
from flask import Flask,render_template app = Flask(__name__) @app.route('/') def index(): # 定义一个评论列表 comments = [ { 'user' : '站长', 'content' : u'xxxxxxxxxxxx' }, { 'user' : '你猜', 'content' : u'yxyxyxyxyxy' }, { 'user' : '船长杰克', 'content' : u'tttttttmtmtmtmtd' } ] return render_template('index.html',comments=comments) if __name__ == '__main__': app.run(debug=True)
index.html中
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>index</title> </head> <body> <p>过滤器模板文件</p> <hr> <p>评论数:({{ comments|length }})</p> <ul> {% for comment in comments %} <li> <a href="#">{{ comment.user }}</a> <p href="#">{{ comment.content }}</p> </li> {% endfor %} </ul> </body> </html>
(4)一些常用的过滤器
- abs(value):返回一个数值的绝对值。示例:-1|abs
- default(value,default_value,boolean=false):如果当前变量没有值,则会使用参数中的值来代替。示例:name|default(‘xiaotuo’)——如果name不存在,则会使用xiaotuo来替代。boolean=False默认是在只有这个变量为undefined的时候才会使用default中的值,如果想使用python的形式判断是否为false,则可以传递boolean=true。也可以使用or来替换。
- escape(value)或e:转义字符,会将<、>等符号转义成HTML中的符号。显例:content|escape或content|e。
- first(value):返回一个序列的第一个元素。示例:names|first
- format(value,*arags,**kwargs):格式化字符串。比如:
{{ "%s" - "%s"|format('Hello?',"Foo!") }}
将输出:Helloo? - Foo! - last(value):返回一个序列的最后一个元素。示例:names|last。
- length(value):返回一个序列或者字典的长度。示例:names|length。
- join(value,d=u”):将一个序列用d这个参数的值拼接成字符串。
- safe(value):如果开启了全局转义,那么safe过滤器会将变量关掉转义。示例:content_html|safe。
- int(value):将值转换为int类型。
- float(value):将值转换为float类型。
- lower(value):将字符串转换为小写。
- upper(value):将字符串转换为小写。
- replace(value,old,new): 替换将old替换为new的字符串。
- truncate(value,length=255,killwords=False):截取length长度的字符串。
- striptags(value):删除字符串中所有的HTML标签,如果出现多个空格,将替换成一个空格。
- trim:截取字符串前面和后面的空白字符。
- string(value):将变量转换成字符串。
- wordcount(s):计算一个长字符串中单词的个数。
4、if判断
(1)语法
{% if xxx %} {% else %} {% endif %}
5、for循环遍历字典
1. 字典的遍历
selfprojectName.py中:
@app.route('/') def index(): # 定义一个字典 user = { 'username' : u'站长', 'age' : 22 } return render_template('index.html',user=user)
index.html中
{% for k,v in user.items() %} <p>{{ k }}:{{ v }}</p> {% endfor %}
语法和python
一样,可以使用items()
、keys()
、values()
、iteritems()
、iterkeys()
、itervalues()
2.列表的遍历
selfprojectName.py中:
# for遍历列表 @app.route('/') def index(): websites = ['www.baidu.com','www.google.com'] # 定义一个列表 return render_template('index.html',websites=websites)
index.html中
{% for website in websites %} <p>{{ website }}</p> {% endfor %}
6、继承和block
(1)作用:可以把一些公共的代码放在父模板中,避免写重复的代码
1.语法
父模板:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>{% block title %}{% endblock %}</title> {% block head %}{% endblock %} </head> <div> <h1>其他照旧</h1> </div> {% block MainContainer %}{% endblock %} <body> </body> </html>
子模板:
{% extends 'base.html %} {% block title %} 名字 {% endblock %} {% block head %} <style> 不同的风格文件 </style> <link rel="stylesheet" href=""> <script>不同的脚本文件</script> {% endblock %} {% block MainContainer %} <h1>这里是写具体内容的地方</h1> {% endblock %}
selfprojectName.py中:
from flask import Flask,render_template app = Flask(__name__) @app.route('/') def index(): return render_template('index.html') @app.route('/login') def login(): return render_template('login.html') if __name__ == '__main__': app.run(debug=True)
base.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> .nav-header { background: #3a3a3a; height: 65px; } ul{ overflow: hidden; } ul li{ float: left; list-style: none; padding: 0 10px; line-height: 65px; } ul li a{ color: #ffffff; } </style> </head> <body> <div class="nav-header"> <ul> <li><a href="#">首页</a></li> <li><a href="#">论坛</a> </li> </ul> </div> {% block MainContainer %}{% endblock %} </body> </html>
index.html 中
使用这个模板之后,所有的代码必须写到block里面去!
{% extends 'base.html' %} {% block MainContainer %} <p>这里是首页</p> {% endblock %}
login.html中
{% extends 'base.html' %} {% block MainContainer %} <p>这里是注册页面</p> {% endblock %}
五、URL链接和加载静态文件
通用语法:
url_for('static',filename='路径')
1.url跳转
视图函数中:
@app.route('/login/) def login_function(): return render_template('login.html')
方法一:
html文件里面
<a href="/login/">点击我</a>
方法二(推荐):
html文件里面
<a href="{{ url_for('login_function') }}">点击我</a>
2.加载静态文件
方法一:
html文件里面
<link rel="stylesheet" href="static/css/index.css">
方法二(推荐):
html文件里面
<link rel="stylesheet" href="{{ url_for('static',filename=''css/index.css) }}">
加载图片方法(推荐):
html文件里面:
<img src="{{ url_for('static',filename='images/logo.png') }}">
加载Js文件方法(推荐):
html文件里面:
<script src="{{ url_for('static',filename='js/index.js') }}">