Django中使用Celery的教程详解


Posted in Python onAugust 24, 2018

Django教程

Python下有许多款不同的 Web 框架。Django是重量级选手中最有代表性的一位。许多成功的网站和APP都基于Django。
Django是一个开放源代码的Web应用框架,由Python写成。
Django遵守BSD版权,初次发布于2005年7月, 并于2008年9月发布了第一个正式版本1.0 。
Django采用了MVC的软件设计模式,即模型M,视图V和控制器C。

一、前言

Celery是一个基于python开发的分布式任务队列,如果不了解请阅读笔者上一篇博文Celery入门与进阶,而做python WEB开发最为流行的框架莫属Django,但是Django的请求处理过程都是同步的无法实现异步任务,若要实现异步任务处理需要通过其他方式(前端的一般解决方案是ajax操作),而后台Celery就是不错的选择。倘若一个用户在执行某些操作需要等待很久才返回,这大大降低了网站的吞吐量。下面将描述Django的请求处理大致流程(图片来源于网络):

Django中使用Celery的教程详解

请求过程简单说明:浏览器发起请求-->请求处理-->请求经过中间件-->路由映射-->视图处理业务逻辑-->响应请求(template或response)

二、配置使用

celery很容易集成到Django框架中,当然如果想要实现定时任务的话还需要安装django-celery-beta插件,后面会说明。需要注意的是Celery4.0只支持Django版本>=1.8的,如果是小于1.8版本需要使用Celery3.1。

配置

新建立项目taskproj,目录结构(每个app下多了个tasks文件,用于定义任务):

taskproj
├── app01
│ ├── __init__.py
│ ├── apps.py
│ ├── migrations
│ │ └── __init__.py
│ ├── models.py
│ ├── tasks.py
│ └── views.py
├── manage.py
├── taskproj
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
└── templates

在项目目录taskproj/taskproj/目录下新建celery.py:

#!/usr/bin/env python3
# -*- coding:utf-8 -*-
# Author:wd
from __future__ import absolute_import, unicode_literals
import os
from celery import Celery
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'taskproj.settings') # 设置django环境
app = Celery('taskproj')
app.config_from_object('django.conf:settings', namespace='CELERY') # 使用CELERY_ 作为前缀,在settings中写配置
app.autodiscover_tasks() # 发现任务文件每个app下的task.py

taskproj/taskproj/__init__.py:
from __future__ import absolute_import, unicode_literals
from .celery import app as celery_app
__all__ = ['celery_app']
taskproj/taskproj/settings.py
CELERY_BROKER_URL = 'redis://10.1.210.69:6379/0' # Broker配置,使用Redis作为消息中间件
CELERY_RESULT_BACKEND = 'redis://10.1.210.69:6379/0' # BACKEND配置,这里使用redis
CELERY_RESULT_SERIALIZER = 'json' # 结果序列化方案

进入项目的taskproj目录启动worker:

celery worker -A taskproj -l debug

定义与触发任务

任务定义在每个tasks文件中,app01/tasks.py:

from __future__ import absolute_import, unicode_literals
from celery import shared_task
@shared_task
def add(x, y):
 return x + y
@shared_task
def mul(x, y):
 return x * y

视图中触发任务

from django.http import JsonResponse
from app01 import tasks
# Create your views here.
def index(request,*args,**kwargs):
 res=tasks.add.delay(1,3)
 #任务逻辑
 return JsonResponse({'status':'successful','task_id':res.task_id})

访问http://127.0.0.1:8000/index

Django中使用Celery的教程详解

若想获取任务结果,可以通过task_id使用AsyncResult获取结果,还可以直接通过backend获取:

Django中使用Celery的教程详解

扩展

除了redis、rabbitmq能做结果存储外,还可以使用Django的orm作为结果存储,当然需要安装依赖插件,这样的好处在于我们可以直接通过django的数据查看到任务状态,同时为可以制定更多的操作,下面介绍如何使用orm作为结果存储。

1.安装

pip install django-celery-results

2.配置settings.py,注册app

INSTALLED_APPS = (
 ...,
 'django_celery_results',
)

4.修改backend配置,将redis改为django-db

