什么是Jinja2,Jinja2起什么作用
Jinja2是Python下一个被广泛应用的模版引擎,且它自带一个感觉挺nb的转义功能
作用1.它起了让前端和后端分离的作用
2.减少了Flask项目代码的耦合性,页面逻辑放在模板中,业务逻辑放在视图函数中,
3.提供控制语句/继承等高级功能
//Jijon的默认渲染路径是从template中找如果要改变,可以在Flask初始化的时候指定template_folder进行指定模板的路径
2.模板的渲染、传参要渲染一个模板,可以通过render_template方法
render_template('xxx.html')
传参:
render_template('index.html',uanme(key)='momo')
页面取参
{{key}}
当传递多个参数的时候可以将其以字典的形式封装,
count={
'name':'xxx',
'passwrod':'ppp',
'age':'18',
'shen':{
'xxx':'ttt' //总有闲人喜欢在搞点特殊调用的时候通过shen.xxx
}
}
render_template('xxx.htm',**count) //**可以将字典打散,然后直接掉key值就行,不用再加字典名称
3.模版中使用url_for模版中的`url_for`跟我们后台视图函数中的`url_for`使用起来基本是一模一样的。也是传递视图函数的名字,也可以传递参数。使用的时候,需要在`url_for`左右两边加上一个`{{ url_for('func') }}`
通常在a标签中使用{ url_for('func') }}'>
url_for后面跟着的两种参数传值
1.路径传值: {# /account/login/tantan/ 其中tantan为路径参数 #}
{ url_for('login',name='tantan') }}">登录4
2.查询字串传值:
{# /account/login/tantan/?p1=lol&p2=daota #}{ url_for('login',p1='lol',p2='daota',name='tantan') }}">登录5
只用name的值作作为key键值名转换为变量,其余的都是直接默认加在后面的参数
4.过滤器:简单对参数进行一些处理然后在返回出去使用方法:在调用的后面加‘|’字符
基本语法:`{{ variable|过滤器名字 }}`。使用管道符号`|`进行组合。
{{ postion|abs}}
//常用发过滤器的种类及作用:default(value,default_value,boolean=false):如果当前变量没有值,则会使用参数中的值来代替。name|default('xiaotuo')——如果name不存在,则会使用xiaotuo来替代。boolean=False默认是在只有这个变量为undefined的时候才会使用default中的值,如果想使用python的形式判断是否为false,则可以传递boolean=true。也可以使用or来替换
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='+'):将一个序列用d这个参数的值拼接成字符串。
所谓的宏就是类似于自定义函数,可以把常用的代码封装然后只管往其中添加值就行,
一般格式{% macro xxx() %}
{% macro input(name,value="",type="text") %}
在实际开发中我们不会在html显示的页面中写宏,而是在templates下面创建一个文件夹去写
写完之后在直接导入就行,导入一共有两种方式
1。{% from ‘宏文件的路径’ import input(这个是你刚才宏里面mocro 后面的名)as xxx %}
2.{% import "文件路径" as macros(宏文件路径 ) with context %}
这时宏文件可以使用这种界面上面的函数值,这就是context的作用,可以让两者共享函数
6.Jinja中的导入在实际编写代码的时候,我们往往将相同的代码 单独提取出来,在使用的时候在进行导入
这时候导入的方法就有
1.include标签:
1.include标签相当于直接将指定的模板中的代码复制到当前位置,在include中使用父类末班的变量可以直接使用,不需要在with context
2.include与import一样也是基于templates
语法:
{% include “xx/xx.html“” %}
7.Jinja中的变量定义set与withset语句:set相当于gloat全局定义
with则相当于局部定义
所以set是单行语句,定义完了就不管了而with是双行语句其变量要在其作用域中生效
{% set name=‘momo’ %}
用户名 {{ name}}>
{% with classroom='nnn' %}
<>
{% endwith %}
8.加载静态文件如:css,js文件,图片文件
加载静态文件使用时url_for函数,第一参数需要传入state第二个传入文件的路径
语法:
{{ url_for ("static",filename='xxxx')}}
所以静态文件要存放了state库中
9.Jinja的高级开始了1.模板继承
为什么要继承:将公用的代码抽取出来,低耦合高内聚
模板继承语法:extends语句,继承父类模板,父类模板基于tempaltes
{% extends "base.html" %}
父类的接口block
就是接口函数,在父类模板中{% block block接口名称 %}
{%endblock %}
在子模板中{% block block的名字 %}
子模板中的代码
{% endblock %}
父类中的block下面也可以写代码,如果子类重写那么父类的将会被覆盖,如果子类的需要增添那么要调用父类的模板中的代码使用super(),这个super在什么时候调用都可以,而且可以更灵活方便的实现插入
{{ super() } }
10.没想到 这才是真正的高级的开始 标准类视图 (1).add_url_rule和app,route的原理解析.add_url_rule(rule,endpoint=None,view_func=None)
rule为url路径,endpoint为命名映射,view_func为绑定函数
add_url_rule是用于添加视图函数与url的映射的,在add_url_rule中如果设置了endpoint使用endpoint 后面指定的字符串进行调用,如果没有则使用view_func进行设置
`app.route(rule,**options)`装饰器:
这个装饰器底层,其实也是使用`add_url_rule`来实现url与视图函数映射的。
(2).使用:标准类视图
首先定义一下类视图。之前使用app。route调用都是函数视图
使用类视图的最主要好处就是可以进行继承,但类视图需要使用app.url_add_rule()来进行注释绑定
使用步骤:
1.继承flask.views.View
2.实现dipatch_request方法,用于接收请求返回对象
3.通过app.url_add_rule()来绑定视图映射,其中view_func这个函数需要使用视图类下面的as_view类方法进行转换:ListView.as_view('list')
4.如果使用了endpoint,那么在使用url_for反转的时候,必须使用endpoint指定的那个值
(3).基于调度方法的类视图
所谓基于调度就是在类视图中编写post与get方法同时处理两种请求方法
1.根据请求的method来执行不同的方法,如果用户发送get请求,那么就执行类的get方法,如果是post请求,就执行类的post方法。
这种方式可以让代码更加简洁,无需在通过request.method==''方法进行调用
(4).类装饰器的使用
装饰器就是@后面修饰的。,python里面给封装完成了很多了装饰器,但有的时候还不能满足开发的需求,所以需要我们自定义装饰器
官方话语:python装饰器就是用于拓展【原来函数功能】的一种函数,这个【函数的特殊之处在于它的返回值也是一个函数】
定义方法:
基于函数视图的使用
1.首先定义一个方法传递值fun,在方法中在定义一个方法用于实现对数据的加工,形参为(*args元组,**kwagrs字典两种)
//可以给方法加上装饰器@wraps(func)这个装饰器可以确保参数专递的安全
最后return 定义的方法
2.在需要使用的函数上直接@加定义方法名称即可
在视图函数中使用自定义装饰器,那么自己定义的装饰器必须放在`app.route`下面。否则这个装饰器就起不到任何作用。
基于类视图的使用
基于类视图的使用需要重写类视图中的decorators方法
后面参数可以为元组也可以为字典形式传递
11.蓝图
基本定义:
所谓蓝图就是将Flash模块化的工具,让其url与视图函数相分离
语法:
1.首先创建一个总的蓝图文件夹blueprints并且在里面创建一个个蓝图模块并且导入蓝图
form flash import Blueprint
2,创建蓝图对象
use_up = Blueprint('蓝图模块名',__name__)
并在蓝图对象中创建蓝图模块的功能
定义函数,放问路径绑定使用@蓝图对象.route
3.在主类中app中注册蓝图
首先将蓝图对象在主类中导入,from flask import 蓝图模块.蓝图创建对象
app.register_blueprint(user_bp(l蓝图的对象名))
//此时,这中访问还无法区分模块,所有的访问都是i直接使用蓝图.route的路径进行访问的,
要想进行模块化访问可以在创建蓝图对象的时候加上url_preifix='/xxx'表示前缀
蓝图的找寻规则:
动态文件:
* 如果项目中的templates文件夹中有相应的模版文件,就直接使用了。
* 如果项目中的templates文件夹中没有相应的模版文件,那么就到在定义蓝图的时候指定的路径中寻找。并且蓝图中指定的路径可以为相对路径,相对的是当前这个蓝图文件所在的目录。比如:
news_bp = Blueprint('news',__name__,url_prefix='/news',template_folder='news_page')
简单来说就是当你在蓝图模块中使用tempalte_folder进行蓝图文件位置定义的时候,它仍然是
先从templates中查找没有,在定义蓝图的时候在蓝图指定的路径中查找
蓝图中静态文件的查找规则:
当蓝图中文件链接使用url_for进行文件绑定的时候,如果使用的是static
那默认还是app下面的static文件中去找
但如果是蓝图模块名称.static那么就必须去蓝图模块设置的template_folder中去查找
//蓝图反转时候的注意事项:
如果使用蓝图,那么以后想要反转蓝图中的视图函数为url,那么就应该在使用url_for的时候指定这个蓝图名字。 app类中、模版中、同一个蓝图类中都是如此。否则就找不到这个endpoint。
子域名实现详解:



