模板引擎
说明:模板文件就是按照一定的规则书写的展示效果的HTML文件 模板引擎就是负责按照指定规则进行替换的工具
模板引擎选择jinja2
一、渲染模板的方法
1、将渲染的模板进行返回
1 |
|
2、渲染字符串返回
1 |
|
实例
1 2 3 4 5 6 |
|
二、模板的语法
模板中只存在俩种语法
1、变量
{{ var }}
1 2 3 |
|
2、标签
{% 标签名 %}
注意:
在模板中使用字典中的键 需要像使用对象得方式来调用
{{data.key}}
如果在模板中给定的变量不存在 则插入的是空字符串 不会报错
三、过滤器
常用的过滤函数
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):计算一个长字符串中单词的个数。
过滤器使用管道符 | 来使用的
1、{{ var|abs }} 返回一个数值的绝对值
2、default 设置默认值
只有当给定的变量不存在时 则执行默认值
当设置default的boolean的时候 会执行默认值
1 |
|
3、first: 取出变量中的第一个字符
4、last: 取出变量中的最后一个字符
5、format: 字符的格式化
1 |
|
6、length: 返回变量值的长度
7、join: 拼接成字符串
1 2 |
|
8、safe: 不转义标签 原样显示
9、lower 转为小写
10、upper 转为大写
11、replace 替换
1 |
|
12、striptages 去除HTML标签
{{ data.html|striptags }}
四、标签
语法格式 :{% 标签名 %}
(1) if
实例
1 2 3 4 5 6 7 |
|
(2) for 循环
实例
1 2 3 4 5 6 7 |
|
注意:
break continue 不能够在这里使用
迭代字典
1 2 3 |
|
获取当前迭代的状态
变量 | 描述 |
---|---|
loop.index | 获取当前迭代的索引 从1开始 |
loop.index0 | 获取当前迭代的索引 从0开始 |
loop.first | 是否为第一次迭代 |
loop.last | 是否为最后一次迭代 |
loop.length | 迭代的长度 |
六、注释
{# 多行注释 #}
七、文件包含 include
相当于把一个文件 拷贝到当前的你的包含的位置
实例
1 2 3 |
|
注意:
1、包含的公共的文件中 只存放 公共的代码 除此以外什么都不要存在
2、导入的时候 如果文件和在同一级别 直接导入就可以 如果包含在某个目录中 需要写出路径
1 2 |
|
八、宏 macro
概念: 类似python中的函数
实例
在macro.html中
1 2 3 |
|
宏的调用
1 2 3 |
|
宏的导入
(1) import
1 2 3 |
|
(2) form import
1 2 3 |
|
注意:
- 宏的调用只能在定义的下方去调用 否则未定义
- 宏如果存在形参 且没有默认值 则可以调用(没意义)
- 形参的默认值 需要遵循默认值规则 有默认值的参数 放右侧
- 可以正常使用 关键字参数
九、继承 extends
语法:
- {% extends %} 继承某个模板
- {% block %} 挖坑和填坑
- {{ super() }} 调用被替换掉的代码
base.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
|
index.html继承 base.html
1 2 3 4 5 6 7 8 9 10 11 12 |
|
注意:
如果当替换某个样式的时候 所有原来的样式 都消失了 去查看是否使用了super()
十、flask-bootstrap
安装
1 2 3 |
|
使用
继承 bootstrap/base.html 基础模板 改造成适用于自己网站的base.html基础模板
自己的base.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
|
使用 index.html
1 2 3 4 |
|
十一、错误页面的定制
manage.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
十二、视图传递多个参数
(1) 原始传参
1 2 3 |
|
(2) 使用字典
1 2 3 4 5 |
|
(3) 使用全局变量g
1 2 3 4 5 |
|
模板中
1 2 3 4 |
|
(4) 使用 **locals()
1 2 3 4 5 6 |
|
模板中
1 2 |
|
十三、url_for 构造绝对的链接地址
1 2 3 4 |
|
十四、加载静态资源
静态资源:图片,css,js,视频,音频,,
实例
1 |
|
十五、基本的项目结构
1.模板继承
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{% block title %}{% endblock %}</title> 盒子1
<!-- <link rel="stylesheet" href="/static/css/commons.css" /> --> 引入 css第一种方式
<link rel="stylesheet" href="{{ url_for('static',filename='css/commons.css') }}" /> 引入css第二种方式
{% block css %}{% endblock %} 盒子2
</head>
<body>
<div class="pg-header"></div>
<div class="pg-body">
{% block body %}{% endblock %} 盒子3
</div>
{% block js %}{% endblock %} 盒子4
</body>
</html>
2.连接数据库
'''
db_pool.py
创建数据库连接池
'''
import time
import pymysql
import threading
from DBUtils.PooledDB import PooledDB, SharedDBConnection
POOL = PooledDB(
creator=pymysql, # 使用链接数据库的模块
maxconnections=6, # 连接池允许的最大连接数,0和None表示不限制连接数
mincached=2, # 初始化时,链接池中至少创建的空闲的链接,0表示不创建
maxcached=5, # 链接池中最多闲置的链接,0和None不限制
maxshared=3,
# 链接池中最多共享的链接数量,0和None表示全部共享。PS: 无用,因为pymysql和MySQLdb等模块的 threadsafety都为1,所有值无论设置为多少,_maxcached永远为0,所以永远是所有链接都共享。
blocking=True, # 连接池中如果没有可用连接后,是否阻塞等待。True,等待;False,不等待然后报错
maxusage=None, # 一个链接最多被重复使用的次数,None表示无限制
setsession=[], # 开始会话前执行的命令列表。如:["set datestyle to ...", "set time zone ..."]
ping=0,
# ping MySQL服务端,检查是否服务可用。# 如:0 = None = never, 1 = default = whenever it is requested, 2 = when a cursor is created, 4 = when a query is executed, 7 = always
host='47.93.4.198',
port=3306,
user='root',
password='123',
database='s6',
charset='utf8'
)
'''
sqlhelper.py
因为每次操作都需要连接连接池,获取游标等,所以把这些操作封装起来
'''
from utils.pool import db_pool
import pymysql
class SQLHelper(object):
def __init__(self):
self.conn = None
self.cursor = None
def open(self, cursor=pymysql.cursors.DictCursor):
self.conn = db_pool.POOL.connection()
self.cursor = self.conn.cursor(cursor=cursor)
def close(self):
self.cursor.close()
self.conn.close()
def fetchone(self, sql, params):
cursor = self.cursor
cursor.execute(sql, params)
result = cursor.fetchone()
return result
def fetchall(self, sql, params):
cursor = self.cursor
cursor.execute(sql, params)
result = cursor.fetchall()
return result
def __enter__(self):
self.open()
return self
def __exit__(self, exc_type, exc_val, exc_tb):
self.close()
'''
login.py
'''
#!/usr/bin/env python
# -*- coding:utf-8 -*-
from flask import Blueprint, request, render_template, redirect, session,current_app
from utils.pool import db_pool
from utils.pool.sqlhelper import SQLHelper
account = Blueprint('account', __name__)
@account.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'GET':
return render_template('login.html')
else:
# 方式一
# helper = SQLHelper()
# helper.open()
# result = helper.fetchone('select * from users where name=%s and pwd = %s',[request.form.get('user'),request.form.get('pwd'),])
# helper.close()
# 方式二:
with SQLHelper() as helper:
result = helper.fetchone('select * from users where name=%s and pwd = %s',[request.form.get('user'),request.form.get('pwd'),])
if result:
current_app.auth_manager.login(result['name'])
return redirect('/index')
return render_template('login.html')
3.应用flask-session
from flask_session import Session
#引入session后,注册app
app = Flask(__name__)
Session(app)
'''
settings.py 配置
'''
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import redis
class BaseConfig(object):
SESSION_TYPE = 'redis' # session类型为redis
SESSION_KEY_PREFIX = 'session:' # 保存到session中的值的前缀
SESSION_PERMANENT = False # 如果设置为True,则关闭浏览器session就失效。
SESSION_USE_SIGNER = False # 是否对发送到浏览器上 session:cookie值进行加密
class ProductionConfig(BaseConfig):
SESSION_REDIS = redis.Redis(host='47.93.4.195', port=6379, password='123123') # 用于连接redis的配置
class DevelopmentConfig(BaseConfig):
SESSION_REDIS = redis.Redis(host='47.93.4.196', port=6379, password='123123') # 用于连接redis的配置
class TestingConfig(BaseConfig):
SESSION_REDIS = redis.Redis(host='47.93.4.197', port=6379, password='123123') # 用于连接redis的配置