再折腾一遍前后端分离

再折腾一遍前后端分离

当年前后端分离忘得差不多了,现在重新折腾一下。

借着给公司新编写的系统刚刚弄完,信心爆棚,准备把前后端分离再捡起来看一下,前端还是得用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应用接受三个参数:sendreceivescope,简单的看一下使用方法

# 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代码的麻烦。

LICENSED UNDER CC BY-NC-SA 4.0
Comment