[Django]-Unusual warning with djcelery, billiard, and the django_settings_module

2👍

✅

Oddly enough, I just ran into the same problem! Looking up the file in question (billiard/forking.py), I found this function:

def _Django_old_layout_hack__save():
    if 'DJANGO_PROJECT_DIR' not in os.environ:
        try:
            settings_name = os.environ['DJANGO_SETTINGS_MODULE']
        except KeyError:
            return  # not using Django.

        try:
            project_name, _ = settings_name.split('.', 1)
        except ValueError:
            return  # not modified by setup_environ

        project = __import__(project_name)
        try:
            project_dir = os.path.normpath(_module_parent_dir(project))
        except AttributeError:
            return  # dynamically generated module (no __file__)
        warnings.warn(UserWarning(
            W_OLD_DJANGO_LAYOUT % os.path.realpath(project_dir)
        ))
        os.environ['DJANGO_PROJECT_DIR'] = project_dir

This function apparently does some sanity checks on os.environ. Notice that, after retrieving DJANGO_SETTINGS_MODULE, it tries to split the module name by a period. This code seems to assume that, if your DJANGO_SETTINGS_MODULE is a top-level module (as it is, by default), then your environment hasn’t been modified.

Unfortunately, if it isn’t a top-level module, it seems to assume that you used setup_environ, and that it must now add the project directory to the path.

In my case, I had simply moved the simple settings.py module out into its own settings package, splitting it up into the common, and development/production files. Of course, I had to modify manage.py and wsgi.py to point to the correct settings module. Which, of course, started to trigger this warning.

The way I worked around it was by adding the DJANGO_PROJECT_DIR variable directly in my manage.py. I’m not sure if I’ll need to add it elsewhere (e.g. in production environments), but that’s all I’ve run into so far.

Here’s the relevant line in manage.py:

if __name__ == "__main__":
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings.current")

    # Add the project directory to the path, to appease billiard
    os.environ.setdefault("DJANGO_PROJECT_DIR",
        os.path.dirname(os.path.realpath(__file__)))

2👍

I’m using django 1.4 and celery 3.0.11.

thank’s @voithos. I tried yours solution. It’s work for me.

But I came across another solution, much more simple. no need of creating a new module settings.

Juste add this piece of code into your manage.py file

      # Add the project directory to the path, to appease billiard
      os.environ.setdefault("DJANGO_PROJECT_DIR", os.path.dirname(os.path.realpath(__file__)))

finally my manage.py file looks like this

if __name__ == "__main__":
      os.environ.setdefault("DJANGO_SETTINGS_MODULE", "sample.settings")

      from django.core.management import execute_from_command_line

      # Add the project directory to the path, to appease billiard
      os.environ.setdefault("DJANGO_PROJECT_DIR",os.path.dirname(os.path.realpath(__file__)))

      execute_from_command_line(sys.argv)

Leave a comment