Opened 4 years ago

Closed 4 years ago

Last modified 4 years ago

#15064 closed Bug (fixed)

DJANGO_SETTINGS_MODULE doesn't work with runserver

Reported by: olau Owned by: ShawnMilo
Component: Core (Management commands) Version: 1.3
Severity: Normal Keywords:
Cc: gordl, dougal85@…, luc.saffre@… Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: yes UI/UX:

Description

The help for --settings claims that one can use DJANGO_SETTINGS_MODULE to specify the settings module as an alternative to --settings. This seems to be wrong on two accounts, first it works even without a DJANGO_SETTINGS_MODULE (since it guesses settings.py), second setting DJANGO_SETTINGS_MODULE doesn't seem to have any effect at all with runserver.

If I try "DJANGO_SETTINGS_MODULE=alternative_settings python manage.py runserver" with a print in alternative_settings.py, I never get the print. The culprit seems to be setup_environ in django.core.init.py:

    # Set DJANGO_SETTINGS_MODULE appropriately.
    if original_settings_path:
        os.environ['DJANGO_SETTINGS_MODULE'] = original_settings_path
    else:
        os.environ['DJANGO_SETTINGS_MODULE'] = '%s.%s' % (project_name, settings_name)

This always overwrites the environment variable; if I delete those lines, my alternative_settings.py are imported. I guess the correct fix is checking that DJANGO_SETTINGS_MODULE isn't set before overwriting it.

Attachments (4)

15064_DJANGO_SETTINGS_MODULE_ignored.diff (2.8 KB) - added by ShawnMilo 4 years ago.
Patch with test. If environment variable DJANGO_SETTINGS_MODULE is set it will be used.
15064_DJANGO_SETTINGS_MODULE_ignored_2.diff (3.0 KB) - added by ShawnMilo 4 years ago.
Restored os.environ variable to original value after tests. Removed whitespace.
15064_setup_teardown.diff (3.8 KB) - added by ShawnMilo 4 years ago.
TestCase setUp and tearDown to ensure environment is not changed.
15064_DJANGO_SETTINGS_MODULE_ignored_update.diff (3.8 KB) - added by ShawnMilo 4 years ago.
Update due to conflict with current trunk.

Download all attachments as: .zip

Change History (23)

comment:1 Changed 4 years ago by russellm

  • Component changed from Uncategorized to django-admin.py
  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Triage Stage changed from Unreviewed to Accepted

There is an inconsistency here, which should be addressed. manage.py and django-admin.py do much more path-fiddling than is good practice, and this sort of bug is the result.

comment:2 follow-up: Changed 4 years ago by gordl

  • Cc gordl added
  • Severity set to Normal
  • Type set to Uncategorized

And, what's worse is that when populating the settings via the command line, the overridden settings are never loaded. If I have a custom set of settings for certain management commands

manage.py mymanagementcommand --settings=custom_settings

The settings specified are not loaded.

comment:3 in reply to: ↑ 2 Changed 4 years ago by gordl

Replying to gordl:

And, what's worse is that when populating the settings via the command line, the overridden settings are never loaded. If I have a custom set of settings for certain management commands

manage.py mymanagementcommand --settings=custom_settings

The settings specified are not loaded.

Sorry, ignore this. Turns out I had some code that import used django.conf settings at import time that caused the standard settings.py to be used.

comment:4 Changed 4 years ago by anonymous

  • Type changed from Uncategorized to Bug

Changed 4 years ago by ShawnMilo

Patch with test. If environment variable DJANGO_SETTINGS_MODULE is set it will be used.

comment:5 Changed 4 years ago by ShawnMilo

  • Easy pickings set
  • Has patch set
  • Version changed from 1.2 to 1.3

Added patch against trunk with tests.

comment:6 follow-up: Changed 4 years ago by jacob

  • Triage Stage changed from Accepted to Ready for checkin

The patch is a little bit whitespace-happy, but close enough for a trivial cleanup. Marking RFC.

comment:7 in reply to: ↑ 6 Changed 4 years ago by ShawnMilo

Replying to jacob:

The patch is a little bit whitespace-happy, but close enough for a trivial cleanup. Marking RFC.

To be clear, is it the use of multi-line statements or too much whitespace around docstrings? Other than that, most of the whitespace is between parts of the tests for clarity. Is that counter to the community standard? The multi-lines were to avoid 80+ character lines.

Shawn

comment:8 follow-up: Changed 4 years ago by Alex

