D先生 2020-05-09
情景:用户发起request,并等待response返回。在本些views中,可能需要执行一段耗时的程序,那么用户就会等待很长时间,造成不好的用户体验,比如发送邮件、手机验证码等。
使用celery后,情况就不一样了。解决:将耗时的程序放到celery中执行。
celery名词:
pip install celery
pip install eventlet
celery -A celery_tasks.tasks worker -l info -P eventlet ## window系统 celery -A celery_tasks.tasks worker -l info ## Linux系统
进行任务发出,这里会报错:
Traceback (most recent call last): File "c:\users\administrator\appdata\local\programs\python\python37\lib\site-packages\celery\app\trace.py", line 385, in trace_task R = retval = fun(*args, **kwargs) File "c:\users\administrator\appdata\local\programs\python\python37\lib\site-packages\celery\app\trace.py", line 648, in __protected_call__ return self.run(*args, **kwargs) File "F:\PycharmProjects\复习\Django复习\dailyfresh_celery\celery_tasks\tasks.py", line 23, in send_register_active_email sender = settings.EMAIL_FROM File "c:\users\administrator\appdata\local\programs\python\python37\lib\site-packages\django\conf\__init__.py", line 56, in __getattr__ self._setup(name) File "c:\users\administrator\appdata\local\programs\python\python37\lib\site-packages\django\conf\__init__.py", line 41, in _setup % (desc, ENVIRONMENT_VARIABLE)) django.core.exceptions.ImproperlyConfigured: Requested setting EMAIL_FROM, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure() befor e accessing settings.
这是因为在处理者端没有进行初始化,下面进行初始化
在处理者端的celery_tasks文件夹中找到tasks.py,加入下面几句:
## 在任务处理者加 import os,django os.environ.setdefault("DJANGO_SETTINGS_MODULE", "dailyfresh.settings") django.setup()
运行成功
[2020-05-06 10:27:50,073: INFO/MainProcess] ready. [2020-05-06 10:27:58,532: INFO/MainProcess] Received task: celery_tasks.tasks.send_register_active_email[1550d187-f637-4fcf-806f-9263d94124d0] [2020-05-06 10:28:44,081: INFO/MainProcess] Task celery_tasks.tasks.send_register_active_email[1550d187-f637-4fcf-806f-9263d94124d0] succeeded in 45.536000000021886s: None
补充:任务发出者发生改动,任务处理者端也必须进行同样的改动
from celery import Celery from django.conf import settings from django.template import loader ## 在任务处理者加 #import os,django #os.environ.setdefault("DJANGO_SETTINGS_MODULE", #"dailyfresh.settings") #django.setup() from goods.models import GoodsType,IndexGoodsBanner,IndexPromotionBanner,IndexTypeGoodsBanner ## 这里导入goods.models一定要在上面三行的后面,不然处理者端会导入失败 ## 创建一个Celery类的实例对象 app = Celery(‘celery_tasks.tasks‘,broker=‘redis://127.0.0.1:6379/3‘) ## 处理端这里ip改成发送端的IP地址,包括处理端中setting文件中的MySQL和Redis都要改成发送端的IP地址 @app.task def generate_static_index_html(): ‘‘‘生成首页静态页面‘‘‘ # 获取商品的种类信息 types = GoodsType.objects.all() # 获取首页轮播商品信息 goods_banners = IndexGoodsBanner.objects.all().order_by(‘index‘) # 获取首页促销活动信息 promotion_banners = IndexPromotionBanner.objects.all().order_by(‘index‘) # 获取首页分类商品展示信息 for type in types: # GoodsType # 获取type种类首页分类商品的图片展示信息 image_banners = IndexTypeGoodsBanner.objects.filter(type=type, display_type=1).order_by(‘index‘) # 获取type种类首页分类商品的文字展示信息 title_banners = IndexTypeGoodsBanner.objects.filter(type=type, display_type=0).order_by(‘index‘) # 动态给type增加属性,分别保存首页分类商品的图片展示信息和文字展示信息 type.image_banners = image_banners type.title_banners = title_banners # 组织模板上下文 context = {‘types‘: types, ‘goods_banners‘: goods_banners, ‘promotion_banners‘: promotion_banners} # 使用模板 # 1.加载模板文件,返回模板对象 temp = loader.get_template(‘static_index.html‘) # 2.模板渲染 static_index_html = temp.render(context) # 生成首页对应静态文件 save_path = os.path.join(settings.BASE_DIR, ‘static/index.html‘) with open(save_path, ‘w‘,encoding=‘utf8‘) as f: f.write(static_index_html)
处理端进入django项目,启动celery
celery -A celery_tasks.tasks worker -l info
发送端启动行,进入Python调试
>>> from celery_tasks.tasks import generate_static_index_html >>> generate_static_index_html.delay()
处理端提示:
再看处理端中django项目中的static多了一个index.html,成功生成静态首页。
修改nginx.conf的配置项
敲入命令行: vim /usr/local/nginx/conf/nginx.conf
修改成下面几行
server { listen 80; server_name localhost; #charset koi8-r; #access_log logs/host.access.log main; location /static { alias /root/桌面/dailyfresh/static/; ## dailyfresh项目中static文件的绝对路径 } location / { # root html; root /root/桌面/dailyfresh/static/; ## dailyfresh项目中static文件的绝对路径 index index.html index.htm; }
重启Nginx
/usr/local/nginx/sbin/nginx -s reload
查看Nginx的启动端
ps aux | grep nginx
在浏览器中敲入 127.0.0.1 即可访问,如果是其它电脑则需要敲入 Nginx端的IP
注意这里可以会出现 403 错误,也就是找不到static,解决方法:https://blog.csdn.net/sz85850597/article/details/84955992
from django.contrib import admin from goods.models import GoodsType,GoodsSKU,Goods,GoodsImage,IndexGoodsBanner,IndexTypeGoodsBanner,IndexPromotionBanner # Register your models here. class BaseModelAdmin(admin.ModelAdmin): ‘‘‘更新或删除生成首页静态页面模型类‘‘‘ def save_model(self, request, obj, form, change): ‘‘‘更新时调用‘‘‘ super().save_model(request,obj,form,change) ## 发送任务队列 from celery_tasks.tasks import generate_static_index_html generate_static_index_html.delay() def delete_model(self, request, obj): ‘‘‘删除时调用‘‘‘ super().delete_model(request, obj) ## 发送任务队列 from celery_tasks.tasks import generate_static_index_html generate_static_index_html.delay() # class GoodsTypeAdmin(BaseModelAdmin): # pass # class GoodsSKUAdmin(BaseModelAdmin): # pass # class GoodsAdmin(BaseModelAdmin): # pass # class GoodsImageAdmin(BaseModelAdmin): # pass # class IndexGoodsBannerAdmin(BaseModelAdmin): # pass # class IndexPromotionAdmin(BaseModelAdmin): # pass def register(obj,obj1): admin.site.register(obj,obj1) register(GoodsType,BaseModelAdmin) register(GoodsSKU,BaseModelAdmin) register(Goods,BaseModelAdmin) register(GoodsImage,BaseModelAdmin) register(IndexGoodsBanner,BaseModelAdmin) register(IndexTypeGoodsBanner,BaseModelAdmin) register(IndexPromotionBanner,BaseModelAdmin)
admin.py