IT评测·应用市场-qidao123.com

标题: Celery在Django中的作用 [打印本页]

作者: 勿忘初心做自己    时间: 2025-3-13 16:41
标题: Celery在Django中的作用
在 Django 中使用 Celery 主要是为了处理耗时或需要异步实验的使命,避免阻塞 Web 哀求的相应,提升用户体验和系统性能。 
安装很简朴,打开终端
  1. pip install celery
复制代码
先来了解一下
async tasks——异步使命


异步实现发送验证码流程

流程就是,把一些方法“摘”出来,放在tasks.py文件下,在视图函数中调用这个方法,这里举例发送邮箱验证码。
先看下目录结构,一清二楚,有人问tasks.py放app里还是哪?tasks.py 文件的最佳实践是 直接放在相干功能的应用目录下(例如这里验证码流程在 Login 应用,tasks就放在Login下)
  1. book_demo/
  2. ├── book_demo/              # 项目根目录
  3. │   ├── __init__.py
  4. │   ├── settings.py         # Django 配置
  5. │   ├── urls.py
  6. │   └── celery.py           # Celery 初始化配置(关键!)
  7. └── Login/                  # 你的登录/注册功能应用
  8.     ├── __init__.py
  9.     ├── tasks.py            # Celery 任务定义(核心文件)
  10.     ├── views.py            # 处理验证码的视图函数
  11.     ├── models.py
  12.     └── ...
复制代码
0.情况准备

   不消担心,总共需要安装Redis\Celery两个就行了
  先安装一些设置才能启动Celery:也就是安装Celery 架构的焦点组成部分。
常看到一个描述是:使用Redis作为Broker  ?????一头雾水,下面用人话讲讲,了解一下在开始安装:
1. 什么是 Broker?



2. 什么是 Redis?



3. Celery 的完整工作流程

  1. [Django] --> [Broker(Redis)] --> [Celery Worker] --> [执行任务]
复制代码

4. 为什么需要 Broker?


了解完毕,我这里使用的是Redis充当Broker
安装Redis
1.下载

2. 运行安装程序

3.验证安装

  1. # 检查 Redis 是否安装成功
  2. redis-server --version
  3. # 输出示例:Redis server v=5.0.14.1
  4. # 启动 Redis 服务端
  5. redis-server
复制代码
 出现下面的图案代表启动成功:

这里如果报错出现下图,不消担心
 

可参考另一篇博客~

安装完Celery和Redis之后,可开始下面的: 
1.设置 Celery

book_deml/settings.py下添加:
  1. CACHES = {
  2.     'default': {
  3.         'BACKEND': 'django.core.cache.backends.redis.RedisCache',
  4.         'LOCATION': 'redis://127.0.0.1:6379/1',  # Redis 地址和数据库编号
  5.     }
  6. }
  7. CELERY_BROKER_URL = 'redis://localhost:6379/0'
  8. CELERY_RESULT_BACKEND = 'redis://localhost:6379/1'
复制代码
确保项目根目录的 celery.py 和 __init__.py 已正确设置:
  1. # book_demo/book_demo/celery.py
  2. import os
  3. from celery import Celery
  4. # 设置 Django 环境变量
  5. os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'book_demo.settings')
  6. app = Celery('book_demo')
  7. # 从 Django 配置中读取 Celery 设置
  8. app.config_from_object('django.conf:settings', namespace='CELERY')
  9. # 自动发现所有应用中的 tasks.py
  10. app.autodiscover_tasks()
复制代码
  1. # book_demo/book_demo/__init__.py
  2. from .celery import app as celery_app
  3. __all__ = ['celery_app']
复制代码

2.运行 Celery Worker

启动 Celery Worker 处理异步使命,说人话就是打开终端输入命令启动celery:
  1. celery -A book_demo worker --loglevel=info -P eventlet
复制代码
   这里关于这个命令另一篇处理启动Celery的博客中有具体介绍。eventlet记得也先pip install 安装
  出现下图则代表安装成功: 

测试缓存功能
在 Django Shell 中手动测试缓存功能:
  1. 1.输入:
  2. python manage.py shell
  3. 2.输入:
  4. from django.core.cache import cache
  5. # 设置缓存
  6. cache.set('test_key', 'test_value', timeout=300)
  7. # 获取缓存
  8. value = cache.get('test_key')
  9. print(value)  # 输出:test_value
