摘要:例子如下语法一般在父模板中只能定义一些共性公用的代码,子模板可能要根据不同的需求实现不同的代码。这时候父模板就应该提供一个接口,让子模板来实现。
flask之二 预热
在渲染模板的时候,默认会从项目根路径下的templates目录下查找模板
如果想要指定模板路径的时候,就在初始化APP的时候,这样操作即可:
app = Flask(__name__,template_folder="C:/templates") #template_folder可以指定模板位置模板传参
在使用render_template渲染模板的时候,可以传递关键字参数,以后直接在模板中使用就可以了
如果参数过多的话,那么就可以将所有的参数放到一个字典中,然后再传这个参数的时候使用**将字典打散成关键字参数。
小例子:
my_template.py
from flask import Flask,render_template app = Flask(__name__) app.debug = True @app.route("/") def hello_world(): context = { "username": "wanghui", "age":19, "children":{ "user":"ccc", "type":"stu", } } return render_template("index.html", **context) # return render_template("index.html",context=context) # return render_template("index.html",username="wanghui",age=19) if __name__ == "__main__": app.run()
templates/index.html
模板中的url_formy blog 这是模板渲染的数据
{#{{ username }}
#} {#{{ age }}
#} {{ context.username }} {{ context.age }}{{ username }}
{{ children.user }}
模板中的url_for和视图函数中的url_for是类似的,也是传递视图函数的名字,也可以传递参数。使用的时候,需要在url_for两边加上一个{{ url_for("func_name"),ref="/",id="1"}}
templates.py
from flask import Flask,render_template,url_for app = Flask(__name__) app.debug = True @app.route("/") def hello_world(): return render_template("index.html") @app.route("/accounts/login//") def login(id): return render_template("login.html") if __name__ == "__main__": app.run(port=8888)
templates/index.html
my blog 这是从模板中渲染的
templates/login.html
过滤器Login page 这是登录页面
{#{{ 用来存放变量 }}#} {#{% 用来执行函数或者逻辑代码 %}#}
有时候我们需要在模板中对一些变量进行处理,那么就必须要类似于python中的函数一样,可以将这个值传到函数中,然后做一些操作。在模板中过滤器相当于是一个函数,把当前的变量传入到过滤器中,然后过滤器会根据自己的功能,再返回相应的值,之后再将结果渲染到页面上。
基本语法:{{ variable |过滤器的名字 }}
guo
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):计算一个长字符串中单词的个数。
default过滤器详解:
如果某个变量使用方式是{{ value|default("默认值")}},如果value这个key不存在的话就使用过滤器提供的默认值;如果类似于python中判断一个值是否为False(例如:空字典,空字符串,空列表的话)那么久必须要传递另外一个参数{{ value | default("默认值",boolean=True)}};
可以使用or来替换default("默认值",boolean=True)(例如{{ siginature or "此人很懒没有留下任何说明"}})
例子:
defaulte_falter.py
from flask import Flask,render_template app = Flask(__name__) @app.route("/") def index(): context = { "position":-9, "signature":"", #"signature":"this ismy blog" } return render_template("index.html",**context) if __name__ == "__main__": app.run(debug=True)
templates/index.html
MyBlog {#个性签名:{{ signature|default("此人很懒没有留下任何说明!",boolean=True) }}
#}个性签名:{{ signature or "此人很懒没有留下任何说明!"}}
esacape:转义过滤器
safe过滤器:可以关闭一公分字符串的自动转义
escape过滤器:对某个字符串进行转义
autoescape过滤器:可以对其代码框内的代码块关闭自动转义
first:返回序列中的第一个元素
last:返回序列中的最后一个元素
format:格式化输出
length:长度计算
int:转换成整数
replase:旧字符串换成新的
truncate:指定长度截取(结合striptags去除掉html字段之后截取纯净字符串然后按字数去做预览页填充)
striptags:去除标签中的html字段
worldcount(s):统计一个长字符串中的单词数
小例子:
escape.py
from flask import Flask,render_template app = Flask(__name__) @app.route("/") def hello_world(): context = { "position":-9, "signature":"", "persons":["abc","def"], "age":"18", "article":"hello hello xxooo xxooo!!" } return render_template("index.html",**context) if __name__ == "__main__": app.run(debug=True,port=8080)
templates/index.html
自定义模板过滤器MyBlog {#{% autoescape off %}#} {#个性签名:{{ signature }}
#} {#{% endautoescape %}#}{{ signature|safe }}
{{ persons|first }}
{{ persons[0] }}
{{ persons|last }}
{{ persons[-1] }}
{{ "我的名字是%s"|format("hello word!") }}
{{ "人数是 %d"|format(persons|length) }}
{% if age|int == 18 %}年龄是18岁
{% else %}年龄不是18岁
{% endif %}{{ article|replace("hello","sssssz") }}
{{ article|truncate(length=5) }}
{{ signature|striptags }}
在python文件中写好自己的过滤器(本质上就是一个函数)
如果要在模板中调用这个过滤器,那就需要在这个函数上加一个装饰器@app.template_filter("过滤器名称")
自动加载的话就在app下添加
app.config["TEMPLATES_AUTO_RELOAD"] = True
小例子:
define_filter.py
from flask import Flask,render_template app = Flask(__name__) app.config["TEMPLATES_AUTO_RELOAD"] = True @app.route("/") def hello_world(): context={ "article":"anyway hello anyway hello abccc" } return render_template("index.html",**context) @app.template_filter("cut") def cut(value): vaule = value.replace("hello","sbsb") return value if __name__ == "__main__": app.run(debug=True,port=9090)**
templates/index.html
实战自定义过滤器myblog {{ article|cut }}
时间处理(从现在到发帖的时间差)
shizhan.py
from flask import Flask,render_template from datetime import datetime app = Flask(__name__) app.config["TEMPLATES_AUTO_RELOAD"] = True @app.route("/") def index(): context={ "article":"aaa bbb ccc", "create_time":datetime(2018,02,23,10,12,11) } return render_template("index.html",**context) @app.template_filter("handle_time") def handle_time(time): """ 1.距离现在的时间多久,如果间隔在一分钟以内就表示刚刚 2.在一小时以内就显示xx分钟前 3.在24小时以内就显示xx小时前 4. 在一个月之内就显示多少天之前 5. 否则就显示具体的时间 :param time: :return: """ if isinstance(time,datetime): now = datetime.now() timestamp = (now - time).total_seconds() #获取间隔秒数 if timestamp < 60: return "刚刚" elif timestamp >=60 and timestamp<= 60*60: minutes = timestamp/60 return "%s分钟前",int(minutes) elif timestamp >= 60*60 and timestamp <= 60*60*24: hours = timestamp/(60*60) return "%s小时前",int(hours) elif timestamp >= 60*60*24 and timestamp<= 60*60*24*30: days = timestamp/(60*60*24) return "%s天前",int(days) else: return time.strftime("%Y-%m-%d %H:%M") if __name__ == "__main__": app.run(port=9092,debug=True)
templates/index.html
条件判断 For循环MyBlog 发表时间:{{ create_time|handle_time }}
在jinjia2中的for循环,跟python中的for循环基本是一致的,也是用for in形式;
而且可以便利所有的序列以及迭代器,但是唯一不同的是jinjia2中的for循环没有break和continue
小例子:
for_ex.py
from flask import Flask,render_template app = Flask(__name__) @app.route("/") def hello_world(): context = { "users":["user01","user02","user03"], "person":{ "username":"wanghui", "age":21, "country":"china", }, "books":[ { "name":"sk1", "author":"saa", "price":100, }, { "name": "aaaeede1", "author": "se232aa", "price": 103, }, { "name": "AAAew", "author": "VVVeqwea", "price": 190, }, { "name": "skfdfds1", "author": "sdfsfsdfdaa", "price": 30, } ] } return render_template("index.html",**context) if __name__ == "__main__": app.run(debug=True)
templates/index.html
MyBlog
{{ user }}
{% endfor %}用户名 | 年龄 | 国家 | ||
---|---|---|---|---|
{{ value }} | {% endfor %}
ID | 书名 | 作者 | 价格 | 总数 |
---|---|---|---|---|
{{ loop.index }} | {{ book.name }} | {{ book.author }} | {{ book.price }} | {{ loop.length }} |
{{ y }}*{{ x }}={{ x*y }} | {% endfor %}
模板中的宏跟python中的函数类似,可以传递参数,但是不能有返回值
使用宏的时候,参数可以是默认值
小例子:
macro.py
from flask import Flask,render_template app = Flask(__name__) app.config["TEMPLATES_AUTO_RELOAD"] = True app.config["DEBUG"] = True @app.route("/") def hello_world(): return render_template("index.html") if __name__ == "__main__": app.run(port=9999)
templates/index.html
Macro {% macro input(name="",value="",type="text") %} {% endmacro %}登陆页面
用户名: | {{ input("username") }} |
密码: | {{ input("password",type="password") }} |
{{ input(value="提交",type="submit") }} |
在真实的开发中,会将一些常用的宏多带带放在一个文件中,在需要使用的时候,再从这个文件中进行导入。
import语句的用法跟python中的import类似,可以直接import...as...,也可以from...import...或者from...import...as...,假设现在有一个文件,叫做forms.html,里面有两个宏分别为input和textarea,如下:
注意事项:
a. inport宏文件 as xxx
b. from 宏文件路径 import 宏的名字 [as xxx]
c. 宏文件的路径,不要以相对路径去找,都要以templates作为绝对路径去找
d. 如果想要在导入宏的时候,就把当前末班的一些参数传递给宏所在的模板,那么就应该在导入的时候使用
with context
小例子:
macros.py
from flask import Flask,render_template app = Flask(__name__) app.config["TEMPLATES_AUTO_RELOAD"] = True app.config["DEBUG"] = True @app.route("/") def hello_world(): return render_template("index/index.html") if __name__ == "__main__": app.run(port=9999)
templates/macros/macros.html
{% macro input(name="",value="",type="text") %} {% endmacro %}
templates/index/index.html
{#{% from "macros.html" import input as inp %}#} {% import "macros/macros.html" as macros with context %}Macro 登陆页面
用户名: | {{ macros.input("username") }} |
密码: | {{ macros.input("password",type="password") }} |
{{ macros.input(value="提交",type="submit") }} |
这个标签相当于是将指定模板中的代码复制粘贴到当前的位置
include标签,如果要继续使用父模板中的变量,直接用就可以了
include的路径也和import一样,需要从templates为根,不要以相对路径去找。
小例子:
include_ex.py
from flask import Flask,render_template app = Flask(__name__) app.config["TEMPLATES_AUTO_RELOAD"] @app.route("/") def hello_world(): return render_template("index.html",username="wanghui") @app.route("/detail/") def detail(): return render_template("course_detail.html") if __name__ == "__main__": app.run(debug=True)
templates/index.html
MyBlog {% include "common/header.html" %}中间的{% include "common/footer.html" %}
templates/course_detail.html
Title {% include "common/header.html" %}文章详情!{% include "common/footer.html" %}
templates/common/header.html
templates/common/footer.html
set with语句在模板中,可以使用set来定义变量;一旦定义了这个变量。那么在后面的代码中,都可以使用这个变量。
with语句定义的变量,只能在with的代码块中使用。超出with代码块,则不能使用
with不一定要跟一个变量,也可以是一个空的with语句,以后要用的话,就在with中使用set定义的变量来使用。
{% set username="wanghui" %}加载静态文件用户名:{{ username }}
{% with %} {% set classroom="2018" %}班级:{{ classroom }}
{% endwith %}别的班级{{ classroom }}
加载静态文件使用的是url_for函数,第一个参数为static,第二个参数是filename="path"
路径查找要以static目录作为根目录
小例子:
static_ex.py
from flask import Flask,render_template app = Flask(__name__) app.config.update({ "DEBUG":True, "TEMPLATES_AUTO_RELOAD":True, }) @app.route("/") def hello_world(): return render_template("index.html") if __name__ == "__main__": app.run()
static/css/index.css
body{ background: pink; }
static/js/index.js
alert("hello user!")
static/imgs/sas.jpg
图片
templates/index.html
模板继承 为什么需要模板继承?Title
可以将一些公用的代码多带带抽取出来放到一个父模板中,以后子模板直接继承就给可以使用了。
这样可以减少重复性的代码,并且以后代码修改起来也很方便
模板继承的语法使用extends语句来指明继承的父模板。父模板的路径也就是相对于templates文件夹下的绝对路径。例子如下{% extends "base.html" %}
block语法一般在父模板中只能定义一些共性公用的代码,子模板可能要根据不同的需求实现不同的代码。这时候父模板就应该提供一个接口,让子模板来实现。从而实现业务的具体功能。
在父模板中
{% block body_block %}我是base下的
{% endblock %}
在子模板中
{% block body_block %}调用父模板代码block中的代码我是index的内容
{% endblock %}
默认情况下,字幕版实现了父模板定义的block,那么子模板中block的代码就会覆盖掉父模板中的代码,要想保留父模板中的block的话就是用{{ super() }}来实现
父模板的内容:
{% block body_block %}base.html
{% endblock %}
子模板中的内容:
{% extends "base.html" %} {% block body_block %} {{ super() }}调用另外一个block中的代码我是index的内容
{% endblock %}
在另外一个模板中使用其他模板中的代码,可以使用{{ self.blockname() }}即可
父模板
{% block title %} {% endblock %} {% block body_block %}base.html
{% endblock %}
子模板:
{% extends "base.html" %} {% block title %} MyIndex {% endblock %} {% block body_block %} {{ super() }} {{ self.title() }}其他注意事项我是index的内容
{% endblock %}
继承的代码必须放在子模板中的第一行{% extends "base.html" %}
子模板中要实现自己的代码,要放到block中,不然不生效
继承的例子:inherit_ex.py
from flask import Flask,render_template app = Flask(__name__) app.config.update({ "DEBUG":True, "TEMPLATES_AUTO_RELOAD":True }) @app.route("/") def index(): return render_template("index.html") @app.route("/detail/") def detail(): return render_template("course_detail.html") if __name__ == "__main__": app.run()
templates/base.html
{% block title %} {% endblock %} {% block body_block %}base.html
{% endblock %}
templates/index.html
{% extends "base.html" %} {% block title %} MyIndex {% endblock %} {% block body_block %} {{ super() }} {{ self.title() }}我是index的内容
{% endblock %}
templates/course_detail.html
{% extends "base.html" %} {% block body_block %}this is course
{% endblock %}
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/41667.html
摘要:使用导出端口,使用挂载数据卷。清理应用使用一键清理应用总结已经实现了容器扩容自动挡更直观的控制容器启动顺序及依赖。从部署到编排,单字面理解,看起来能够维护的容器量都增长了。推荐应用包括多个服务,推荐部署方式就是。前言 容器化,云原生越演越烈,新概念非常之多。信息爆炸的同时,带来层层迷雾。我尝试从扩容出发理解其脉路,经过实践探索,整理形成一个入门教程,包括下面四篇文章。 容器化实践之路-从d...
摘要:今天开始实战虚拟机之二虚拟机的工作模式。总计有个系列实战虚拟机之一堆溢出处理实战虚拟机之二虚拟机的工作模式实战虚拟机之三的新生代实战虚拟机之四禁用实战虚拟机之五开启编译目前的虚拟机支持和两种运行模式。 今天开始实战Java虚拟机之二:虚拟机的工作模式。 总计有5个系列实战Java虚拟机之一堆溢出处理实战Java虚拟机之二虚拟机的工作模式实战Java虚拟机之三G1的新生代GC实战Jav...
摘要:目前已经成为全球最为流行的建站程序,根据的最新统计,的市场份额过去一年在持续增长。报告显示,市场份额过去一年增长了至,这意味着互联网上大约五分之二的网站是用创建的。资料显示,在年初,为所有网站提供了的支持。作为该年度的第三大主要核心版本。WordPress目前已经成为全球最为流行的CMS建站程序,根据 W3techs 的最新统计,WordPress 的市场份额过去一年在持续增长。W3tech...
摘要:数据结构之二叉树本文讲解二叉树的基本操作查找节点计算树的高度清空树递归遍历先序遍历中序遍历后序遍历按层遍历来看一下树的结构首先,为了方便后面看到效果,先手动初始化一个有个节点的二叉树查找节点查找节点递归左子树递归右子树计算树的深度计算树的深 数据结构之二叉树 本文讲解二叉树的基本操作: 查找节点 计算树的高度 清空树 递归遍历:先序遍历、中序遍历、后序遍历 按层遍历 来看一下树的结...
阅读 829·2021-11-25 09:44
阅读 1020·2021-11-19 09:40
阅读 6854·2021-09-07 10:23
阅读 1924·2019-08-28 17:51
阅读 1074·2019-08-26 10:59
阅读 1890·2019-08-26 10:25
阅读 3068·2019-08-23 18:22
阅读 835·2019-08-23 16:58