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处理python编码问题
Mar 13 Python
详解Django之admin组件的使用和源码剖析
May 04 Python
python2.x实现人民币转大写人民币
Jun 20 Python
python3解析库pyquery的深入讲解
Jun 26 Python
浅谈PyQt5 的帮助文档查找方法,可以查看每个类的方法
Jun 25 Python
python tkinter组件摆放方式详解
Sep 16 Python
Pytorch技巧:DataLoader的collate_fn参数使用详解
Jan 08 Python
tensorflow 实现自定义layer并添加到计算图中
Feb 04 Python
Python数组并集交集补集代码实例
Feb 18 Python
Python3如何在Windows和Linux上打包
Feb 25 Python
keras slice layer 层实现方式
Jun 11 Python
用Python生成会跳舞的美女
Jan 18 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
ThinkPHP3.2.2的插件控制器功能简述
2014/07/09 PHP
微信推送功能实现方式图文详解
2019/07/12 PHP
基于JavaScript实现继承机制之构造函数+原型链混合方式的使用详解
2013/05/07 Javascript
解决JQeury显示内容没有边距内容紧挨着浏览器边线
2013/12/20 Javascript
把字符串按照特定的字母顺序进行排序的js代码
2014/01/28 Javascript
Javascript高级技巧分享
2014/02/25 Javascript
js通过iframe加载外部网页的实现代码
2015/04/05 Javascript
js控制div弹出层实现方法
2015/05/11 Javascript
浅谈javascript的分号的使用
2015/05/12 Javascript
js判断移动端是否安装某款app的多种方法
2015/12/18 Javascript
浅析AngularJS Filter用法
2015/12/28 Javascript
JS不用正则验证输入的字符串是否为空(包含空格)的实现代码
2016/06/14 Javascript
AngularJS bootstrap启动详解及实例代码
2016/09/14 Javascript
用js将long型数据转换成date型或datetime型的实例
2017/07/03 Javascript
Vue实现table上下移动功能示例
2019/02/21 Javascript
js逆向解密之网络爬虫
2019/05/30 Javascript
Javascript模拟实现new原理解析
2020/03/03 Javascript
在vue中嵌入外部网站的实现
2020/11/13 Javascript
用vue设计一个日历表
2020/12/03 Vue.js
HTML元素拖拽功能实现的完整实例
2020/12/04 Javascript
[01:08:44]NB vs VP 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/19 DOTA
深入理解NumPy简明教程---数组1
2016/12/17 Python
Python使用jsonpath-rw模块处理Json对象操作示例
2018/07/31 Python
Django进阶之CSRF的解决
2018/08/01 Python
Python检查和同步本地时间(北京时间)的实现方法
2018/12/03 Python
python自定义函数实现一个数的三次方计算方法
2019/01/20 Python
PyQt5笔记之弹出窗口大全
2019/06/20 Python
canvas 橡皮筋式线条绘图应用方法
2019/02/13 HTML / CSS
澳大利亚购买健身器材网站:Gym Direct
2019/12/19 全球购物
介绍一下gcc特性
2015/10/31 面试题
党员培训思想汇报
2014/01/07 职场文书
2015元旦节寄语
2014/12/08 职场文书
承诺书范本
2015/01/21 职场文书
学校党员干部承诺书
2015/05/04 职场文书
2015年档案管理员工作总结
2015/05/13 职场文书
python中的plt.cm.Paired用法说明
2021/05/31 Python