Skip to main content
 首页 » 编程设计

python之Django 1.8.5 和 Celery 的 ImportError

2025年05月04日22exmyth

我正在尝试让 Celery 运行 Django,遵循官方文档和位于此处的视频:https://godjango.com/63-deferred-tasks-and-scheduled-jobs-with-celery-31-django-17-and-redis/

我不知道我做错了什么,但这总是会导致 ImportError。

该项目名为“clubmgmt”

“clubmgmt/celery.py”的内容:

from __future__ import absolute_import 
import os 
import django 
from celery import Celery 
from django.conf import settings 
 
# set the default Django settings module for the 'celery' program. 
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'clubmgmt.settings') 
django.setup() 
 
app = Celery('clubmgmt') 
 
# Using a string here means the worker will not have to 
# pickle the object when using Windows. 
app.config_from_object('django.conf:settings') 
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS) 

“clubmgmt/__init__.py”的内容

from __future__ import absolute_import 
 
# This will make sure the app is always imported when 
# Django starts so that shared_task will use this app. 
from clubmgmt.celery import app as celery_app 

任务在名为“activation”的应用中定义

“activation/tasks.py”的内容:

from activation.models import Activation 
from django.conf import settings 
from django.template.loader import render_to_string 
import smtplib 
from email.mime.text import MIMEText 
from email.mime.multipart import MIMEMultipart 
from clubmgmt.celery import app 
 
__author__ = 'jeroenjacobs' 
 
@app.task 
def send_activation_mail(activation_pk): 
    activation = Activation.objects.get(pk=activation_pk) 
    mail = activation.user.email 
 
    msg = MIMEMultipart('alternative') 
    msg['Subject'] = "Please activate your account" 
    msg['From'] = settings.SMTP_SENDER_ADDRESS 
    msg['To'] = mail 
    ... 

我总是收到以下错误:

(clubmgmt) > $ python manage.py runserver                                                                                                                      [±master ●●●] 
Traceback (most recent call last): 
  File "manage.py", line 10, in <module> 
    execute_from_command_line(sys.argv) 
  File "/Users/jeroenjacobs/.pyenv/versions/clubmgmt/lib/python3.4/site-packages/django/core/management/__init__.py", line 351, in execute_from_command_line 
    utility.execute() 
  File "/Users/jeroenjacobs/.pyenv/versions/clubmgmt/lib/python3.4/site-packages/django/core/management/__init__.py", line 303, in execute 
    settings.INSTALLED_APPS 
  File "/Users/jeroenjacobs/.pyenv/versions/clubmgmt/lib/python3.4/site-packages/django/conf/__init__.py", line 48, in __getattr__ 
    self._setup(name) 
  File "/Users/jeroenjacobs/.pyenv/versions/clubmgmt/lib/python3.4/site-packages/django/conf/__init__.py", line 44, in _setup 
    self._wrapped = Settings(settings_module) 
  File "/Users/jeroenjacobs/.pyenv/versions/clubmgmt/lib/python3.4/site-packages/django/conf/__init__.py", line 92, in __init__ 
    mod = importlib.import_module(self.SETTINGS_MODULE) 
  File "/Users/jeroenjacobs/.pyenv/versions/3.4.3/Python.framework/Versions/3.4/lib/python3.4/importlib/__init__.py", line 109, in import_module 
    return _bootstrap._gcd_import(name[level:], package, level) 
  File "<frozen importlib._bootstrap>", line 2254, in _gcd_import 
  File "<frozen importlib._bootstrap>", line 2237, in _find_and_load 
  File "<frozen importlib._bootstrap>", line 2212, in _find_and_load_unlocked 
  File "<frozen importlib._bootstrap>", line 321, in _call_with_frames_removed 
  File "<frozen importlib._bootstrap>", line 2254, in _gcd_import 
  File "<frozen importlib._bootstrap>", line 2237, in _find_and_load 
  File "<frozen importlib._bootstrap>", line 2226, in _find_and_load_unlocked 
  File "<frozen importlib._bootstrap>", line 1200, in _load_unlocked 
  File "<frozen importlib._bootstrap>", line 1129, in _exec 
  File "<frozen importlib._bootstrap>", line 1471, in exec_module 
  File "<frozen importlib._bootstrap>", line 321, in _call_with_frames_removed 
  File "/Users/jeroenjacobs/PycharmProjects/clubmgmt/clubmgmt/__init__.py", line 5, in <module> 
    from clubmgmt.celery import app as celery_app 
  File "/Users/jeroenjacobs/PycharmProjects/clubmgmt/clubmgmt/celery.py", line 9, in <module> 
    django.setup() 
  File "/Users/jeroenjacobs/.pyenv/versions/clubmgmt/lib/python3.4/site-packages/django/__init__.py", line 18, in setup 
    apps.populate(settings.INSTALLED_APPS) 
  File "/Users/jeroenjacobs/.pyenv/versions/clubmgmt/lib/python3.4/site-packages/django/apps/registry.py", line 115, in populate 
    app_config.ready() 
  File "/Users/jeroenjacobs/PycharmProjects/clubmgmt/activation/apps.py", line 10, in ready 
    import activation.handlers 
  File "/Users/jeroenjacobs/PycharmProjects/clubmgmt/activation/handlers.py", line 6, in <module> 
    from activation.utils import create_or_update_activation 
  File "/Users/jeroenjacobs/PycharmProjects/clubmgmt/activation/utils.py", line 2, in <module> 
    from activation.tasks import send_activation_mail 
  File "/Users/jeroenjacobs/PycharmProjects/clubmgmt/activation/tasks.py", line 7, in <module> 
    from clubmgmt.celery import app 
ImportError: cannot import name 'app' 

谁能解释一下为什么“app”无法导入?

顺便说一句:这是在 python 3.4 下测试的。回到 Python 2 不是一种选择,所以请不要建议将其作为解决方案。如果 Celery 与 Python3 不兼容,是否有其他选择?

请您参考如下方法:

问题是 clubmgmt.celery.app 尝试导入 clubmgm.celery.app 导致循环导入。

如果你查看你的堆栈跟踪 clubmgmt.__init__ 导入 clubmgmt.celery.app,这反过来使 django 运行它的设置例程这最终触发了 clubmgmt.activation.apps 的导入,它在某个时候通过 clubmgmt.activation.tasks 再次导入 clubmgmt.celery.app ,而它仍在导入,导致 ImportError。

从 __init__.py 中删除导入肯定会解决问题,但如果你仍然需要它,你可以使用 activation/apps.py 做一些事情> 相反。

到目前为止,我了解到的一件事是,90% 的 ImportError 发生是由于循环导入,另外 10% 是由于拼写错误或类似的原因。