借着给公司新编写的系统刚刚弄完,信心爆棚,准备把前后端分离再捡起来看一下,前端还是得用React,后端简单一点,先用Django。
将来把公司的分析体系如果都搬到系统中,那自己也能靠前后端分离搞点东西玩玩。
还有服务器的配置,也通过虚拟机搞搞好,彻底再搞一遍。
这次除了以前买的React的书,还找了一本新书:Modern Django Web Development With Channels, DRF, GraphQL, and React (Malhar Lathkar)
01 WSGI
Python自带一个WSGI库用于测试用途,WSGI传递环境变量和HTTP请求给WEB应用程序,然后返回响应。按照书上自己编写一个Web应用,返回一个h2标签。
from wsgiref.simple_server import make_server
def wsgiapp(environ, start_response):
host = environ.get('HTTP_HOST')
start_response("200 OK", [("Content-type", "text/html")])
ret = [("<h2>Hello World App on WSGI Server Running at :{}</h2>".format(host).encode("utf-8"))]
return ret
server = make_server('0.0.0.0', 8080, wsgiapp)
server.serve_forever()
02 异步标准库
这个我很少用,但以后涉及到重型运算还是得用用才行。
Django异步支持来自于标准库asyncio,使用async加在正常的def之前来定义函数。在另外的函数里使用await来进行等待该函数的执行结果,根据执行结果来进行动作。
Python的这个包是在一个线程内执行的,并不是多线程程序。
# 同步版本的程序
def syncHello():
print ("Hello World")
# 异步版本的程序
async def asyncHello():
print ("Hello World")
异步版本的程序启动需要使用asyncio.run(asyncHello()),run中的参数必须是一个可等待对象。主程序运行到await的时候,就会等待协程的结果,拿到结果之后再进行下一步动作:
import asyncio
import time
async def asyncHello():
await asyncio.sleep(2)
print("\tHello World")
return 999
async def main():
for i in range(1, 4):
print("Iteration:", i)
print(f"\tstarted at {time.strftime('%X')}")
result = await asyncHello()
print(result)
print(f"\tfinished at {time.strftime('%X')}")
03 ASGI
WSGI是同步的,为了使用异步IO,需要使用ASGI(Asynchronous Server Gateway Interface)。
ASGI不是标准库的一部分,而且也不像WSGI标准库有一个样例服务器,需要安装asgiref库,然后再装一个服务器,书里推荐安装Uvicorn作为ASGI服务器。
pip3 install asgiref
pip3 install uvicorn
ASGI应用接受三个参数:send,receive和scope,简单的看一下使用方法
# main.py
import uvicorn
async def app(scope, receive, send):
print(scope)
print('---------------****************----------------')
print(receive)
await send({
'type': 'http.response.start',
'status': 200,
'headers': [
[b'content-type', b'text/html'],
],
})
await send({
'type': 'http.response.body',
'body': b'<h2>Hello World App on ASGI Server</h2>',
})
if __name__ == "__main__":
uvicorn.run("main:app", port=5000, log_level="info")
打印出来看了看,第一个是类似环境变量,第二个类似请求,最后是处理函数。这里直接用异步往里边填写了响应,不过实际使用还是要看看怎么编写。
从Django 3.1开始,异步包成了必需依赖(看了一下刚写完的项目就有这个依赖)。有个SyncToAsync可以把同步改成异步。现代Django应用比如Channels和Django REST Frameworkd都使用ASGI方式来处理WebSocket连接和异步后台任务。
看来异步的东西也得做起来了,希望这书后边有异步的内容。
04 回顾一下Django历史
Django2005年7月正式发布,看来赶在20年的时候重新捡起来也是巧合,就和我7月27号刚让大班站起来,发现第二天就是第三次Alpha二是周年,没想到7月也是Django20周年。
Django有自己的模板系统,ORM和基于正则的URL分发器,与其他的小型框架不同,这些都不用额外安装。
Django还附带了很多通用的东西在contrib包中,提供了后台管理和认证功能,内置防止CSRF攻击和SQL注入的安全因素以及其他很多东西。
05 其他方法启动Django
创建好项目之后,项目下边有一个wsgi.py和asgi.py,分别对应之前提到的两种方式。
WSGI启动
在项目里创建一个py文件:
import firstproject.wsgi as ws
from wsgiref.simple_server import make_server
server = make_server('localhost', 8000, ws.application)
server.serve_forever()
通过这个方式就可以将服务器启动为WSGI。
ASGI启动
需要安装一个服务器,这里推荐的是Daphne:
pip install daphne
这是个可执行文件,在终端里输入:
daphne firstproject.asgi:application
就可以启动了。
06 Django Shell
使用如下命令启动当前Django环境下的交互式命令行,在其中就可以进行很多简便的操作了。
python manage.py shell
可以通过交互式命令直接进行一些简易操作,省去了编写CRUD代码的麻烦。