Do the tests always leave the environ in the same state it was before they began? It's not obvious to me that they do.

Changed 4 years ago by ShawnMilo

Restored os.environ variable to original value after tests. Removed whitespace.

comment:9 in reply to: ↑ 8 Changed 4 years ago by ShawnMilo

Replying to Alex:

Do the tests always leave the environ in the same state it was before they began? It's not obvious to me that they do.

Alex,

It did not. It does now.

Shawn

comment:10 Changed 4 years ago by ShawnMilo

  • Owner changed from nobody to ShawnMilo

comment:11 follow-up: Changed 4 years ago by SmileyChris

  • Patch needs improvement set
  • Triage Stage changed from Ready for checkin to Accepted

Clean up should happen in the tearDown method.

It would also look cleaner to just not touch os.environ['DJANGO_SETTINGS_MODULE'] if it's already set.

One other take-it-or-leave-it change (since it is more correct but result in a bigger code change) would be to move the settings_name generation code inside the only conditional that will use it.

comment:12 in reply to: ↑ 11 Changed 4 years ago by ShawnMilo

Replying to SmileyChris:

Clean up should happen in the tearDown method.

It would also look cleaner to just not touch os.environ['DJANGO_SETTINGS_MODULE'] if it's already set.

One other take-it-or-leave-it change (since it is more correct but result in a bigger code change) would be to move the settings_name generation code inside the only conditional that will use it.

Thanks. I'll put up a new patch later today.

Shawn

Changed 4 years ago by ShawnMilo

TestCase setUp and tearDown to ensure environment is not changed.

comment:13 Changed 4 years ago by ShawnMilo

I had to add back the global_settings import that was just removed yesterday because my test uses it.

The code patch is a simple one-line fix.

Brief description of the test, since it's more complicated:

    There are three conditions that may exist when django.core.management.setup_environ is called.

        1. The optional kwarg original_settings_path is passed in (takes precedence).
           action: use original_settings_path

        2. original_settings_path not passed, DJANGO_SETTINGS_MODULE in environment.
           action: use DJANGO_SETTINGS_MODULE (fixed by this patch)

        3. original_settings_path not passed, DJANGO_SETTINGS_MODULE not in environment.
           action: use default (was happening for #2 before this patch)

comment:14 Changed 4 years ago by ShawnMilo

  • Patch needs improvement unset

Patch improved. Please check. Thanks.

Changed 4 years ago by ShawnMilo

Update due to conflict with current trunk.

comment:15 Changed 4 years ago by d0ugal

  • Cc dougal85@… added

comment:16 Changed 4 years ago by ramiro

  • Resolution set to fixed
  • Status changed from new to closed

In [16222]:

Fixed #15064 -- Made manage.py honor the existence and value of DJANGO_SETTINGS_MODULE env var. Thanks olau for the report and Shawn Milochik for a patch.

comment:17 follow-up: Changed 4 years ago by lsaffre

  • Cc luc.saffre@… added

It took me a few days to understand that my problems came from this change. This change has also the effect that DJANGO_SETTINGS_MODULE will take precedence over any existing settings.py in the current directory. Until now I almost never set DJANGO_SETTINGS_MODULE when developing, I just go to "my" directory and called manage.py. Now I must take care of not having accidentally DJANGO_SETTINGS_MODULE set to some other project. Maybe a warning would be useful.

comment:18 in reply to: ↑ 17 Changed 4 years ago by ShawnMilo

Replying to lsaffre:

It took me a few days to understand that my problems came from this change. This change has also the effect that DJANGO_SETTINGS_MODULE will take precedence over any existing settings.py in the current directory. Until now I almost never set DJANGO_SETTINGS_MODULE when developing, I just go to "my" directory and called manage.py. Now I must take care of not having accidentally DJANGO_SETTINGS_MODULE set to some other project. Maybe a warning would be useful.

Where do you propose the warning should be? I think the docs are pretty clear that DJANGO_SETTINGS_MODULE should be authoritative. Also, when you run manage.py runserver the settings file being used is displayed.

https://docs.djangoproject.com/en/1.3/topics/settings/

comment:19 Changed 4 years ago by lsaffre

Okay, I hadn't read this page for quite some time now, and I agree that they are clear. So I was using an undocumented feature. I now simply modified my local manage.py files so I can continue the old way:

  import os
  os.environ['DJANGO_SETTINGS_MODULE'] = 'myproject.settings'
Note: See TracTickets for help on using tickets.
Back to Top