我有一个Django项目
RabbitMQ正在运行(从命令行进行测试,它接收消息)
芹菜正在运行并识别任务。
简化的项目树:
├── wha/core │ ├── wha/core/__init__.py │ ├── wha/core/celery.py │ ├── wha/core/settings.py │ ├── wha/core/urls.py │ └── wha/core/wsgi.py ├── wha/factura │ ├── wha/factura/__init__.py │ ├── wha/factura/admin.py │ ├── wha/factura/forms.py │ ├── wha/factura/models.py │ ├── wha/factura/urls.py │ └── wha/factura/views.py └── wha/manage.pywha / core / init .py
from __future__ import absolute_import from .celery import app as celery_appwha / core / celery.py( 作为文档 )
from __future__ import absolute_import import os from celery import Celery os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'core.settings') from django.conf import settings app = Celery('core') app.config_from_object('django.conf:settings') app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)WHA /型芯/ settings.py
BROKER_URL = 'amqp://XXX:XXX@localhost:5672//' CELERY_ACCEPT_CONTENT = ['json'] CELERY_TASK_SERIALIZER = 'json' CELERY_RESULT_SERIALIZER = 'json' CELERY_RESULT_BACKEND = "amqp" CELERY_IMPORTS = ('factura.views')WHA / factura / views.py
@task(name="factura.views.notify") def notify(request, uid): factura = get_object_or_404(Factura, pk=uid) subject = '%s - Your domain' % factura.contrato.dominio.nombre.upper() from_email = 'Mail Name <asd@asd.com>' to = [factura.contrato.dominio.cliente.email][...]等等,发送电子邮件, uid真的是“factura”id。 我觉得没关系。
Celery控制台输出(调试)
-------------- celery@nnbmp.local v3.1.19 (Cipater) ---- **** ----- --- * *** * -- Darwin-15.2.0-x86_64-i386-64bit -- * - **** --- - ** ---------- [config] - ** ---------- .> app: core:0x10c451fd0 - ** ---------- .> transport: amqp://hola:**@nnmbp:5672// - ** ---------- .> results: amqp - *** --- * --- .> concurrency: 4 (prefork) -- ******* ---- --- ***** ----- [queues] -------------- .> celery exchange=celery(direct) key=celery [tasks] . celery.backend_cleanup . celery.chain . celery.chord . celery.chord_unlock . celery.chunks . celery.group . celery.map . celery.starmap . factura.views.notify调用视图的URL:
http://localhost:8000/factura/notify/8其中8是“factura”id,
编辑:
不起作用的是,当我从浏览器调用“factura.notify”时,Celery无法识别被调用的任务,因此它不会向RabbitMQ发送消息。
知道为什么这不起作用吗?
I have a Django project
RabbitMQ is running (testing from command line, it receives messages)
Celery is running and recognising tasks.
Simplified tree of project:
├── wha/core │ ├── wha/core/__init__.py │ ├── wha/core/celery.py │ ├── wha/core/settings.py │ ├── wha/core/urls.py │ └── wha/core/wsgi.py ├── wha/factura │ ├── wha/factura/__init__.py │ ├── wha/factura/admin.py │ ├── wha/factura/forms.py │ ├── wha/factura/models.py │ ├── wha/factura/urls.py │ └── wha/factura/views.py └── wha/manage.pywha/core/init.py
from __future__ import absolute_import from .celery import app as celery_appwha/core/celery.py (as docs)
from __future__ import absolute_import import os from celery import Celery os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'core.settings') from django.conf import settings app = Celery('core') app.config_from_object('django.conf:settings') app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)wha/core/settings.py
BROKER_URL = 'amqp://XXX:XXX@localhost:5672//' CELERY_ACCEPT_CONTENT = ['json'] CELERY_TASK_SERIALIZER = 'json' CELERY_RESULT_SERIALIZER = 'json' CELERY_RESULT_BACKEND = "amqp" CELERY_IMPORTS = ('factura.views')wha/factura/views.py
@task(name="factura.views.notify") def notify(request, uid): factura = get_object_or_404(Factura, pk=uid) subject = '%s - Your domain' % factura.contrato.dominio.nombre.upper() from_email = 'Mail Name <asd@asd.com>' to = [factura.contrato.dominio.cliente.email][...] blah blah, sends email, uid is really "factura" id. I think doesn't matter.
Celery console output (debug)
-------------- celery@nnbmp.local v3.1.19 (Cipater) ---- **** ----- --- * *** * -- Darwin-15.2.0-x86_64-i386-64bit -- * - **** --- - ** ---------- [config] - ** ---------- .> app: core:0x10c451fd0 - ** ---------- .> transport: amqp://hola:**@nnmbp:5672// - ** ---------- .> results: amqp - *** --- * --- .> concurrency: 4 (prefork) -- ******* ---- --- ***** ----- [queues] -------------- .> celery exchange=celery(direct) key=celery [tasks] . celery.backend_cleanup . celery.chain . celery.chord . celery.chord_unlock . celery.chunks . celery.group . celery.map . celery.starmap . factura.views.notifyURL for calling the view:
http://localhost:8000/factura/notify/8Where 8 is the "factura" id,
EDIT:
The thing that isn't working is that when I call "factura.notify" from the browser, Celery doesn't recognise the task being called, so it doesn't send a message to RabbitMQ.
Any idea why this isn't working?
最满意答案
它不起作用的原因是您将视图作为芹菜任务运行,这显然是错误的。 你的观点应该通过一个任务(例如generate_invoice.delay() , send_email.delay() )将一些工作(例如生成PDF,发送电子邮件)卸载到Celery,而不是任务本身。
现在Django将url解析为notify函数(可调用),并且只是同步执行它,因此它不会发布到Celery消息代理。
这是你应该做的一个例子:
def notify(request, uid): ... tasks.process_invoice.delay(invoice_id) return response @task def process_invoice(invoice_id): ...The reason it does not work is that you are running views as celery tasks, that's plain wrong. Your views should offload some work (eg. generate a pdf, send an email) to Celery via a task (eg. generate_invoice.delay(), send_email.delay()), not be the task itself.
Right now Django resolves the url to the notify function (which is a callable) and simply executes it in sync and therefore it does not get published to your Celery message broker.
Here's an example of you should probably do:
def notify(request, uid): ... tasks.process_invoice.delay(invoice_id) return response @task def process_invoice(invoice_id): ...更多推荐
发布评论