Django3.1异步

先决条件

项目环境依赖

  1. Python >= 3.8
  2. Django >= 3.1
  3. Uvicorn

ASGI

ASGI支持异步服务器网关接口。ASGI与WSGI向后兼容,可以直接将uWSGI之类的WSHI服务器切换至Uvicorn或Daphne之类的ASGI服务器。

创建项目与应用

mkdir django-async-views && cd django-async-views
python3.8 -m venv env
source env/bin/activate
alias activate='source 绝对路径'(添加/etc/profile永久生效)
# 退出虚拟环境 deactivate
django-admin.py startproject hello_async

安装Uvicorn并启动

pip install uvicorn
使用Uvicorn运行项目,需要从项目跟目录使用命令:
uvicorn (project_name).asgi:application --reload(--reload标志告诉uvicorn监视文件的更改,发现更改从新加载)
本项目为例:
uvicorn hello_async.asgi:application

##异步使用

views.py
import asyncio
from time import sleep
 
import httpx
from django.http import HttpResponse
 
 
# 异步任务
async def http_call_async():
    for num in range(1, 6):
        await asyncio.sleep(1)
        print(num)
    async with httpx.AsyncClient() as client:
        r = await client.get("https://httpbin.org/")
        print(r)
 
# 同步任务
def http_call_sync():
    for num in range(1, 6):
        sleep(1)
        print(num)
    r = httpx.get("https://httpbin.org/")
    print(r)
 
 
# 异步视图 - 无异步或同步任务
async def index(request):
    return HttpResponse("Hello, async Django!")
 
# 异步视图 - 调用异步任务
async def async_view(request):
    loop = asyncio.get_event_loop()
    loop.create_task(http_call_async())
    return HttpResponse("Non-blocking HTTP request")
 
# 同步视图 - 调用普通同步任务
def sync_view(request):
    http_call_sync()
    return HttpResponse("Blocking HTTP request")
urls.py
# hello_async/urls.py
 
from django.contrib import admin
from django.urls import path
 
from hello_async.views import index, async_view, sync_view
 
urlpatterns = [
    path("admin/", admin.site.urls),
    path("async/", async_view),
    path("sync/", sync_view),
    path("", index),
]

Django中异步视图中调用和执行异步任务是非阻塞的,执行效率非常高。如果在异步视图中调用同步任务是与同步视图执行同步任务无区别。当你希望使用Django异步视图提升你的代码效率时,不仅视图需要是异步的,其调用的任务函数也必须是异步的。

同步转异步

异步视图内调用同步任务(比如通过Django ORM与数据库进行交互),请使用sync_to_async作为包装器或装饰器。

from asgiref.sync import sync_to_async

async def async_with_sync_view(request):
    loop = asyncio.get_event_loop()
    async_function = sync_to_async(http_call_sync)
    loop.create_task(async_function())
    return HttpResponse("Non-blocking HTTP request (via sync_to_async)")
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值