Django asyncio 配合使用

被问到如何在django中使用asyncio , 突然闷比, 没学过django, 

快速入门后 , 搞了一下, 发现还是可以配合使用,

至于效果就不知道了 ,没并发测试过

具体方法是动态添加协程; 动态添加协程

只是给出一个思路:

就只放视图函数了,  路由那些自己随意配把; 

下面代码中用了aiomysql 

from django.http import HttpRequest,HttpResponse
from django.shortcuts import render,redirect
import aiomysql
import asyncio
import threading
import time
thread_handler = None
from concurrent.futures import ThreadPoolExecutor,as_completed

#创建一个ioloop给线程用
lp = asyncio.new_event_loop() #type:asyncio.AbstractEventLoop
#mysql pool
pool = None

#线程函数, 在线程中启动一个ioloop
def ioloop(lp : asyncio.AbstractEventLoop):
    print("thread id:" , threading.currentThread().ident)
    asyncio.set_event_loop(lp)
    lp.run_forever()

#启动线程
def start_ioloop():
    thread_handler = threading.Thread(target=ioloop,args=(lp,))
    thread_handler.start()

    #这里用了aiomysql
    fu = asyncio.run_coroutine_threadsafe(init_mysql_pool(lp),lp)
    fu.result() #等待直到mysql初始化完
    print("初始化mysql -> ok")



#视图函数 
def classes(req:HttpRequest):

    #select_from_db()创建生成器对象, 仍进ioloop中
    fu = asyncio.run_coroutine_threadsafe(select_from_db(),lp)

    #这个 furture对象是concurrent.futures中的, 因此将阻塞,我这里只是测试
    #你可以完全不等待
    ret = fu.result()
    return render(req,"classes.html",{"class_list" : ret})

#视图函数 , 测试插入一个数据
def addclass(req:HttpRequest):
    if req.method == "GET":
        return render(req,"addclass.html")
    elif req.method == "POST":
        classname = req.POST.get("cls",None)
        d = {
            "title" : classname
        }
    
        # 动态添加一个生成器对象
        fu = asyncio.run_coroutine_threadsafe(insert_into_db(d),lp)
        fu.result()
        return redirect("/classes/")


#插入mysql用的
async def insert_into_db(d : dict , table="classes"):
    keys =  ",".join(d.keys())
    values = ",".join(["%s"] * len(d))
    sql = "insert into {table}({keys}) VALUES ({values})".format(table=table,
                                                                 keys=keys,
                                                                 values=values)
    async  with pool.acquire() as conn:
        async  with conn.cursor() as cur:
            await cur.execute(sql,tuple(d.values()))
            await conn.commit()


#查询mysql
async def select_from_db():
    arr = []
    async  with pool.acquire() as conn:
        async  with conn.cursor() as cur:
            await cur.execute("select id,title from classes")
            row = await cur.fetchone()
            while row:
                arr.append(row)
                row = await cur.fetchone()
    return arr

#关闭用的
async def close_mysql():
    pool.close()
    await pool.wait_closed()


#初始化mysql pool
async def init_mysql_pool(lp:asyncio.AbstractEventLoop):
    global  pool
    mysql_settings = {
        'db': 'testdb',
        'host': '127.0.0.1',
        'port': 3306,
        'user': 'root',
        'password': 'fuck',
        'charset': 'utf8',
        'maxsize': 50
    }
    pool = await aiomysql.create_pool(**mysql_settings)



#启动ioloop
start_ioloop()

 

你可能感兴趣的:(py)