模版引擎jinja2
1. 什么是Jinja2模板引擎?
- 官方网址: http://docs.jinkan.org/docs/jinja2/
Jinja2 是一个现代的,设计者友好的,仿照 Django 模板的 Python 模板语言。 它速度快,被广泛使用,并且提供了可选的沙箱模板执行环境保证安全: - 1). python的Web开发中, 业务逻辑(实质就是视图函数的内容)和页面逻辑(html件)分开的, 使得代码的可读性增强, 代码容易理解和维护;
- 2). 模板渲染: 在html文件中,通过动态赋值 ,将重新翻译好的html文件(模板引擎生效) 返回给用户的过程。
- 3). 其他的模板引擎: Mako, Template, Jinja2
-
2. Jinja2语法
Jinja2变量显示语法:
{{ 变量名| 函数调用 }}
{{ name }}
{{ url_for() }}
{{ get_flshed_messages() }}
Jinja2变量内置过滤器:
“hello”.lower()
safe 渲染值时不转义
capitalize 把值的首字母转换成大写,其他字母转换成小写
lower 把值转换成小写形式
upper 把值转换成大写形式
title 把值中每个单词的首字母都转换成大写
trim 把值的首尾空格去掉
striptags 渲染之前把值中所有的 HTML 标签都删掉
for循环:
{% for i in li%}
xxx
{% endfor %}
if语句
{% if user == 'westos'%}
xxxx
{% elif user == 'hello' %}
xxx
{% else %}
xxx
{% endif%}
宏的操作
- 相当于函数
如何定义宏?
<!--相当于python里面的定义函数, 后面使用的场景: 分页显示-->
{% macro render(id) %}
<h1>hello world {{ id }}</h1>
{% endmacro %}
如何调用宏?
<!--调用定义好的宏(类似于python中的函数)-->
{{ render(1) }}
{{ render(2) }}
{{ render(3) }}
include包含操作
- 如何使用: {% include “06_inclued.html”%}
模板的继承:
一般网站的导航栏和底部不会变化, 为了避免重复编写导航栏信息;
如何定义模板?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{% block title %} {% endblock %}</title>
</head>
<body>
<div style="width: 100px; height: 200px" > 这是导航栏</div>
{% block body %}
hello
{% endblock %}
<div style="width: 100px; height: 200px" >这是底部</div>
</body>
</html>
如何继承基模板?
{% extends '06_base.html'%}
{% block title %}
继承案例
{% endblock %}
{% block body %}
<span style="color: green">这是最新填的block内容</span>
{% endblock %}
Bootstrap简介
Bootstrap(http://getbootstrap.com/)是Twitter 开发的一个开源框架,
它提供的用户界面组件可用于创建整洁且具有吸引力的网页,而且这些网页还能兼容所有现代Web 浏览器。
为什么需要在Flask中集成Bootstrap?
Flask模板集成Bootstrap。一般情况下Flask都是搭配Jinja2模板引擎来实现视图展现,
不过现在Bootstrap比较流行,内置的样式也比较好看,有利于提高开发效率.
Flask中如何使用集成的Bootstrap?
要想在程序中集成Bootstrap,显然要对模板做所有必要的改动。
不过,更简单的方法是使用一个名为Flask-Bootstrap 的Flask 扩展,简化集成的过程。
Flask-Bootstrap 使用pip安装:
pip install flask_bootstrap
Flask 扩展一般都在创建程序实例时初始化,Flask_Bootstrap的初始化方法:
from flask_bootstrap import Bootstrap
bootstrap = Bootstrap(app)
初始化Flask-Bootstrap 之后,就可以在程序中使用一个包含所有Bootstrap 文件的基模板base.html。
这个模板利用Jinja2 的模板继承机制,让程序扩展一个具有基本页面结构的基模板,其中就有用来
引入Bootstrap 的元素。
- Jinja2 中的extends 指令从Flask-Bootstrap 中导入bootstrap/base.html, 从而实现模板继承。
- Flask-Bootstrap 中的基模板提供了一个网页框架,引入了Bootstrap 中的所有CSS 和JavaScript 文件。
- 基模板中定义了可在衍生模板中重定义的块。block 和endblock 指令定义的块中的内容可添加到基模板中。
{%extends "bootstrap/base.html"%}
{%block title %}Flask{% endblock %}
{%block navbar %}
<div class="navbar navbar-inverse" role="navigation">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle"
data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/">Flasky</a>
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li><a href="/">Home</a></li>
</ul>
</div>
</div>
</div>
{% endblock %}
{% block content %}
<div class="container">
<div class="page-header">
<h1>Hello,你好!</h1>
</div>
</div>
{% endblock %}
Bootstrap警告框组件
<div class="alert alert-success" role="alert">...</div>
<div class="alert alert-info" role="alert">...</div>
<div class="alert alert-warning" role="alert">...</div>
<div class="alert alert-danger" role="alert">...</div>
<div class="alert alert-warning alert-dismissible" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button>
<strong>Warning!</strong> Better check yourself, you're not looking too good.
</div>
Flask-Bootstrap自定义模板块
Flask-Bootstrap 的base.html 模板还定义了很多其他块,都可在衍生模板中使用,下表列出了所有可用的块:
Flask-Bootstrap自定义模板块的继承实现
上表中的很多块都是Flask-Bootstrap 自用的,如果直接重定义可能会导致一些问题。例如,Bootstrap 所需的文件在styles 和scripts 块中声明。如果程序需要向已经有内容的块中添加新内容,必须使用Jinja2 提供的super() 函数。例如,如果要在衍生模板中添加新的JavaScript 文件,需要这么定义scripts 块:
{% block scripts %}
{{ super() }}
<script type="text/javascript" src="my-script.js"></script>
{% endblock %}
为什么需要使用Flask-Mail组件?
在我们开发完web系统后,一些特定的事件发生时,系统要自动发送相关邮件至管理员,运维人员和其他相关人员。
python标准库中的smtplib包也可以用在Flask程序中发送邮,但包装了smtplib的flask-mail扩展能更好地
和Flask集成。
如何使用flask-mail扩展发送邮件?
- 安装flask-mail扩展
pip install flask-mail
- 查看安装情况
pip show flask-mail
发送邮件的时候需要设置什么?
- 发件人账户
- 密码
- 收件人
- 邮件标题
- 邮件正文
- QQ邮件服务器的域名或者IP;
详细代码
"""
Date: 2019--29 13:32
User: yz
Email: 1147570523@qq.com
Desc:
"""
from flask_mail import Mail,Message
from flask import Flask, render_template, request, flash, redirect
app = Flask(__name__)
app.config.from_pyfile('config.py')
def send_mail(to, subject,filename,**kwargs):
mail = Mail(app)
msg = Message(subject=subject,
sender='1147570523@qq.com',
recipients=to,
)
msg.html=render_template(filename+'.html',**kwargs)
with app.app_context():
mail.send(msg)
@app.route('/register/',methods=['POST','GET'])
def register():
if request.method=='GET':
return render_template('register.html')
else:
email=request.form.get('email')
try:
send_mail(to=[email],subject='注册通知邮件',filename='registerok',username=email)
except Exception as e:
flash('注册失败')
print(e)
return redirect('/register/')
else:
flash('注册成功')
return redirect('/login/')
@app.route('/login/')
def login():
return 'login'
if __name__ == '__main__':
app.run()
配置信息config.py代码:
# 配置发送邮件的相关信息;
# 指定邮件服务器的域名或者IP https://service.mail.qq.com/cgi-bin/help?subtype=1&&id=28&&no=369
MAIL_SERVER = 'smtp.qq.com'
# 指定端口, 默认25, 但qq邮箱默认为
MAIL_PORT = 465
MAIL_USE_SSL = True
MAIL_USERNAME = '1147570523'
# 此处的密码并非邮箱登录密码, 而是开启pop3
MAIL_PASSWORD = 'jduqsefulccwjcec'
DEBUG=True
SECRET_KEY='redhat'
Flask表单操作
Form表单,在Web应用中无处不在。比如: 用户登录表单, 用户注册表单。
- 所有的表单项都有共性,比如有文字输入框,单选框,密码输入框等;
- 表单的验证也有共性,比如有非空验证,长度限制,类型验证等。
如果有个框架,能把这些共性抽象出来,那就能大量简化我们的工作。Python的 WTForms 就提供了这
些功能,这里我们就要结合Flask的 WTForms 扩展, Flask-WTF ,来介绍如何在Web应用中制作表单。
安装和启用:pip install Flask-WTF
常见的表单域类型
常见验证规则
案例代码:
from flask import Flask, request, render_template, flash
from forms import LoginForm, RegisterForm
from flask_bootstrap import Bootstrap
app = Flask(__name__)
app.config.from_pyfile('config.py')
bootstrap = Bootstrap(app)
@app.route('/login/', methods = ['GET', 'POST'])
def login():
# 1. 实例化表单对象
form = LoginForm()
# 1). 是否为post提交表单信息;
# 2). 是否通过验证函数?
if form.validate_on_submit():
# 获取表单的内容
email = form.email.data
password = form.password.data
if email =='westos@qq.com' and password=='westos':
return '登录成功'
else:
return "登录失败"
else:
return render_template('bs_login.html', form=form)
@app.route('/register/', methods = ['GET', 'POST'])
def register():
form = RegisterForm()
if form.validate_on_submit():
return '获取性别%s' %(form.gender.data)
else:
return render_template('register.html', form=form)
if __name__ == '__main__':
app.run()
表单代码:
"""
表单文件
"""
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField, SelectField, SelectMultipleField
from wtforms.validators import DataRequired, Length, Email, EqualTo, Regexp, ValidationError
class LoginForm(FlaskForm):
email = StringField(label="电子邮箱",
validators=[
DataRequired(message='邮箱不能为空'),
Length(1, 15, message="长度不符合条件"),
Email(message='请输入有效的邮箱地址,比如:username@domain.com')
])
password = PasswordField('密码',
validators=[
DataRequired(message=u'密码不能为空')])
submit = SubmitField(u'登录')
class RegisterForm(FlaskForm):
# StringField <input type='text' name='name' required>
# PasswordField <input type='password' name='password' required>
name = StringField(
label="用户名",
# 验证: 用户名不能为空的
validators=[DataRequired(message='用户名不能为空'),Length(5, 12, message="用户名长度必须在5-12之间") ]
)
password = PasswordField(
label="密码",
validators=[
DataRequired(),
# 验证密码长度是否为6~8之间, 如果不是, 则报错;
Length(6, 16, message="密码格式不正确"),
]
)
repassword = PasswordField(
"确认密码",
validators=[
DataRequired(),
# 验证当前表单输入的内容和password这个表单输入的内容是否一致, 如果不一致, 报错;
EqualTo('password', message="密码不一致")
]
)
效果显示: