Python中如何在Django的view中阻塞请求
具体如图中,一个是验证码,一个验证码颜色,https://gitee.com/zhuqiyu/django_monitor/blob/master/index_img/index.png
目前是让验证码颜色函数阻塞 0.01 秒,但是有时候验证码函数超过 0.01 秒就会导致第二张图片加载不出来
代码地址 https://gitee.com/zhuqiyu/django_monitor/blob/master/monitor/ad/views.py (auth 是验证码函数,auth2 是验证码颜色函数)
代码
auth_code_color = None
def auth(request):
“”" 验证码函数 ,authCode 类来自 Authcode.py
@:return
auth_code_img, 二进制图片
“”"
auth_code = authCode()
auth_code_img = auth_code.gene_code()
auth_code_text = auth_code.text
global auth_code_color
auth_code_color = auth_code.create_color()
request.session[“verify_code”] = auth_code_text
return HttpResponse(auth_code_img, ‘image/png’)
def auth2(request):
time.sleep(0.01)
global auth_code_color
return HttpResponse(auth_code_color, ‘image/png’)
Python中如何在Django的view中阻塞请求
请问能用什么方式将 time.sleep(0.01)替换了吗,或者思路也行。之前在 auth 函数中添加一个变量,值为 1,在 auth2 中-1,可能实现的有问题,结果比现在还差。
在Django的view中,你可以通过几种方式实现请求的“阻塞”,这通常指的是让请求处理暂停一段时间,或者等待某个条件满足。最常见的方法是使用time.sleep(),但更符合Web应用场景的做法是使用异步等待。
1. 使用time.sleep(简单阻塞) 这是最直接的方法,但会阻塞整个工作线程,不推荐在生产环境中对耗时操作使用。
import time
from django.http import HttpResponse
def my_view(request):
# 阻塞5秒
time.sleep(5)
return HttpResponse("请求处理完成,已阻塞5秒")
2. 使用asyncio.sleep(异步视图,推荐) 如果你使用的是Django 3.1+并启用了异步支持,可以使用异步视图,这样在等待时不会阻塞其他请求。
import asyncio
from django.http import HttpResponse
async def my_async_view(request):
# 异步等待5秒,不会阻塞服务器线程
await asyncio.sleep(5)
return HttpResponse("异步请求处理完成,已等待5秒")
3. 等待某个条件(轮询) 如果需要等待某个外部条件满足,比如一个任务完成,可以使用轮询的方式。
import time
from django.http import HttpResponse, HttpResponseBadRequest
def waiting_view(request):
task_id = request.GET.get('task_id')
if not task_id:
return HttpResponseBadRequest("需要task_id参数")
# 模拟等待某个任务完成,最多等待10秒
timeout = 10
start_time = time.time()
while not is_task_completed(task_id): # 假设的检查函数
if time.time() - start_time > timeout:
return HttpResponse("等待超时", status=408)
time.sleep(0.5) # 每次检查间隔0.5秒
return HttpResponse(f"任务 {task_id} 已完成")
# 假设的任务完成检查函数
def is_task_completed(task_id):
# 这里应该是你的业务逻辑,检查任务状态
# 例如从数据库或缓存中查询
# 此处返回True仅作示例
return True
关键点:
time.sleep()在同步视图中会阻塞整个工作线程,这意味着在此期间,该线程无法处理其他请求。这可能会严重影响服务器的并发能力,特别是在使用同步工作模式(如Gunicorn的同步worker)时。仅适用于本地测试或极低并发场景。- 异步等待 (
asyncio.sleep) 是更优的选择。在异步视图中,await asyncio.sleep()会将控制权交还给事件循环,允许事件循环去处理其他异步任务(如其他请求),从而实现“非阻塞”的等待。这是处理需要等待的I/O密集型操作的现代方式。 - 轮询等待条件 适用于需要等待外部事件(如后台任务完成、第三方API回调)的场景。重要的是要设置超时机制,避免请求无限期挂起,并合理设置检查间隔,避免过于频繁的检查消耗资源。
总结建议:对于需要等待的视图,优先使用Django的异步支持。
目前最容易出现的是在服务重启之后的前两次访问,后面就一般不会复现。
为什么不在第一个请求结束后再发起第二个请求啊
因为我不会前端。。
<div style=“display: inline-block;”><img name=“img_code” src="/ad/auth/?0.42844671870369355" onclick=“this.src=’/ad/auth/?’+Math.random();document.getElementById(‘verify_code_color’).src=’/ad/auth2/?’+Math.random()”/></div>
<div style=“position: absolute;left: 90px;top: 10px;”>输入 <img id=“verify_code_color” src="/ad/auth2/?0.42844671870369355"/> 验证码</div>
别瞎折腾了百度一下 django-captcha
你自己写的那个 login 也是乱七八糟的,还不直接 django 自己带的 auth 模块呢。

