django天天生鲜项目--------celery功能

Posted maoxinjueluo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了django天天生鲜项目--------celery功能相关的知识,希望对你有一定的参考价值。

  • 1、celery(分布式任务队列)介绍:

情景:用户发起request,并等待response返回。在本些views中,可能需要执行一段耗时的程序,那么用户就会等待很长时间,造成不好的用户体验,比如发送邮件、手机验证码等。

使用celery后,情况就不一样了。解决:将耗时的程序放到celery中执行。

celery名词:

  • 任务task:就是一个Python函数。
  • 队列queue:将需要执行的任务加入到队列中。
  • 工人worker:在一个新进程中,负责执行队列中的任务。
  • 代理人broker:负责调度,在布置环境中使用redis。

 

  • 2、celery安装以及实现发送邮件

技术图片

  • 1)安装celery包:
pip install celery

 

  •  2)新建一个文件专门来放置celery的文件

技术图片

 

  • 3)编写tasks.py文件(tasks就是任务发出者,Redis作为中间人broker)
技术图片tasks.py

 

  • 4)拷贝一份dailyfresh项目到任务处理者,注意任务处理者可以是同一台电脑,也可以是不同电脑
  • 5)在任务处理者中安装eventlet
pip install eventlet

 

  • 6)处理者端启动celery
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:usersadministratorappdatalocalprogramspythonpython37libsite-packagesceleryapp	race.py", line 385, in trace_task
    R = retval = fun(*args, **kwargs)
  File "c:usersadministratorappdatalocalprogramspythonpython37libsite-packagesceleryapp	race.py", line 648, in __protected_call__
    return self.run(*args, **kwargs)
  File "F:PycharmProjects复习Django复习dailyfresh_celerycelery_tasks	asks.py", line 23, in send_register_active_email
    sender = settings.EMAIL_FROM
  File "c:usersadministratorappdatalocalprogramspythonpython37libsite-packagesdjangoconf\\__init__.py", line 56, in __getattr__
    self._setup(name)
  File "c:usersadministratorappdatalocalprogramspythonpython37libsite-packagesdjangoconf\\__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] celery@PC-201904021625 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

 补充:任务发出者发生改动,任务处理者端也必须进行同样的改动

 

  • 3、celery生成首页静态页面,配合nginx显示首页静态页面

  • 1)编写tasks.py 

技术图片

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)

 

  • 2)将django项目拷贝一份到处理端

  • 3)测试静态首页生成

处理端进入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,成功生成静态首页。

 

  • 4)配合Nginx让用户可以访问静态首页

修改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

 技术图片

 

 

 

  • 5)访问Nginx中的static中的index.html

在浏览器中敲入  127.0.0.1 即可访问,如果是其它电脑则需要敲入 Nginx端的IP

注意这里可以会出现 403 错误,也就是找不到static,解决方法:https://blog.csdn.net/sz85850597/article/details/84955992

 

  • 4、admin管理更新首页数据表数据时重新生成index静态页面

  • 编写goods中的admin.py ,当后台管理更新首页数据时可以通过celery重新生成index静态页面

技术图片

技术图片
 1 from django.contrib import admin
 2 from goods.models import GoodsType,GoodsSKU,Goods,GoodsImage,IndexGoodsBanner,IndexTypeGoodsBanner,IndexPromotionBanner
 3 
 4 # Register your models here.
 5 
 6 class BaseModelAdmin(admin.ModelAdmin):
 7     ‘‘‘更新或删除生成首页静态页面模型类‘‘‘
 8 
 9     def save_model(self, request, obj, form, change):
10         ‘‘‘更新时调用‘‘‘
11         super().save_model(request,obj,form,change)
12         ##  发送任务队列
13         from celery_tasks.tasks import generate_static_index_html
14         generate_static_index_html.delay()
15 
16 
17 
18     def delete_model(self, request, obj):
19         ‘‘‘删除时调用‘‘‘
20         super().delete_model(request, obj)
21         ##  发送任务队列
22         from celery_tasks.tasks import generate_static_index_html
23         generate_static_index_html.delay()
24 
25 
26 # class GoodsTypeAdmin(BaseModelAdmin):
27 #     pass
28 # class GoodsSKUAdmin(BaseModelAdmin):
29 #     pass
30 # class GoodsAdmin(BaseModelAdmin):
31 #     pass
32 # class GoodsImageAdmin(BaseModelAdmin):
33 #     pass
34 # class IndexGoodsBannerAdmin(BaseModelAdmin):
35 #     pass
36 # class IndexPromotionAdmin(BaseModelAdmin):
37 #     pass
38 
39 def register(obj,obj1):
40     admin.site.register(obj,obj1)
41 register(GoodsType,BaseModelAdmin)
42 register(GoodsSKU,BaseModelAdmin)
43 register(Goods,BaseModelAdmin)
44 register(GoodsImage,BaseModelAdmin)
45 register(IndexGoodsBanner,BaseModelAdmin)
46 register(IndexTypeGoodsBanner,BaseModelAdmin)
47 register(IndexPromotionBanner,BaseModelAdmin)
admin.py

 

  • 通过nignx调度

技术图片

 

以上是关于django天天生鲜项目--------celery功能的主要内容,如果未能解决你的问题,请参考以下文章

天天生鲜(Python)Django项目学习资料(视频源码)

天天生鲜(Python)Django项目学习资料(视频源码)

DJANGO-天天生鲜项目从0到1-006-首页-内容展示

DJANGO-天天生鲜项目从0到1-015-部署-uWSGI+Nginx

DJANGO-天天生鲜项目从0到1-015-部署-uWSGI+Nginx

django天天生鲜项目--------celery功能