内容提要:如何学习网络框架
学习3个核心知识:
1、路由的配置
2、模板的使用
3、静态资源的使用
一、tornado项目建立:
通过PyCharm工具实现项目的管理和代码的编写
1、创建项目:
file ==> New Project ==> Pure Python
Location:项目路径 + 项目名称
Interpreter:解释执行器
2、创建包:
1、点击项目文件,右击鼠标
2、选择Python Package
New ==> Python Package
3、创建源文件
1、点击包文件,右击鼠标
2、选择Python File
New ==> Python File
注:
1、文件名不能用test
2、Alt + Enter:在代码的错误位置输入,修复错误;注意不要选错了选项
二、基础
1、搭建简单tornado服务(9行代码)
class IndexHandler(RequestHandler):
def get(self, *args, **kwargs):
self.write('Hello Tornado')
def post(self, *args, **kwargs):
pass
app = Application(handlers=[('/',IndexHandler)])
server = HTTPServer(app)
server.listen(8888)
IOLoop.current().start()
注:浏览器访问路径:http://localhost:8888/
参考源码:https://github.com/hilqiqi0/AI/tree/master/3.Web/tornado/first_basic/first
2、配置和访问参数
1、将端口号写到配置文件中
将端口号写入配置文件需要3步:
1.定义端口号在配置文件中的名称,类型,默认值
define('名称',type=int,default=8888)
2.解析配置文件
parse_config_file('配置文件路径')
3.读取配置文件中的内容
options.名称
2、利用路径的变化请求不同的资源.
/java/day3/css
/java/day4
服务器利用正则表达式获取不同路径的内容
生成不同的响应内容
/java/(day[0-9]+)
/java/(day[0-9]+)/([a-z0-9]+)
3、利用参数的变化请求不同的资源.
1、以GET方式提交参数
/python?day=day3&subject=css
/python?day=day4
服务器会调用RequestHandler中的相关方法获取请求参数,再根据不同的请求参数进行不同的响应.
1、self.get_query_argument('参数名称',默认值)
提供默认值防止用户没有提供该参数时,产生400错误.
2、self.get_query_arguments('参数名称')
以列表的形式返回参数值(们),即使用户没有提供该参数,
也不会产生400错误,只会得到一个空列表.
2、以POST方式提交参数
用表单进行提交.
可以使用postman:网页post提交(表格form)数据导服务器
服务器会调用RequestHandler中的相关方法获取请求参数,再根据不同的请求参数进行不同的响应.
1、self.get_body_argument('参数名称',默认值)
提供默认值防止用户没有提供该参数时,产生400错误.
2、self.get_body_arguments('参数名称')
以列表的形式返回参数值(们),即使用户没有提供该参数,
也不会产生400错误,只会得到一个空列表.
3、RequestHandler另外一组获取参数函数
get_argument()
get_arguments()
函数使用效果:
get_query_argument()+get_body_argument()
get_query_arguments()+get_body_arguments()
4、参考
1、参考源码:https://github.com/hilqiqi0/AI/tree/master/3.Web/tornado/second
2、访问说明
http://localhost:9999/
路径变化:JavaHandler
http://localhost:9999/java/day4/css
http://localhost:9999/java/day50
GET/POST参数变化:PythonHandler
http://localhost:9999/python?day=day3&subject=css
http://localhost:9999/python?day=day4
postman使用
3、页面跳转
从一个页面跳转到另一个页面:self.redirect('/路径')
redirect跳转时采用的是get方式发起访问
4、文件上传
表单的文件上传:
需要增加属性:
enctype=multipart/form-data
说明:
HttpServerRequest,它封装了与请求相关的所有内容
self.request
利用HttpServerRequest对象的files属性处理上传的文件
self.request.files
{'avatar':[{'content_type':'image/jpeg',
'body':文件的二进制格式,
'filename':上传者本地图像名称},
{},{}]}
注:如果用户没有上传文件,files属性是空字典{}
5、示例
在首页面呈现一个登录表单收集用户名和密码.如果用户输入的用户名为"abc",密码为"123",在控制台上打印"用户信息正确",否则打印"用户名或密码错误"
参考源码:https://github.com/hilqiqi0/AI/tree/master/3.Web/tornado/login_basic
注:文件上传
参考源码:https://github.com/hilqiqi0/AI/tree/master/3.Web/tornado/login_files
三、钩子方法和服务器响应
1、框架设计者会使用钩子方法将框架代码与使用者的代码结合在一起
钩子方法属于让使用者选择性重写的内容.
如果重写,就调用重写的内容.
如果不重写,也不会影响代码的整体执行效果.
2、Tornado的RequestHandler中常用的钩子方法
set_default_headers:用来设置自定义响应头
initialize:在get/post方法执行前进行初始化操作(比如获取一些资源)
get/post:生成真正的响应内容
on_finish:在get/post方法执行后,进行资源的释放
3.服务器的响应内容
最常见的两种:
1、一种是JSON字符串
2、一种是HTML页面
1.Tornado以JSON字符串作为响应内容
第一种方式: 构建一个字典,直接把字典写入缓冲区
finish方法会自动帮助我们把字典转为正确JSON字符串,推回到客户端/浏览器
eg:
resp = {'key1':'value1','key2':'value2'}
self.write(resp)
第二种方式: 构建一个字典
利用json.dumps将字典转为一个纯字符串
手动设置响应头
self.set_header('Content-Type','application/json;charset=UTF-8')
设置完毕后把纯字符串写入到缓冲区
eg:
resp = {'key1':'value1','key2':'value2'}
self.set_header('Content-Type','application/json;charset=UTF-8')
json_str = json.dumps(resp)
self.write(json_str)
二者的差别:响应头的不一样,前者是finish方法自动完成,后者是手动设置
2、Tornado以真正的HTML页面作为响应内容
第一步:创建一个存放模板/页面的文件夹.
第二步: 在第一步创建的文件夹中,创建作为响应的HTML文件
第三步:配置第一步所创建的文件夹.
找到Application,传入第二个参数:
template_path='第一步创建的文件夹名称'
第四步: 使用第二步创建的HTML文件作为响应
self.render('文件名称.html')
render文法实际就是根据第三步配置的路径找到HTML文件,将HTML文件内容转为一个纯的字符串,写入缓冲区等待finish方法将缓冲区中的字符串推回客户端/浏览器
4、参考
参考源码:https://github.com/hilqiqi0/AI/tree/master/3.Web/tornado/third
四、模板和静态文件
1、在模板中使用变量,算术表达式,函数表达式
变量的使用方式:{{变量名}}
eg{{a}} {{b}}
算术表达式:{{表达式}}
eg:{{a+b}} {{a-b}}
函数表达式:{{函数名(参数列表)}}
eg:内置函数表达式{{len('abc')}}
自定义函数表达式{{myfunc(a,b)}}
注:
如果在模板使用了上述的变量,算术表达式或函数表达式,必须提前告知render方法,变量的值以及自定义函数所对应的具体函数
eg:self.render('模板',a=100,b=150,myfunc=self.xxx)
2、在模板中使用语句
循环语句:
{%for 变量 in 可迭代内容%}
...
{%end%}
分支语句:
{%if 条件%}
...
{%else%}
...
{%end%}
注:
如果在模板使用了for语句,必须提前告知render方法,可迭代内容的值.
eg:
3、静态资源的使用
常见的静态资源包括:图片,js,css
1、使用静态资源的步骤:
第一步,新建存放静态资源的文件夹.静态资源文件夹下可以继续新建子文件夹,把不同类型的静态资源文件存入不同的子文件夹中.
第二步,进行静态资源的配置.给Application继续添加参数
static_path='静态资源文件夹的名称'
第三步,需要使用静态资源时,要遵照如下格式:
static/子文件夹名称/具体静态资源文件的名称
eg:static/images/default_avatar.png
4、参考
参考源码:https://github.com/hilqiqi0/AI/tree/master/3.Web/tornado/forth
五、模板的进阶(块和模块)
1、块(block)的用法
在不同的模板中会存在一些相同的标签或者内容,为了避免每次都重复写这些相同的内容,我们可以把他们提取到一个公共的模板中(base.html),让不同的模板通过继承公共模板获得这些相同的内容.
使用步骤:
1、在公共模板中,使用{%block 名字%}{%end%}标识出不同的模板可能存在不同内容的地方.
2、不同的模板在使用公共模板时,一定把继承写在第一行
{%extends base.html%}
2、模块(module)的使用
模块的意义:
1、模块是可以复用的.利用已有的模块可以非常方便的拼出新的页面/模板.
2、可以进行协同开发.
3、通过模块让模块看上去更加的简洁.
使用步骤:
1、创建一个文件夹存放模块文件.该文件夹必须建立在模板文件夹下.
2、创建模块文件.(html文件)
3、关联模板文件和模块文件.
{%module xxxxx()%}
4、进行配置.在Application中增加参数:
ui_modules={'xxxxx':类名}
5、创建配置时对应的类
必须继承自UIModule,重写钩子方法render,该方法必须返回一个字符串,作为模板与模块的关联内容.所以这里应该返回的是模块文件转成的字符串,直接调用UIModule的render_string方法就可以完成.
注意:
如果模块中有变量,表达式等内容,必须在render_string方法中对变量、表达式进行相应的赋值.
3、UIModule补充说明
UIModule中,request属性引用着HttpServerRequest类型的对象,可以帮助我们完成一些与请求相关的操作.比如,获取请求参数.
HttpServerRequest对象的常用属性:
method HTTP的请求方式,如GET或POST;
host 被请求的主机名;
uri 请求的完整资源标示,包括路径和查询字符串;
path 请求的路径部分;
query 请求的查询字符串部分;
version 使用的HTTP版本;
headers 请求的协议头,是类似字典的对象,支持关键字索引的方式获取特定协议头信息,例如:request.headers[“Content-Type”],也可以用get的方式获取指定特定协议头信息;
body 请求体数据(二进制格式);
remote_ip 客户端的IP地址;
files 用户上传的文件,为字典类型
4.Tornado的转义
一种安全机制,防止用户在页面中嵌入JavaScript代码;
这种安全机制是自动开启的,可以通过设置进行关闭。
关闭方法:给Application添加参数:autoescape=None
5、参考
参考源码:https://github.com/hilqiqi0/AI/tree/master/3.Web/tornado/fifth
六、利用pymysql操作数据库的步骤
step1. 建立与数据库的联接
step2. 如果step1成功,利用联接获得一个游标(Cursor)
step3. 利用游标发送SQL语句,操作数据库
step4. 如果有需要,利用游标获取数据库的返回结果集
七、优化
1、代码的封装.应该把处理一类事情的代码(例如:所有与数据库相关的代码)都封装到一个类中.
2、尽量避免创建过多的对象.
补充:'单例模式'
八、示例
参考源码:https://github.com/hilqiqi0/AI/tree/master/3.Web/tornado/seventh
九、AJAX
A:Asynchoronous 异步的
J:JavaScript (JSON)
A:and
AJAX纯前端技术(浏览器使用的)
浏览器里内嵌了一个XMLHTTPReqeust对象.
通过该对象也能发起一个请求,并等待服务器的响应,处理响应.
单独发送请求,单独等待响应,单独刷新局部的页面.
1、使用AJAX的步骤
a、方法1
标准JS:
step1 获得XMLHTTPReqeust对象
step2 进行配置:包括请求路径,发送的数据,如何处理收到的响应
step3 发送请求
b、方法2
使用Jquery:(对方法1做了简单的封装)
$.ajax(配置参数);
配置参数是以JS对象的形式传入:
url:"/xxx"
ajax请求提交的路径
data:{"k1":"v1"}
ajax请求提交的参数
type:"post"
ajax请求提交的方式
datatype:"json"
可接受的服务器响应内容的格式
success:function(data){}
当服务器正常响应后,被回调的函数.服务器响应内容以参数形式传入回调函数.
error:function(err){}
当服务器无法正常响应时,被回调的函数.错误描述内容以参数形式传入回调函数.
2、cookie session
cookie:服务器写入到浏览器中的一些键值对.这些键值对会在下次访问服务器时,被浏览器自动提交上来.
session:相关信息存储在服务器,然后向浏览器中写入一个键值对,该键值对就是下一次访问服务器时,找到存储信息的一个"凭证"."凭证"要尽量做到不重复.
3、参考
参考源码:https://github.com/hilqiqi0/AI/tree/master/3.Web/tornado/eighth
十、附录:目录