Django: how to pass individual setting to manage.py
Asked Answered
D

4

14

I'm looking for a way to override/define some individual django setting from command line without additional settings files.

What I need right now is to set the DEBUG setting or logging level each time when I run my management command. But it would be nice to be able to set anything.

Debrahdebrecen answered 19/12, 2011 at 15:18 Comment(2)
Do you want to set DEBUG every time python manage.py runserver called or you have your custom command python manage.py foo and you want to set DEBUG inside it?Anestassia
I want to set any setting for any command. Like this: ./manage.py --set="DEBUG=True" runserver. Maybe the most easy way is to exec a command line parameter value right in settings.py. But I was hoping there is a way to not modify the source code at all.Debrahdebrecen
D
9

Here is my solution. Add the code below to the bottom of your settings file.

# Process --set command line option
import sys
# This module can be imported several times,
# check if the option has been retrieved already.
if not hasattr(sys, 'arg_set'):
    # Search for the option.
    args = filter(lambda arg: arg[:6] == '--set=', sys.argv[1:])
    if len(args) > 0:
        expr = args[0][6:]
        # Remove the option from argument list, because the actual command
        # knows nothing about it.
        sys.argv.remove(args[0])
    else:
        # --set is not provided.
        expr = ''
    # Save option value for future use.
    sys.arg_set = expr
# Execute the option value.
exec sys.arg_set

Then just pass any code to any management command:

./manage.py runserver --set="DEBUG=True ; TEMPLATE_DEBUG=True"
Debrahdebrecen answered 20/12, 2011 at 17:10 Comment(5)
I think this is only possible way since Django doesn't offer any hook for preprocessing command-line arguments. I wonder why you need it?Anestassia
Hi Kirill. Thank you for your comment. I was not sure about this. Also what I don't like about my solution is the way I store the option value. But I have not found a better way to save the option between imports.Debrahdebrecen
Why I need this is just because this is fast and easy way to tweak any setting during the development process. I can play with settings without modifying the settings file. And I can be sure I will not forget to change things back (this makes problem sometimes). Also it may be usefull for production. It is possible to tweak settings for individual task on cron/celery/etc. Right now what I need is to run some management command for me with the debug output, and for my partner with usefull output only. I don't feel like I should change the command for such needs.Debrahdebrecen
You could use a local settings file. You most probably already have one, since you have different database login credentials in development as in production. This local settings file wouldn't be overriden by checkout and you don't risk forgetting settings in there.Manchester
@AndrasGyomrey The question is about the command line arguments.Debrahdebrecen
H
2

You can add custom option (ex. log level) to your command. Docs

Example:

from optparse import make_option

class Command(BaseCommand):
    option_list = BaseCommand.option_list + (
        make_option('--delete',
            action='store_true',
            dest='delete',
            default=False,
            help='Delete poll instead of closing it'),
        )
    # ...
Haberdashery answered 19/12, 2011 at 15:30 Comment(1)
Thank you Denis. Sure I can. But I don't want to add this option to each command in each project. I'm looking for some more universal method.Debrahdebrecen
L
2

In settings.py you can check for command line arguments, like this:

import sys

# for testing
if "--enable-wiki" in sys.argv:
    ENABLE_WIKI = True
    sys.argv.remove("--enable-wiki")

Usage:

./manage.py test --enable-wiki MyApp.tests
Luo answered 21/6, 2020 at 15:18 Comment(0)
A
-1

You can make your settings.py more aware of it's current environment:

DEBUG = socket.gethostname().find( 'example.com' ) == -1

Here's an option for different databases when testing:

'ENGINE': 'sqlite3' if 'test_coverage' in sys.argv else 'django.db.backends.postgresql_psycopg2',
Astronomer answered 19/12, 2011 at 17:24 Comment(3)
Thanks. This method requires modifications for any constant that I need to override. Not exactly what I want.Debrahdebrecen
There is no such thing as a constant in Python, any variable can be re-bound. Good luck.Astronomer
This is not important. Let's say setting, not constant :)Debrahdebrecen

© 2022 - 2024 — McMap. All rights reserved.