复制代码
成功就长如许: 
 

 3.创建 tasks.py

在 Login/tasks.py 中定义发送验证码的异步使命:
  1. # book_demo/Login/tasks.py
  2. from celery import shared_task
  3. from django.core.mail import send_mail
  4. from django.conf import settings
  5. import random
  6. @shared_task
  7. def send_email_captcha_task(email):
  8.     # 生成 6 位随机验证码
  9.     captcha = ''.join(random.choices('0123456789', k=6))
  10.     # 存储到缓存(有效期 5 分钟)这里我用的Redis
  11.     cache_key = f'verification_code_{email}'
  12.     cache.set(cache_key, captcha, timeout=300)
  13.     stored_captcha = cache.get(cache_key)  # 从缓存中获取验证码
  14.     # 打印缓存键和验证码
  15.     logger.info(f"缓存键:{cache_key}, 缓存值:{stored_captcha}")
  16.     try:
  17.         send_mail(
  18.             subject='您的验证码',
  19.             message=f'您的验证码是:{captcha},有效期 5 分钟。',
  20.             from_email=None,  # 使用配置的默认发件人
  21.             recipient_list=[email],
  22.             fail_silently=False,
  23.         )
  24.         return True  # 可选:返回任务执行状态
  25.     except Exception as e:
  26.         # 记录错误日志
  27.         logger.error(f'邮件发送失败: {str(e)}')
  28.         return False  # 可选:返回任务执行状态
复制代码
这里需要注意几点:


4.在视图函数中调用异步使命

修改 book_demo/Login/views.py,触发异步使命:
  1. # book_demo/Login/views.py
  2. from django.shortcuts import render, HttpResponse
  3. from .tasks import send_verification_code_task  # 从当前应用导入任务
  4. from rest_framework.views import APIView
  5. class send_email_captcha(APIView):
  6.     def post(self, request):
  7.         email = request.POST.get('email')
  8.         
  9.         ##这里一般校验邮箱格式、是否为空、是否已经注册等
  10.         try:
  11.             # 异步触发发送验证码任务
  12.             send_email_captcha_task.delay(email)  # 关键:使用 .delay()
  13.             # 使用.delay()确保任务在CeleryWorker中执行,避免阻塞请求。
  14.             return JsonResponse(
  15.                 {'success': True, 'message': '验证码已发至您的邮箱'},
  16.                 status=status.HTTP_200_OK
  17.             )
  18.         except Exception as e:
  19.             return JsonResponse(
  20.                 {'success': False, 'message': f'服务器错误:{str(e)}'},
  21.                 status=status.HTTP_500_INTERNAL_SERVER_ERROR
  22.             )
复制代码
从缓存中获取验证码是否正确:
  1. class verify_email_captcha(APIView):
  2.     def post(self, request):
  3.         try:
  4.             email = request.data.get('email')
  5.             user_input_captcha = request.data.get('emailCaptcha')
  6.             cache_key = f'verification_code_{email}'
  7.             stored_captcha = cache.get(cache_key)  # 从缓存中获取验证码
  8.             # 打印缓存键和验证码
  9.             print(f"缓存键:{cache_key}, 缓存值:{stored_captcha}")
  10.             if not stored_captcha:
  11.                 return Response({'success': False, 'message': '验证码已过期或无效'}, status=status.HTTP_400_BAD_REQUEST)
  12.             # 比较用户输入的验证码和存储的验证码
  13.             if user_input_captcha == stored_captcha:
  14.                 return Response({'success': True, 'message': '验证码验证成功'}, status=status.HTTP_200_OK)
  15.             else:
  16.                 return Response({'success': False, 'message': '验证码错误'}, status=status.HTTP_400_BAD_REQUEST)
  17.         except Exception as e:
  18.             return Response({'success': False, 'message': f'服务器错误:{str(e)}'}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
复制代码

总结 

 好了到这正常异步处理发验证码的流程就搞好了 ~
回首一下Celery 的焦点作用:

Redis 的双重角色:
人话就是:
Celery就是单独把发验证码的这个方法摘出来,异步实验(就是把方法写在task.py下),结果呢(好比验证码)就存在Redis里,在用到的时候就再从Redis中获取。 


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 IT评测·应用市场-qidao123.com (https://dis.qidao123.com/) Powered by Discuz! X3.4