异步任务利器Celery(二)在django项目中使用Celery
Celery 4.0支持django1.8及以上的版本,低于1.8的项目使用Celery 3.1。
一个django项目的组织如下:
- proj/
- manage.py
- proj/
- __init__.py
- settings.py
- urls.py
首先建立proj/proj/celery.py文件:
from __future__ import absolute_import, unicode_literals
import os
from celery import Celery # set the default Django settings module for the 'celery' program.
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'proj.settings') app = Celery('proj') # Using a string here means the worker doesn't have to serialize
# the configuration object to child processes.
# - namespace='CELERY' means all celery-related configuration keys
# should have a `CELERY_` prefix.
app.config_from_object('django.conf:settings', namespace='CELERY') # Load task modules from all registered Django app configs.
app.autodiscover_tasks() @app.task(bind=True)
def debug_task(self):
print('Request: {0!r}'.format(self.request))
然后要保证django项目启动时上述的app被载入,修改proj/proj/__init__.py文件:
from __future__ import absolute_import, unicode_literals # This will make sure the app is always imported when
# Django starts so that shared_task will use this app.
from .celery import app as celery_app __all__ = ['celery_app']
现在就可以在INSTALLED_APPS中的app下建立tasks.py文件啦:
- app1/
- tasks.py
- models.py
- app2/
- tasks.py
- models.py
比如:
# Create your tasks here
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 @shared_task
def xsum(numbers):
return sum(numbers)
在views中调用这些tasks即可异步运行。
如果使用Redis作为broker,在settings.py中添加:
CELERY_BROKER_URL = 'redis://localhost:6379/0'
可以使用Django ORM/Cache作为储存backend。
下载库:
$ pip install django-celery-results
设定settings.py:
INSTALLED_APPS = (
...,
'django_celery_results',
)
建立数据表:
$ python manage.py migrate django_celery_results
在settings.py中添加Celery设置:
CELERY_RESULT_BACKEND = 'django-db'
或者
CELERY_RESULT_BACKEND = 'django-cache'
区别在于使用django ORM还是使用django缓存系统。
启动:
$ celery -A proj worker -l info
可以在python manage.py shell中调用:
$ python manage.py shell
Python 2.7.12 (default, Nov 19 2016, 06:48:10)
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from app1.tasks import add
>>> add.delay(3,4)
<AsyncResult: a9abab6d-b7a9-47e6-8c09-ec284948449f>
celery日志:
[2017-09-14 00:09:41,432: INFO/ForkPoolWorker-1] Task urldata.tasks.add[38af760e-ed6c-48f8-b77c-d67bade8d6b8] succeeded in 0.00782653002534s: 7
官方一个完整的例子:https://github.com/celery/celery/tree/master/examples/django/
官方文档还有一个异步审查用户上传评论的例子。
blog/models.py:
from django.db import models
from django.utils.translation import ugettext_lazy as _ class Comment(models.Model):
name = models.CharField(_('name'), max_length=64)
email_address = models.EmailField(_('email address'))
homepage = models.URLField(_('home page'),
blank=True, verify_exists=False)
comment = models.TextField(_('comment'))
pub_date = models.DateTimeField(_('Published date'),
editable=False, auto_add_now=True)
is_spam = models.BooleanField(_('spam?'),
default=False, editable=False) class Meta:
verbose_name = _('comment')
verbose_name_plural = _('comments')
在views中先保存评论,同时调用celery异步审核。
blog/views.py:
from django import forms
from django.http import HttpResponseRedirect
from django.template.context import RequestContext
from django.shortcuts import get_object_or_404, render_to_response from blog import tasks
from blog.models import Comment class CommentForm(forms.ModelForm): class Meta:
model = Comment def add_comment(request, slug, template_name='comments/create.html'):
post = get_object_or_404(Entry, slug=slug)
remote_addr = request.META.get('REMOTE_ADDR') if request.method == 'post':
form = CommentForm(request.POST, request.FILES)
if form.is_valid():
comment = form.save()
# Check spam asynchronously.
tasks.spam_filter.delay(comment_id=comment.id,
remote_addr=remote_addr)
return HttpResponseRedirect(post.get_absolute_url())
else:
form = CommentForm() context = RequestContext(request, {'form': form})
return render_to_response(template_name, context_instance=context)
tasks如下:
blog/tasks.py
from celery import Celery from akismet import Akismet from django.core.exceptions import ImproperlyConfigured
from django.contrib.sites.models import Site from blog.models import Comment app = Celery(broker='amqp://') @app.task
def spam_filter(comment_id, remote_addr=None):
logger = spam_filter.get_logger()
logger.info('Running spam filter for comment %s', comment_id) comment = Comment.objects.get(pk=comment_id)
current_domain = Site.objects.get_current().domain
akismet = Akismet(settings.AKISMET_KEY, 'http://{0}'.format(domain))
if not akismet.verify_key():
raise ImproperlyConfigured('Invalid AKISMET_KEY') is_spam = akismet.comment_check(user_ip=remote_addr,
comment_content=comment.comment,
comment_author=comment.name,
comment_author_email=comment.email_address)
if is_spam:
comment.is_spam = True
comment.save() return is_spam
异步任务利器Celery(二)在django项目中使用Celery的更多相关文章
- Django项目中使用celery做异步任务
异步任务介绍 在写项目过程中经常会遇到一些耗时的任务, 比如:发送邮件.发送短信等等~.这些操作如果都同步执行耗时长对用户体验不友好,在这种情况下就可以把任务放在后台异步执行 celery就是用于处理 ...
- celery 分布式异步任务框架(celery简单使用、celery多任务结构、celery定时任务、celery计划任务、celery在Django项目中使用Python脚本调用Django环境)
一.celery简介: Celery 是一个强大的 分布式任务队列 的 异步处理框架,它可以让任务的执行完全脱离主程序,甚至可以被分配到其他主机上运行.我们通常使用它来实现异步任务(async tas ...
- [翻译]在Django项目中添加谷歌统计(Google Analytics)
原文:<Google Analytics tracking code into Django projects, the easy way> 对我来说,制作一个可扩展的Django应用随时 ...
- Django项目中使用Redis
Django项目中使用Redis DjangoRedis 1 redis Redis 是一个 key-value 存储系统,常用于缓存的存储.django-redis 基于 BSD 许可, 是一个使 ...
- 擦他丫的,今天在Django项目中引用静态文件jQuery.js 就是引入报错,终于找到原因了!
擦 ,今天在Django项目中引用静态文件jQuery.js 就是引入报错,终于找到原因了! 问题在于我使用的谷歌浏览器,默认使用了缓存,导致每次访问同一个url时,都返回的是缓存里面的东西.通过谷歌 ...
- django 项目中使用多数据库 multiple databases
假如在一个django项目中使用到了不只一个数据库, 其实这在大一点的工程中很常见,比如主从库 那么会涉及到如下一些东西 1, 定义 在settings中的DATABASE中定义会使用到的数据,比如除 ...
- django 项目中的 favicon.ico 处理
django 项目中的 favicon.ico 处理 (django == 2.0.6) 1. 引入模块: from django.views.generic.base import Redirec ...
- Django项目中模板标签及模板的继承与引用【网站中快速布置广告】
Django项目中模板标签及模板的继承与引用 常见模板标签 {% static %} {% for x in range(x) %}{% endfor %} 循环的序号{% forloop %} 循环 ...
- Django项目中"expected str, bytes or os.PathLike object, not list"错误解决:
对于这个错误,也在于自己对django基础的掌握不是很牢固,忽略了MEDIA_ROOT的类型是string,而不是list. 错误的写法: MEDIA_ROOT = [ os.path.join(BA ...
随机推荐
- Django Form(表单)
前台用 get 或 post 方法向后台提交一些数据. GET方法: html示例(保存在templates文件夹中): <!DOCTYPE html> <html> < ...
- Selenium基础知识(六)下拉列表定位
1.下拉列表定位 要选择下拉列表中的元素,要先定位到,下拉列表元素,然后可以通过xpath去点击,表内内容 例如,百度搜索-->百度设置-->搜索设置-->选择下拉列表框内" ...
- Spring @Value注解 and Spring Boot @ConfigurationProperties注解
一.Spring的@Value Spring EL表达式语言,支持在XML和注解中表达式,类是于JSP的EL表达式语言. 在Spring开发中经常涉及调用各种资源的情况,包含普通文件.网址.配置文件. ...
- 自定义Http请求头并且获取
在一些开发需求中.我们需要把一些信息放到Http请求头中.比如我需要把签名信息 signature 放到Http请求头 所以就需要自定义请求头 signature ,用webClient发起请求 我这 ...
- js执行上下文
js在执行是会有一个“准备工作”: 主要内容有 1.变量.函数表达式——>变量声明,默认赋值为undefined: 2.this——>赋值: 3.函数声明——>赋值: 这三种数据的准 ...
- 集体干死java 在启动.sh
#!/bin/bash#reboot .jar#author wangdonghuipid=`ps -ef |grep java |awk '{print $2}'`echo $pidecho'--- ...
- NHibernate初学者指南系列文章导航
NHibernate初学者指南系列文章导航 前面的话 经过三个多周的时间,终于将这个系列完成了,谢谢大家的关注和支持,有很多不足之处还望大家包涵. 本系列参考的书籍为NHibernate 3 Be ...
- WEB应用程序:AJAX全套
概述 对于WEB应用程序:用户浏览器发送请求,服务器接收并处理请求,然后返回结果,往往返回就是字符串(HTML),浏览器将字符串(HTML)渲染并显示浏览器上. 1.传统的Web应用 一个简单操作需要 ...
- C/C++笔试题(编程题)
面试过程中遇到的编程题整理,于此备录.分享,共勉.(持续更新中......欢迎补充) (1)用户输入M, N值,从1至N开始顺序循环数数,每数到M输出该数值,直至全部输出.写出C程序. 程序代码如下: ...
- weblogic 乱码
1.找到weblogic安装目录,当前项目配置的domain 2.找到bin下的setDomainEnv.cmd文件 3.打开文件,从文件最后搜索第一个set JAVA_OPTIONS=%JAVA_O ...