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.接口的调用顺序与模板的主要内容,如果未能解决你的问题,请参考以下文章

无法通过接口获取与片段通信的活动

函数模板在c++动态顺序表中的大作用

片段 getActivity() 与接口回调?

第七周收获

如何在片段着色器中进行自定义模板测试

小程序模板使用