Opened 10 years ago

Closed 10 years ago

Last modified 10 years ago

#24150 closed Uncategorized (worksforme)

Settings changed at runtime not reflected in management commands

Reported by: Aryeh Hillman Owned by: nobody
Component: Core (Management commands) Version: 1.7
Severity: Normal Keywords:
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description (last modified by Aryeh Hillman)

Here is the help text for the collectstatic command:

$ ./manage.py collectstatic --help
Usage: ./manage.py collectstatic [options] 

Collect static files in a single location.

Options:
  -v VERBOSITY, --verbosity=VERBOSITY
                        Verbosity level; 0=minimal output, 1=normal output,
                        2=verbose output, 3=very verbose output
  --settings=SETTINGS   The Python path to a settings module, e.g.
                        "myproject.settings.main". If this isn't provided, the
                        DJANGO_SETTINGS_MODULE environment variable will be
                        used.
  --pythonpath=PYTHONPATH
                        A directory to add to the Python path, e.g.
                        "/home/djangoprojects/myproject".
  --traceback           Raise on exception
  --no-color            Don't colorize the command output.
  --noinput             Do NOT prompt the user for input of any kind.
  --no-post-process     Do NOT post process collected files.
  -i PATTERN, --ignore=PATTERN
                        Ignore files or directories matching this glob-style
                        pattern. Use multiple times to ignore more.
  -n, --dry-run         Do everything except modify the filesystem.
  -c, --clear           Clear the existing files using the storage before
                        trying to copy or link the original file.
  -l, --link            Create a symbolic link to each file instead of
                        copying.
  --no-default-ignore   Don't ignore the common private glob-style patterns
                        'CVS', '.*' and '*~'.
  --version             show program's version number and exit
  -h, --help            show this help message and exit

Clearly mentioned is a --settings flag, which takes a path to a django settings file. Supposing, however, that we want to run collectstatic from a script and want to dynamically modify our settings file. For example, something like

from django.conf import settings
from django.core.management import ManagementUtility

settings.USE_S3 = False
m = ManagementUtility(['', 'collectstatic'])
m.execute()

The command instead uses the settings specified at the shell variable DJANGO_SETTINGS_MODULE instead of the dynamic settings. Kind of pesky to have to create a separate settings file to get control of this sort of thing.

Could also be part of a larger problem -- that collectstatic cannot (easily) be used without the ManagementUtility command. Perhaps the core functionality of collectstatic should be factored out of its management command. For example:

from django.conf import settings
from django.core.management import ManagementUtility

m = ManagementUtility(['', 'collectstatic'])
collectstatic = m.fetch_command('collectstatic')

returns an error:

In [70]: collectstatic.collect()
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-70-d17fba11a87b> in <module>()
----> 1 collectstatic.collect()

/.../python2.7/site-packages/django/contrib/staticfiles/management/commands/collectstatic.pyc in collect(self)
     83         Split off from handle_noargs() to facilitate testing.
     84         """
---> 85         if self.symlink and not self.local:
     86             raise CommandError("Can't symlink to a remote destination.")
     87 

AttributeError: 'Command' object has no attribute 'symlink'

Change History (8)

comment:1 by Aryeh Hillman, 10 years ago

Description: modified (diff)

comment:2 by Aryeh Hillman, 10 years ago

Description: modified (diff)

comment:3 by Aryeh Hillman, 10 years ago

Description: modified (diff)

comment:4 by Aryeh Hillman, 10 years ago

Summary: collectstatic -- using django.conf.settingscollectstatic -- Dynamic Usage

comment:5 by Tim Graham, 10 years ago

call_command() is the public API for calling management commands from your own code. Is there a reason you aren't using that?

comment:6 by Aryeh Hillman, 10 years ago

I was not familiar with that public API.

This API also does not use the current django.conf.settings configuration when calling the collectstatic method.

Version 1, edited 10 years ago by Aryeh Hillman (previous) (next) (diff)

comment:7 by Tim Graham, 10 years ago

Resolution: worksforme
Status: newclosed

I couldn't reproduce the problem you described with this test script:

import django
from django.conf import settings
from django.core import management

django.setup()
settings.FOO = 'baz'
management.call_command('test')

The test management command simply printed the value of settings.FOO. It always output 'baz' regardless of the value of DJANGO_SETTINGS_MODULE. Please reopen with a minimal test example if I've misinterpreted.

comment:8 by Tim Graham, 10 years ago

Component: UncategorizedCore (Management commands)
Summary: collectstatic -- Dynamic UsageSettings changed at runtime not reflected in management commands
Note: See TracTickets for help on using tickets.
Back to Top