3.接口的调用顺序与模板
Posted traditional
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了3.接口的调用顺序与模板相关的知识,希望对你有一定的参考价值。
上一节介绍了tornado请求与响应,这一节介绍一下接口调用顺序和模板
首先都有哪些接口呢?作用是什么呢?并且都有的时候,执行顺序是怎么样的呢?
接口:
1.initialize,表示初始化,会在执行http方法之前调用
2.prepare,预处理,会在执行http方法之前调用,任何一种http请求都会执行预处理方法
3.http方法:
get,get请求
post,post请求
head,类似get请求,只不过响应中没有具体内容,只获取报头
delete,请求服务器删除指定的资源
put,从客户端向服务端传送指定内容
patch,修改局部内容
options,返回url支持的所有http方法
4.set_default_headers,设置请求头
5.write_error,处理self.send_error
6.on_finish,在请求处理结束之后调用,用于对资源的清理和释放,或者日志处理。并且尽量不要在该方法中响应输出
执行顺序
在正常执行未抛出错误时,执行顺序从上到下为:
set_default_headers
initialize
prepare
http方法
on_finish
在抛出错误时,执行顺序从上到下为:
set_default_deaders
initialize
prepare
http方法
set_default_headers
write_error
on_finish
测试
import tornado.web class SatoriHandler(tornado.web.RequestHandler): def get(self, *args, **kwargs): print("get") def initialize(self): print("initialize") def prepare(self): print("prepare") def set_default_headers(self): print("set_default_headers") def write_error(self, status_code, **kwargs): print("write_error") def on_finish(self): print("on_finish")
在get函数中引发一个error
import tornado.web class SatoriHandler(tornado.web.RequestHandler): def get(self, *args, **kwargs): print("get") self.send_error() def initialize(self): print("initialize") def prepare(self): print("prepare") def set_default_headers(self): print("set_default_headers") def write_error(self, status_code, **kwargs): print("write_error") def on_finish(self): print("on_finish")
--------------------------------------------------------------------------------------------------------
模板
首先要在settings里面配置模板路径,"template_path": os.path.join(BASE_DIR, "templates")
使用render方法渲染模板给客户端
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>古明地觉</title> </head> <body> <h1 style="text-align: center">欢迎来到古明地觉的避难小屋</h1> </body> </html>
view.py
import tornado.web class SatoriHandler(tornado.web.RequestHandler): def get(self, *args, **kwargs): self.render("satori.html")
变量与表达式
{{var}}
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>古明地觉</title> </head> <body> <h1>my name is {{name}}, which comes from {{place}}, people usually call me {{nickname1}}, {{nickname2}}, {{nickname3}} </h1> </body> </html>
import tornado.web class SatoriHandler(tornado.web.RequestHandler): def get(self, *args, **kwargs): # 在html中定义了name,place,nickname1,nickname2,nickname3 # 那么在渲染模板的时候,可以将参数传进去,然后进行替换 # 这些参数可以用关键字参数的形式传进去 # 而且通过这一点也能明白渲染的流程,tornado是先将整个html文件以字符串的形式全部读取进来 # 再按照模板语言进行替换,然后将替换之后的字符串返回给用户浏览器 # 浏览器再解析成页面,这就是模板渲染的流程。 # 因此最终交给浏览器的字符串是不包含大括号的 # 而且定义了几个{{var}},就要传几个,否则会报错name ‘xxx‘ is not defined # 而且写上了{{}},那么{{}}里面必须要传一个变量名,否则会报错,tornado.template.ParseError: Empty expression at xxx self.render("satori.html", name="古明地觉", place="东方地灵殿", nickname1="少女觉", nickname2="觉大人", nickname3="小五")
{{expression}}
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>古明地觉</title> </head> <body> <h1>my name is {{info["name"]}}, which comes from {{info["place"]}}, people usually call me {{info["nickname1"]}}, {{info["nickname2"]}}, {{info["nickname3"]}} </h1> </body> </html>
import tornado.web class SatoriHandler(tornado.web.RequestHandler): def get(self, *args, **kwargs): info = {"name": "古明地觉", "place": "东方地灵殿", "nickname1": "少女觉", "nickname2": "觉大人", "nickname3": "小五"} self.render("satori.html", info=info)
打印的结果是一样的,可以看到相比于django,tornado的模板语言更接近于python。如果是django,那么就只能通过 . 来访问了。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>古明地觉</title> </head> <body> <h1> 3 > 2 = {{3 > 2}} <br> bin(10) = {{bin(10)}} <br> 2 << 4 = {{2 << 4}} <br> 1 + 1 = {{1 + 1}} <br> sum(range(100)) = {{sum(range(100))}} <br> len("aaabbbccc") = {{len("aaabbbccc")}} <br> "aaa".upper() = {{"aaa".upper()}} </h1> </body> </html>
可以看到tornado的模板语言还支持简单的运算、逻辑判断,可以使用python的一些内置函数。所以这也说明了tornado是先将html文件读取进来,对{{}}用我们传进去的值或者python语法进行解释替换
流程控制
判断
{%if 条件%}
语句
{%end%}
{%if 条件%}
语句
{%else%}
语句
{%end%}
{%if 条件%}
语句
{%elif 条件%}
语句
...(可以多个elif)...
{%else%}
语句
{%end%}
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>古明地觉</title> </head> <body> {%if name == "古明地盆"%} <h1>我是{{name}},东方地灵殿</h1> {%elif name == "古明地恋"%} <h1>我是{{name}},东方地灵殿</h1> {%else%} <h1>管你是谁,我喜欢古明地两姐妹</h1> {%end%} </body> </html>
import tornado.web class SatoriHandler(tornado.web.RequestHandler): def get(self, *args, **kwargs): name = "古明地盆" self.render("satori.html", name=name)
import tornado.web class SatoriHandler(tornado.web.RequestHandler): def get(self, *args, **kwargs): name = "dadasdasdasdas" self.render("satori.html", name=name)
循环
{%for variabl in iterable%}
语句
{%end%}
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>古明地觉</title> </head> <body> {%for v in info%} <h1>{{v}}: {{info[v]}}</h1> {%end%} </body> </html>
import tornado.web class SatoriHandler(tornado.web.RequestHandler): def get(self, *args, **kwargs): info = {"name": "古明地盆", "gender": "女", "from": "东方地灵殿"} self.render("satori.html", info=info)
通过以上可以发现,tornado的模板语言是非常强大的,个人觉得比django的模板语言还要好很多。尽管没有django的那些过滤器什么的,但是对于tornado根本就不需要。因为tornado支持使用python的内置函数,所以django能完成的tornado都能完成,而且用起来比django的过滤器更方便。
并且如果传入了一个数字组成的列表li,我想计算列表的长度以及所有元素的和,对于django来说,可以使用{{li | length}}计算长度,但是不能计算总和,因为没有相应的过滤器,不可能使用{{li | sum}},当然django也提供了自定义过滤器的方法,先建一个templatetags文件夹,在文件夹里面定义一个py文件,在py文件里面定义一个函数,写上要处理的逻辑,然后在模板中把文件load进来,那么就可以将定义的函数作为过滤器使用了。但这样很麻烦,tornado的话,直接{{len(li)}}和{{sum(li)}}就可以了。
因此tornado的模板语言比django好用太多了,非常的精简,根本就不需要django那些过滤器什么,因为支持在html中直接使用python的语法,而且flask作者也是因为觉得django的模板语言不好用,才设计了jinja2。所以虽然django走的大而全的方向,但是模板语言设计的并不优秀,希望可以把模板语言再完善一下
以上是关于3.接口的调用顺序与模板的主要内容,如果未能解决你的问题,请参考以下文章