#CELERY_RESULT_BACKEND = 'redis://10.1.210.69:6379/0' # BACKEND配置,这里使用redis
CELERY_RESULT_BACKEND = 'django-db' #使用django orm 作为结果存储

5.修改数据库

python3 manage.py migrate django_celery_results

此时会看到数据库会多创建:

 Django中使用Celery的教程详解

当然你有时候需要对task表进行操作,以下源码的表结构定义:

class TaskResult(models.Model):
 """Task result/status."""
 task_id = models.CharField(_('task id'), max_length=255, unique=True)
 task_name = models.CharField(_('task name'), null=True, max_length=255)
 task_args = models.TextField(_('task arguments'), null=True)
 task_kwargs = models.TextField(_('task kwargs'), null=True)
 status = models.CharField(_('state'), max_length=50,
        default=states.PENDING,
        choices=TASK_STATE_CHOICES
        )
 content_type = models.CharField(_('content type'), max_length=128)
 content_encoding = models.CharField(_('content encoding'), max_length=64)
 result = models.TextField(null=True, default=None, editable=False)
 date_done = models.DateTimeField(_('done at'), auto_now=True)
 traceback = models.TextField(_('traceback'), blank=True, null=True)
 hidden = models.BooleanField(editable=False, default=False, db_index=True)
 meta = models.TextField(null=True, default=None, editable=False)
 objects = managers.TaskResultManager()
 class Meta:
  """Table information."""
  ordering = ['-date_done']
  verbose_name = _('task result')
  verbose_name_plural = _('task results')
 def as_dict(self):
  return {
   'task_id': self.task_id,
   'task_name': self.task_name,
   'task_args': self.task_args,
   'task_kwargs': self.task_kwargs,
   'status': self.status,
   'result': self.result,
   'date_done': self.date_done,
   'traceback': self.traceback,
   'meta': self.meta,
  }
 def __str__(self):
  return '<Task: {0.task_id} ({0.status})>'.format(self)

三、Django中使用定时任务

如果想要在django中使用定时任务功能同样是靠beat完成任务发送功能,当在Django中使用定时任务时,需要安装django-celery-beat插件。以下将介绍使用过程。

安装配置

1.beat插件安装

pip3 install django-celery-beat

2.注册APP

INSTALLED_APPS = [
 .... 
 'django_celery_beat',
]

3.数据库变更

python3 manage.py migrate django_celery_beat

4.分别启动woker和beta

celery -A proj beat -l info --scheduler django_celery_beat.schedulers:DatabaseScheduler #启动beta 调度器使用数据库
celery worker -A taskproj -l info #启动woker

5.配置admin

urls.py

# urls.py
from django.conf.urls import url
from django.contrib import admin
urlpatterns = [
 url(r'^admin/', admin.site.urls),
]

6.创建用户

python3 manage.py createsuperuser

