异步任务利器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‘

启动:

$ 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

  

时间: 2024-12-21 18:12:44

异步任务利器Celery(二)在django项目中使用Celery的相关文章

Django项目中使用Redis

Django项目中使用Redis DjangoRedis 1 redis Redis 是一个 key-value 存储系统,常用于缓存的存储.django-redis 基于 BSD 许可, 是一个使 Django 支持 Redis cache/session 后端的全功能组件. 1.1 为何要用 django-redis ? 持续更新 本地化的 redis-py URL 符号连接字符串 可扩展客户端 可扩展解析器 可扩展序列器 默认客户端主/从支持 完善的测试 已在一些项目的生产环境中作为 ca

django项目中遇到要实现定时任务

django项目中遇到要实现定时任务,所以选用了简单易用的django-crontab插件. 1.安装 django-crontab pip install django-crontab 2.定时要执行的脚本 先写个简单的测试脚本. ipoms/crons.py import datetime def update_stock_status(): start_time = datetime.datetime.now() print start_time, ", begin update_stoc

Django项目中的实现rbac功能

一.什么是rbacrbac翻译意思就是(Role-Based Access Contro)基于角色的权限控制 二.优势1.将用户和权限的关系2.易扩展,易于维护 比如张三李四需要用客户列表访问权限,如果上百个用户,单独分配权限会麻烦,如果单独放客户列表权限在销售角色里面,张三李四放到销售角色里就OK了 三.RBAC流程图 第一张:用户表第二张:角色表第三张表:用户表和角色表多对多的关系,一个用户可以有多个角色第四张表:权限表第五张表:权限表和角色表多对多的关系,多个权限可以放到一个角色里面 四.

在Django项目中使用富文本编辑器

1 开发要点 现在网上有很多的富文本编辑器,包括Markdown.tinymce.UEditor.KindEditor.ckeditor等等.在项目中使用这些编辑器主要有以下几个问题: 编辑页面 在HTML页面渲染编辑器: 定制编辑器的功能,比如有哪些文本样式.图片上传.代码插入: 定制编辑器的样式,指的是编辑器整体的样式,比如高度.宽度.显示位置等等: 预览内容: 获取内容: 显示页面 显示内容: 2 Django APP 下表列出一些常用的APP,它们都可以在GitHub上找的到,链接见下文

django项目中使用FastDFS

FastDFS客户端与自定义文件存储系统 1. FastDFS的Python客户端 python版本的FastDFS客户端使用说明参考https://github.com/jefforeilly/fdfs_client-py 安装 安装提供给大家的fdfs_client-py-master.zip到虚拟环境中 pip install fdfs_client-py-master.zippip install mutagenpip isntall requests 使用 使用FastDFS客户端,需

django项目中购物车的实现

对于做项目而言,最重要的是分析清楚自己负责模块的思路,确定思路后,把每一步实现的步骤确定后,根据步骤,去实现代码,测试. 购物车的逻辑:    登录用户可以添加购物车,未登陆用户页可以添加到购物车    登陆用户的保存user.id sku_id count selected      保存在redis中,以hash和set两种方式保存    未登陆用户保存sku_id count selectd  保存再cookie中    cart = {            sku_id:{count:

从数据库反向生成django项目中的models文件

1.创建一个django项目 2.在项目配置文件settings.py中配置好数据库的相关配置 3.确保所关联的数据库中已经有表存在 4.在pycharm终端进入到项目的根目录,执行python manage.py inspectdb,查看可以导入到models的相关信息 5.执行python manage.py inspectdb > (需要导入表的app)/models.py,即可完成反向生成models文件 6.进入models文件进行相关修改 原文地址:https://www.cnblo

项目总结二:关于项目中一些功能的优化

前言: 最近一直在维护老的项目,遇到的问题也千奇百怪,需要修补的,需要优化的,需要特殊处理的,感觉总是那么的无语.也许这时候也应该感叹一句:路漫漫其修远兮,吾将上下而求索吧. 这篇文章就只是讲讲老项目中遇到的种种不敢苟同的代码写法,以及遇到一些问题时的处理方法. 1.关于按钮事件的重复点击问题 我们开发中大概都经历过这样的事情,我的一个button被重复的快速点击,(我们开发者应该更清楚的知道这意味着什么).那我们再深入的想一下(给这样的事件安排一个特定的环境):例如当网络较差的情况下,再例如当

DWR(二):项目中使用多个Dwr.xml配置文件

工程文件结构 项目中配置多个DWR文件,其实就是配置多个DWR的servlet,并且给每个servlet配置dwr的映射文件: <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"