1

Before any explanations, here is the tree of my project

| projectname
|____|__init__.py
|____|celery.py
|____|settings.py
|____|urls.py
|____|wsgi.py
|app1
|app2

Here's my celery.py

from celery import Celery
from celery import shared_task

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'projectname.settings')
app = Celery('projectname')
app.config_from_object('django.conf:settings', namespace='CELERY')
app.autodiscover_tasks()

from app1.models import *

@share_task
def tasks():
     ''' '''

Every time I try importing models to the celery.py file with this line from app1.models import * I got:

django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet.

And the local server stops working all of a sudden. This post is related to a similar problem, but not sure it's the case here.

What I want is to import some models to the file, so I can use them for some queries.

I got a little clue about what can be wrong, but not sure.

views import stuff from models.py
views import stuff from celery.py like the task to be executed
celery.py tries to import stuff from models.

So that circle like a snake that bites its own tail is weird to me.

Djensen
  • 1,337
  • 1
  • 22
  • 32

1 Answers1

5

The problem is when you try to upload your tasks before Django loads the configuration() with

from app1.models import *
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'projectname.settings')
app = Celery('projectname')

app.config_from_object('django.conf:settings', namespace='CELERY')
app.autodiscover_tasks()

Off course Celery will detect tasks in celery.py file, remember that you have imported everything from celery.py to __init__.py to let Django loads them (Celery stuff,...) every time the project starts.

__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']

So with this case you're importing models in that celery.py file let's say __init.py__ as well, Your models will be imported before Django loads its configuration while Apps in your settings.py aren't built yet.

You should not import Django app stuffs into your __init__.py file, modules/apps are built before Django loads the configuration(settings.py), this will raise an Error Apps aren't loaded yet if you try to upload like models in __init__.py file.

According to the documentation, Celery has app.autodiscover_tasks() able to discover every tasks found in any well-registered app in settings.INSTALLED_APPS. Instead of importing tasks in the celery.py Just create a tasks.py file in all your apps.

| projectname
|____|__init__.py
|____|celery.py # contains app.autodiscover_tasks()
|____|settings.py
|____|urls.py
|____|wsgi.py
|app1
|____|tasks.py
|app2
|____|tasks.py

Tasks may work in celery.py file, but not when uploading Model from apps, use app.autodiscover_tasks() instead

Use as well absolute imports from the future if needed

from __future__ import absolute_import
Lemayzeur
  • 8,297
  • 3
  • 23
  • 50
  • 1
    Last night, I ended up doing this, it works well! thanks for your answer, and also for the details, it helps me understand what was wrong. I was supposed to be happy to solve this issue, but I'm struggling with another one (Sad), not a related issue, maybe I will ask another question, anyway thank you. this answer is good, and the accepted one –  Jun 04 '18 at 13:13
  • I had to put myself in the same situation with the same issue to figure out what was wrong. glad it works,as you said, ***I bet my question is not awesome at all***, you were right.(laugh) – Lemayzeur Jun 04 '18 at 13:18
  • 1
    Question and answer both are very helpful. Saved my time and fixed my issue. Good work guys. – Khaksar Jun 03 '21 at 08:01