7.登录admin进行管理(地址http://127.0.0.1:8000/admin)并且还可以看到我们上次使用orm作为结果存储的表。

http://127.0.0.1:8000/admin/login/?next=/admin/

Django中使用Celery的教程详解

 使用示例:

Django中使用Celery的教程详解

Django中使用Celery的教程详解

查看结果:

Django中使用Celery的教程详解

二次开发

django-celery-beat插件本质上是对数据库表变化检查,一旦有数据库表改变,调度器重新读取任务进行调度,所以如果想自己定制的任务页面,只需要操作beat插件的四张表就可以了。当然你还可以自己定义调度器,django-celery-beat插件已经内置了model,只需要进行导入便可进行orm操作,以下我用django reset api进行示例:

settings.py

INSTALLED_APPS = [
 'django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'app01.apps.App01Config',
 'django_celery_results',
 'django_celery_beat',
 'rest_framework',
]

urls.py

urlpatterns = [
 url(r'^admin/', admin.site.urls),
 url(r'^index$', views.index),
 url(r'^res$', views.get_res),
 url(r'^tasks$', views.TaskView.as_view({'get':'list'})),
]

views.py

from django_celery_beat.models import PeriodicTask #倒入插件model
from rest_framework import serializers
from rest_framework import pagination
from rest_framework.viewsets import ModelViewSet
class Userserializer(serializers.ModelSerializer):
 class Meta:
  model = PeriodicTask
  fields = '__all__'
class Mypagination(pagination.PageNumberPagination):
 """自定义分页"""
 page_size=2
 page_query_param = 'p'
 page_size_query_param='size'
 max_page_size=4
class TaskView(ModelViewSet):
 queryset = PeriodicTask.objects.all()
 serializer_class = Userserializer
 permission_classes = []
 pagination_class = Mypagination

访问http://127.0.0.1:8000/tasks如下:

Django中使用Celery的教程详解

总结

以上所述是小编给大家介绍的Django中使用Celery的教程详解,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Python 相关文章推荐
Python中__call__用法实例
Aug 29 Python
python实现ipsec开权限实例
Nov 11 Python
Python 专题一 函数的基础知识
Mar 16 Python
python实现八大排序算法(2)
Sep 14 Python
详解Python使用tensorflow入门指南
Feb 09 Python
python3+PyQt5图形项的自定义和交互 python3实现page Designer应用程序
Jul 20 Python
python3 flask实现文件上传功能
Mar 20 Python
Python数组并集交集补集代码实例
Feb 18 Python
Python HTMLTestRunner库安装过程解析
May 25 Python
利用Python实现Json序列化库的方法步骤
Sep 09 Python
python基础之匿名函数详解
Apr 21 Python
Django对接elasticsearch实现全文检索的示例代码
Aug 02 Python
python tornado微信开发入门代码
Aug 24 #Python
python使用rpc框架gRPC的方法
Aug 24 #Python
Python面向对象之静态属性、类方法与静态方法分析
Aug 24 #Python
python中文编码与json中文输出问题详解
Aug 24 #Python
详解Django解决ajax跨域访问问题
Aug 24 #Python
Python面向对象之反射/自省机制实例分析
Aug 24 #Python
Python使用装饰器模拟用户登陆验证功能示例
Aug 24 #Python
You might like
用 Composer构建自己的 PHP 框架之使用 ORM
2014/10/30 PHP
ubuntu下配置nginx+php+mysql详解
2015/09/10 PHP
php可变长参数处理函数详解
2017/02/22 PHP
Win10 下安装配置IIS + MySQL + nginx + php7.1.7
2017/08/04 PHP
phpinfo的知识点总结
2019/10/10 PHP
javascript 命名空间以提高代码重用性
2008/11/13 Javascript
九种js弹出对话框的方法总结
2013/03/12 Javascript
js如何实现设计模式中的模板方法
2013/07/23 Javascript
js控制table合并具体实现
2014/02/20 Javascript
js 金额格式化来回转换示例
2014/02/23 Javascript
浅析javascript 定时器
2014/12/23 Javascript
JavaScript基本的输出和嵌入式写法教程
2015/10/20 Javascript
jquery判断页面网址是否有效的两种方法
2016/12/11 Javascript
详解JavaScript调用栈、尾递归和手动优化
2017/06/03 Javascript
angularjs实现分页和搜索功能
2018/01/03 Javascript
详解Node.js模板引擎Jade入门
2018/01/19 Javascript
Vue快速实现通用表单验证功能
2019/12/05 Javascript
Vue使用screenfull实现全屏效果
2020/09/17 Javascript
在Python程序中实现分布式进程的教程
2015/04/28 Python
Python对象属性自动更新操作示例
2018/06/15 Python
python之super的使用小结
2018/08/13 Python
详解Python中is和==的区别
2019/03/21 Python
利用Python库Scapy解析pcap文件的方法
2019/07/23 Python
Python中的引用和拷贝实例解析
2019/11/14 Python
基于Django快速集成Echarts代码示例
2020/12/01 Python
使用canvas来完成线性渐变和径向渐变的功能的方法示例
2019/07/25 HTML / CSS
银行职业规划书范文
2013/12/28 职场文书
《欢乐的泼水节》教学反思
2014/04/22 职场文书
国庆节活动总结
2014/08/26 职场文书
关键在于落实心得体会
2014/09/03 职场文书
大学生国庆节65周年演讲稿范文
2014/09/25 职场文书
机动车交通事故协议书
2015/01/29 职场文书
民事申诉状范本
2015/05/20 职场文书
2015年青年教师工作总结
2015/05/25 职场文书
举起手来观后感
2015/06/09 职场文书
幼儿园小班教育随笔
2015/08/14 职场文书