Giter Site home page Giter Site logo

jazzband / django-configurations Goto Github PK

View Code? Open in Web Editor NEW
1.1K 1.1K 143.0 549 KB

A helper for organizing Django project settings by relying on well established programming patterns.

Home Page: https://django-configurations.readthedocs.io/

License: BSD 3-Clause "New" or "Revised" License

Python 100.00%

django-configurations's People

Contributors

amureki avatar bittner avatar blaze33 avatar blueyed avatar brianhelba avatar camilonova avatar codingjoe avatar drewbrew avatar ftsell avatar gump avatar hiisi13 avatar jannisleidel avatar jezdez avatar johnfraney avatar joke2k avatar jpadilla avatar jrdietrick avatar mauricioabreu avatar mfogel avatar michael-k avatar mikewooster avatar morenoh149 avatar mvantellingen avatar nagyv avatar paltman avatar pauloxnet avatar slafs avatar stefanw avatar ticosax avatar timgates42 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

django-configurations's Issues

Optionally load from os.environ

In certain cases, it would be nice to be able to override settings defined in the py files with the values of matching os.environ entries. So maybe a part of the initialization routine that sets the attributes appropriately before returning the final resulting settings.

Patching runserver stdout breaks cmd line settings option

When patching the runserver command's inner_run, all commands get imported with get_commands which in turn triggers the import of the settings module with the default os env settings name as specified in manage.py. All this happens before the command line arguments for --settings are even evaluated, because configuration's install happens during the import of execute_from_command_line.

The following stack trace exemplifies this by giving a custom settings module as a cmd line option:

$ ./manage.py runserver --settings=example.custom_settings --configuration=Custom
Traceback (most recent call last):
  File "./manage.py", line 7, in <module>
    from configurations.management import execute_from_command_line
  File "...django-configurations/configurations/management.py", line 3, in <module>
    importer.install(check_options=True)
  File "/Users/sw/Sites/django-configurations/configurations/importer.py", line 77, in install
    commands = management.get_commands()
  File "...lib/python2.7/site-packages/django/core/management/__init__.py", line 107, in get_commands
    apps = settings.INSTALLED_APPS
  File "...lib/python2.7/site-packages/django/conf/__init__.py", line 54, in __getattr__
    self._setup(name)
  File "...lib/python2.7/site-packages/django/conf/__init__.py", line 49, in _setup
    self._wrapped = Settings(settings_module)
  File "...lib/python2.7/site-packages/django/conf/__init__.py", line 128, in __init__
    mod = importlib.import_module(self.SETTINGS_MODULE)
  File "...lib/python2.7/site-packages/django/utils/importlib.py", line 35, in import_module
    __import__(name)
  File "...django-configurations/configurations/importer.py", line 156, in load_module
    mod.__package__))
  File "...django-configurations/configurations/importer.py", line 152, in load_module
    cls = getattr(mod, self.name)
AttributeError: Couldn't find configuration 'Custom' in module 'example':  'module' object has no attribute 'Custom'

Removing the patching of runserver's inner_run in the install function fixes this.

Instead of patching runserver, how about checking if manage.py runserver is being called and then just writing the configuration to stdout. This will not fit in nicely with runserver's output, but at least print the configuration.

Issue with six version > 0.3

It is the same issue as #30

But we are using Django 1.3.7, django-configurations 0.3, python 2.6, when six gets upgraded to version 1.40 and/or 1.41 our travis tests break with the same error.
We can't upgrade to django-configurations 0.4

Is there any possibility that the version of six will be pinned in django-configurations 0.3?

Unable to run project under Gunicorn

Hi,

I've been racking my brain all day with this issue and I've been unable to get it working.

We're in the process of switching over to using django-configurations for our project and for some reason it appears gunicorn isn't able to pick up the settings. Running the project with python manage.py runserver works perfectly.

My code is as follows:

gizmag/settings.py

# I can provide my entire settings file if required
from configurations import Configuration

class Base(Configuration):
    ...

class Dev(Base):
    DEBUG = True
    ...

class Test(Dev):
    ...

class Prod(Base):
    pass

gizmag/wsgi.py

import os

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'gizmag.settings')
os.environ.setdefault('DJANGO_CONFIGURATION', 'Prod')

from configurations.wsgi import get_wsgi_application

application = get_wsgi_application()

manage.py

#!/usr/bin/env python

import os
import sys

if 'test' in sys.argv:
    default_config = 'Test'
else:
    default_config = 'Dev'

if __name__ == "__main__":
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'gizmag.settings')
    os.environ.setdefault('DJANGO_CONFIGURATION', default_config)

    from configurations.management import execute_from_command_line

    execute_from_command_line(sys.argv)

And the error I receive if I don't explicitly export my settings module / configuration

(gizmag)jacob  [master] ~/p/gizmag $ gunicorn gizmag.wsgi:application
2013-09-24 16:38:23 [73705] [INFO] Starting gunicorn 18.0
2013-09-24 16:38:23 [73705] [INFO] Listening at: http://127.0.0.1:8000 (73705)
2013-09-24 16:38:23 [73705] [INFO] Using worker: sync
2013-09-24 16:38:23 [73708] [INFO] Booting worker with pid: 73708
2013-09-24 16:38:23 [73708] [ERROR] Exception in worker process:
Traceback (most recent call last):
  File "/Users/jacob/.virtualenvs/gizmag/lib/python2.7/site-packages/gunicorn/arbiter.py", line 495, in spawn_worker
    worker.init_process()
  File "/Users/jacob/.virtualenvs/gizmag/lib/python2.7/site-packages/gunicorn/workers/base.py", line 106, in init_process
    self.wsgi = self.app.wsgi()
  File "/Users/jacob/.virtualenvs/gizmag/lib/python2.7/site-packages/gunicorn/app/base.py", line 114, in wsgi
    self.callable = self.load()
  File "/Users/jacob/.virtualenvs/gizmag/lib/python2.7/site-packages/gunicorn/app/wsgiapp.py", line 62, in load
    return self.load_wsgiapp()
  File "/Users/jacob/.virtualenvs/gizmag/lib/python2.7/site-packages/gunicorn/app/wsgiapp.py", line 49, in load_wsgiapp
    return util.import_app(self.app_uri)
  File "/Users/jacob/.virtualenvs/gizmag/lib/python2.7/site-packages/gunicorn/util.py", line 354, in import_app
    __import__(module)
  File "/Users/jacob/p/gizmag/gizmag/__init__.py", line 16, in <module>
    post_migrate.connect(update_permissions_after_migration)
  File "/Users/jacob/.virtualenvs/gizmag/lib/python2.7/site-packages/django/dispatch/dispatcher.py", line 75, in connect
    if settings.DEBUG:
  File "/Users/jacob/.virtualenvs/gizmag/lib/python2.7/site-packages/django/conf/__init__.py", line 53, in __getattr__
    self._setup(name)
  File "/Users/jacob/.virtualenvs/gizmag/lib/python2.7/site-packages/django/conf/__init__.py", line 46, in _setup
    % (desc, ENVIRONMENT_VARIABLE))
ImproperlyConfigured: Requested setting DEBUG, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure() before accessing settings.
Traceback (most recent call last):
  File "/Users/jacob/.virtualenvs/gizmag/lib/python2.7/site-packages/gunicorn/arbiter.py", line 495, in spawn_worker
    worker.init_process()
  File "/Users/jacob/.virtualenvs/gizmag/lib/python2.7/site-packages/gunicorn/workers/base.py", line 106, in init_process
    self.wsgi = self.app.wsgi()
  File "/Users/jacob/.virtualenvs/gizmag/lib/python2.7/site-packages/gunicorn/app/base.py", line 114, in wsgi
    self.callable = self.load()
  File "/Users/jacob/.virtualenvs/gizmag/lib/python2.7/site-packages/gunicorn/app/wsgiapp.py", line 62, in load
    return self.load_wsgiapp()
  File "/Users/jacob/.virtualenvs/gizmag/lib/python2.7/site-packages/gunicorn/app/wsgiapp.py", line 49, in load_wsgiapp
    return util.import_app(self.app_uri)
  File "/Users/jacob/.virtualenvs/gizmag/lib/python2.7/site-packages/gunicorn/util.py", line 354, in import_app
    __import__(module)
  File "/Users/jacob/p/gizmag/gizmag/__init__.py", line 16, in <module>
    post_migrate.connect(update_permissions_after_migration)
  File "/Users/jacob/.virtualenvs/gizmag/lib/python2.7/site-packages/django/dispatch/dispatcher.py", line 75, in connect
    if settings.DEBUG:
  File "/Users/jacob/.virtualenvs/gizmag/lib/python2.7/site-packages/django/conf/__init__.py", line 53, in __getattr__
    self._setup(name)
  File "/Users/jacob/.virtualenvs/gizmag/lib/python2.7/site-packages/django/conf/__init__.py", line 46, in _setup
    % (desc, ENVIRONMENT_VARIABLE))
ImproperlyConfigured: Requested setting DEBUG, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure() before accessing settings.
2013-09-24 16:38:23 [73708] [INFO] Worker exiting (pid: 73708)
2013-09-24 16:38:23 [73705] [INFO] Shutting down: Master
2013-09-24 16:38:23 [73705] [INFO] Reason: Worker failed to boot.

And when I do explicitly define them (I also don't know why my default environment variables aren't working)

(gizmag)jacob  [master] ~/p/gizmag $ export DJANGO_CONFIGURATION=Prod
(gizmag)jacob  [master] ~/p/gizmag $ export DJANGO_SETTINGS_MODULE=gizmag.settings
(gizmag)jacob  [master] ~/p/gizmag $ gunicorn gizmag.wsgi:application
2013-09-24 16:39:09 [73732] [INFO] Starting gunicorn 18.0
2013-09-24 16:39:09 [73732] [INFO] Listening at: http://127.0.0.1:8000 (73732)
2013-09-24 16:39:09 [73732] [INFO] Using worker: sync
2013-09-24 16:39:09 [73735] [INFO] Booting worker with pid: 73735
2013-09-24 16:39:09 [73735] [ERROR] Exception in worker process:
Traceback (most recent call last):
  File "/Users/jacob/.virtualenvs/gizmag/lib/python2.7/site-packages/gunicorn/arbiter.py", line 495, in spawn_worker
    worker.init_process()
  File "/Users/jacob/.virtualenvs/gizmag/lib/python2.7/site-packages/gunicorn/workers/base.py", line 106, in init_process
    self.wsgi = self.app.wsgi()
  File "/Users/jacob/.virtualenvs/gizmag/lib/python2.7/site-packages/gunicorn/app/base.py", line 114, in wsgi
    self.callable = self.load()
  File "/Users/jacob/.virtualenvs/gizmag/lib/python2.7/site-packages/gunicorn/app/wsgiapp.py", line 62, in load
    return self.load_wsgiapp()
  File "/Users/jacob/.virtualenvs/gizmag/lib/python2.7/site-packages/gunicorn/app/wsgiapp.py", line 49, in load_wsgiapp
    return util.import_app(self.app_uri)
  File "/Users/jacob/.virtualenvs/gizmag/lib/python2.7/site-packages/gunicorn/util.py", line 354, in import_app
    __import__(module)
  File "/Users/jacob/p/gizmag/gizmag/__init__.py", line 16, in <module>
    post_migrate.connect(update_permissions_after_migration)
  File "/Users/jacob/.virtualenvs/gizmag/lib/python2.7/site-packages/django/dispatch/dispatcher.py", line 75, in connect
    if settings.DEBUG:
  File "/Users/jacob/.virtualenvs/gizmag/lib/python2.7/site-packages/django/conf/__init__.py", line 53, in __getattr__
    self._setup(name)
  File "/Users/jacob/.virtualenvs/gizmag/lib/python2.7/site-packages/django/conf/__init__.py", line 48, in _setup
    self._wrapped = Settings(settings_module)
  File "/Users/jacob/.virtualenvs/gizmag/lib/python2.7/site-packages/django/conf/__init__.py", line 132, in __init__
    mod = importlib.import_module(self.SETTINGS_MODULE)
  File "/Users/jacob/.virtualenvs/gizmag/lib/python2.7/site-packages/django/utils/importlib.py", line 35, in import_module
    __import__(name)
  File "/Users/jacob/p/gizmag/gizmag/settings.py", line 425, in <module>
    class Dev(Base):
  File "/Users/jacob/.virtualenvs/gizmag/lib/python2.7/site-packages/configurations/base.py", line 30, in __new__
    raise ImproperlyConfigured(install_failure)
ImproperlyConfigured: django-configurations settings importer wasn't correctly installed. Please use one of the starter functions to install it as mentioned in the docs: http://django-configurations.readthedocs.org/
Traceback (most recent call last):
  File "/Users/jacob/.virtualenvs/gizmag/lib/python2.7/site-packages/gunicorn/arbiter.py", line 495, in spawn_worker
    worker.init_process()
  File "/Users/jacob/.virtualenvs/gizmag/lib/python2.7/site-packages/gunicorn/workers/base.py", line 106, in init_process
    self.wsgi = self.app.wsgi()
  File "/Users/jacob/.virtualenvs/gizmag/lib/python2.7/site-packages/gunicorn/app/base.py", line 114, in wsgi
    self.callable = self.load()
  File "/Users/jacob/.virtualenvs/gizmag/lib/python2.7/site-packages/gunicorn/app/wsgiapp.py", line 62, in load
    return self.load_wsgiapp()
  File "/Users/jacob/.virtualenvs/gizmag/lib/python2.7/site-packages/gunicorn/app/wsgiapp.py", line 49, in load_wsgiapp
    return util.import_app(self.app_uri)
  File "/Users/jacob/.virtualenvs/gizmag/lib/python2.7/site-packages/gunicorn/util.py", line 354, in import_app
    __import__(module)
  File "/Users/jacob/p/gizmag/gizmag/__init__.py", line 16, in <module>
    post_migrate.connect(update_permissions_after_migration)
  File "/Users/jacob/.virtualenvs/gizmag/lib/python2.7/site-packages/django/dispatch/dispatcher.py", line 75, in connect
    if settings.DEBUG:
  File "/Users/jacob/.virtualenvs/gizmag/lib/python2.7/site-packages/django/conf/__init__.py", line 53, in __getattr__
    self._setup(name)
  File "/Users/jacob/.virtualenvs/gizmag/lib/python2.7/site-packages/django/conf/__init__.py", line 48, in _setup
    self._wrapped = Settings(settings_module)
  File "/Users/jacob/.virtualenvs/gizmag/lib/python2.7/site-packages/django/conf/__init__.py", line 132, in __init__
    mod = importlib.import_module(self.SETTINGS_MODULE)
  File "/Users/jacob/.virtualenvs/gizmag/lib/python2.7/site-packages/django/utils/importlib.py", line 35, in import_module
    __import__(name)
  File "/Users/jacob/p/gizmag/gizmag/settings.py", line 425, in <module>
    class Dev(Base):
  File "/Users/jacob/.virtualenvs/gizmag/lib/python2.7/site-packages/configurations/base.py", line 30, in __new__
    raise ImproperlyConfigured(install_failure)
ImproperlyConfigured: django-configurations settings importer wasn't correctly installed. Please use one of the starter functions to install it as mentioned in the docs: http://django-configurations.readthedocs.org/
2013-09-24 16:39:09 [73735] [INFO] Worker exiting (pid: 73735)
2013-09-24 16:39:09 [73732] [INFO] Shutting down: Master
2013-09-24 16:39:09 [73732] [INFO] Reason: Worker failed to boot.

Thanks in advance for any help! and I'm so sorry if it turns out I've skipped over part of the documentation.

Aggregate fields

Hello, I'm not sure whether this is a feature request, a bug report, or a question.

I want to have a bunch of "settings" classes, each for each possible feature in my site (It's sort of a template project), so I can turn features on and off by adding the specific mixin to the inherintance tree, or maybe a class list I can iterate if inheritance is not a good idea.

So I'd want to do something like

class BaseSettings(Settings):
    INSTALLED_APPS = [
        'django.contrib.auth',
        'django.contrib.sites',
        ]

class CmsSettingsMixin(object):
    INSTALLED_APPS = [
        'cms',
        'menus',
        'mptt',
        ]

class MySiteSettings(BaseSettings, CmsSettingsMixin, FooMixin):
    PROJECT_NAME = 'FooBar'
    def INSTALLED_APPS(self):
        return somehow_aggregate_all()

I'm absolutely flexible about the strategy to achieve this, but is it at all possible without going to the extremes of defining some kind of metaclass or mixin base and ending up in diamond inheritance?

Possible issue with fix for #9...

Hi,

First of all, thank you very much for adding --configuration

I gave it a test and it doesn't seem to work.. but I'm probably doing something wrong:

./manage.py shell_plus
In [1]: from django.conf import settings
In [2]: settings.CONFIGURATION
Out [2]: 'astrobiology.settings.Alpha'

Ok. This matches what's in my manage.py....

./manage.py shell_plus --configuration=Beta
In [1]: from django.conf import settings
In [2]: settings.CONFIGURATION
Out [2]: 'astrobiology.settings.Alpha'

Should say 'astrobiology.settings.Beta'...

./manage.py shell_plus --configuration=ThisDoesNotExist
In [1]: from django.conf import settings
In [2]: settings.CONFIGURATION
Out [2]: 'astrobiology.settings.Alpha'

Shouldn't I get an error if I supply a bad configuration?

./manage.py shell_plus --settings=astrobiology.settings --configuration=Beta
In [1]: from django.conf import settings
In [2]: settings.CONFIGURATION
Out [2]: 'astrobiology.settings.Alpha'

Just in case... but this didn't work either.

Conditional use of values in Configuration class

Is it possible to access a value in the Configuration class itself, like with:

class Common(Configuration):
    if get_env_var('SENTRY_DSN', False):
        # Setup for Sentry


class Common(Configuration):
    SENTRY_DSN = values.Value(environ_prefix="")
    if SENTRY_DSN:
        # Setup for Sentry

This is not possible, because the values get setup later, is it?

It would be nice if the documentation would mention / clarify this (preferably with an example using os.environ in a conditional).

django.db.utils.OperationalError: unable to open database file

I create django project using the command given in the docs:

django-admin.py startproject mysite -v2 --template https://github.com/jezdez/django-configurations/archive/templates/1.6.x.zip

I do:

manage.py syncdb

This happens:

File "/home/mario/Envs/danny/local/lib/python2.7/site-packages/django/db/backends/sqlite3/base.py", line 346, in get_new_connection
conn = Database.connect(**conn_params)
django.db.utils.OperationalError: unable to open database file

I think the error is due to this part inside templates/1.6.x/project_name/settings.py:

DATABASES = values.DatabaseURLValue('sqlite://%s' % os.path.join(BASE_DIR, 'db.sqlite3'), environ=True)

On my ubuntu BASE_DIR points to /home/mario.., so the db url takes value of:

sqlite:///home/mario..

in this case django is trying to open home/mario.. (notice no starting slash). Since it cannot open the file, it throws db error.

To solve it, I use three slashes instead of two (sqlite:///%s), which seems to work fine in ubuntu and windows. But I'm not sure if that's the best solution.

Cannot determine PostGIS version for database

I'm not sure if this is a bug, please close it if it ain't. I put it here to serve as documentation, in case anyone has the same problem.

Currently using Postgres 9.3 and Postgis 2.1. I had to put the version explicitly in my settings file:

   # Actual value defined in environment variable
    DATABASES = values.DatabaseURLValue('postgis://localhost/appdb')
    POSTGIS_VERSION = (2, 1)

Otherwise, I would get this error:

django.core.exceptions.ImproperlyConfigured: Cannot determine PostGIS version for database "appdb". GeoDjango requires at least PostGIS version 1.3. Was the database created from a spatial database template?

Full traceback:

Traceback (most recent call last):
  File "manage.py", line 11, in <module>
    execute_from_command_line(sys.argv)
  File "/home/user/app/venv/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 399, in execute_from_command_line
    utility.execute()
  File "/home/user/app/venv/local/lib/python2.7/site-packages/django/core/management/__init__.py", line 392, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/home/user/app/venv/local/lib/python2.7/site-packages/django/core/management/base.py", line 242, in run_from_argv
    self.execute(*args, **options.__dict__)
  File "/home/user/app/venv/local/lib/python2.7/site-packages/django/core/management/base.py", line 280, in execute
    translation.activate('en-us')
  File "/home/user/app/venv/local/lib/python2.7/site-packages/django/utils/translation/__init__.py", line 130, in activate
    return _trans.activate(language)
  File "/home/user/app/venv/local/lib/python2.7/site-packages/django/utils/translation/trans_real.py", line 188, in activate
    _active.value = translation(language)
  File "/home/user/app/venv/local/lib/python2.7/site-packages/django/utils/translation/trans_real.py", line 177, in translation
    default_translation = _fetch(settings.LANGUAGE_CODE)
  File "/home/user/app/venv/local/lib/python2.7/site-packages/django/utils/translation/trans_real.py", line 159, in _fetch
    app = import_module(appname)
  File "/home/user/app/venv/local/lib/python2.7/site-packages/django/utils/importlib.py", line 40, in import_module
    __import__(name)
  File "/home/user/app/venv/local/lib/python2.7/site-packages/django/contrib/admin/__init__.py", line 6, in <module>
    from django.contrib.admin.sites import AdminSite, site
  File "/home/user/app/venv/local/lib/python2.7/site-packages/django/contrib/admin/sites.py", line 4, in <module>
    from django.contrib.admin.forms import AdminAuthenticationForm
  File "/home/user/app/venv/local/lib/python2.7/site-packages/django/contrib/admin/forms.py", line 6, in <module>
    from django.contrib.auth.forms import AuthenticationForm
  File "/home/user/app/venv/local/lib/python2.7/site-packages/django/contrib/auth/forms.py", line 17, in <module>
    from django.contrib.auth.models import User
  File "/home/user/app/venv/local/lib/python2.7/site-packages/django/contrib/auth/models.py", line 48, in <module>
    class Permission(models.Model):
  File "/home/user/app/venv/local/lib/python2.7/site-packages/django/db/models/base.py", line 96, in __new__
    new_class.add_to_class('_meta', Options(meta, **kwargs))
  File "/home/user/app/venv/local/lib/python2.7/site-packages/django/db/models/base.py", line 264, in add_to_class
    value.contribute_to_class(cls, name)
  File "/home/user/app/venv/local/lib/python2.7/site-packages/django/db/models/options.py", line 124, in contribute_to_class
    self.db_table = truncate_name(self.db_table, connection.ops.max_name_length())
  File "/home/user/app/venv/local/lib/python2.7/site-packages/django/db/__init__.py", line 34, in __getattr__
    return getattr(connections[DEFAULT_DB_ALIAS], item)
  File "/home/user/app/venv/local/lib/python2.7/site-packages/django/db/utils.py", line 199, in __getitem__
    conn = backend.DatabaseWrapper(db, alias)
  File "/home/user/app/venv/local/lib/python2.7/site-packages/django/contrib/gis/db/backends/postgis/base.py", line 11, in __init__
    self.ops = PostGISOperations(self)
  File "/home/user/app/venv/local/lib/python2.7/site-packages/django/contrib/gis/db/backends/postgis/operations.py", line 158, in __init__
    if self.spatial_version < (1, 3, 4):
  File "/home/user/app/venv/local/lib/python2.7/site-packages/django/utils/functional.py", line 49, in __get__
    res = instance.__dict__[self.func.__name__] = self.func(instance)
  File "/home/user/app/venv/local/lib/python2.7/site-packages/django/contrib/gis/db/backends/postgis/operations.py", line 258, in spatial_version
    'template?' % self.connection.settings_dict['NAME']
django.core.exceptions.ImproperlyConfigured: Cannot determine PostGIS version for database "appdb". GeoDjango requires at least PostGIS version 1.3. Was the database created from a spatial database template?

Proposal for improved Mixin functionality

I don't know if you have already considered something like this, but from an organizational point of view, I think that it would be nice if we could use use separate classes for the configuration of each django application. For example:

class DjangoDebugToolbar(object):
    pass

class DjangoAvatar(object):
    pass

class MyAppConfig(Configuration, DjangoAvatar):
    pass

class MyDevConfig(MyAppConfig, DjangoDebugToolbar):
    pass

The problem with this approach, is that the current implementation of mixins does not work with settings like the INSTALLED_APPS which are tuples (i.e. the settings get overwritten).

What I propose is to make changes in the ConfigurationBase metaclass in order to allow tuples to be concatenated instead of overwritten. I.e to allow something like this:

from configurations import Configuration

class A(object):
    A = ("A.A1", "A.A2")
    B = "A.B"

class B(object):
    A = ("B.A1", "B.A2")
    B = "B.B"
    C = "B.C"
    D = "B.D"

class Foo(Configuration, A, B):
    A = ("Foo.A1", "Foo.A2",)
    C = "Foo.C"
    E  = "Foo.E"

assert Foo.A == ("Foo.A1", "Foo.A2", "A.A1", "A.A2", "B.A1", "B.A2")
assert Foo.B == "A.B"
assert Foo.C == "Foo.C"
assert Foo.D == "B.D"
assert Foo.E == "Foo.E"

As a (simple) proof of concept, I came up with the following. It is not extensively tested but it seems to work; at least the tests continue to work :)

-        if parents:
-            for base in bases[::-1]:
-                settings_vars.update(uppercase_attributes(base))
+        if parents:
+            for base in bases:
+                for key, value in uppercase_attributes(base).items():
+                    if key in attrs:
+                        if isinstance(value, tuple):
+                            attrs[key] += value
+                    else:
+                        attrs[key] = value

Would you be interested in something like that?

Values inside of a dictionary seems not to work

at best a paste my example:

    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'NAME': values.Value(environ_name='DB_NAME', environ_prefix='RDS'),
            'USER': values.Value(environ_name='USERNAME', environ_prefix='RDS'),
            'PASSWORD': values.SecretValue(environ_name='PASSWORD', environ_prefix='RDS'),
            'HOST': values.Value(environ_name='HOSTNAME', environ_prefix='RDS'),
            'PORT': values.Value(environ_name='PORT', environ_prefix='RDS'),
        }
    }

in that case the mysql client will complain the flollowing:

[...]
  File "/home/sassman/.virtualenvs/shelter/lib/python2.7/site-packages/django/db/backends/mysql/client.py", line 27, in runshell
    if '/' in host:
TypeError: argument of type 'Value' is not iterable

my first idea was a __str__() function on Value class, but calling setup_value there once again seems not to be the right solution.
Maybe it is worth it to cache the final fetched value inside of Value instance, and on setup of the Configuration class only pass the config name into the value. However it seems that it will end up in a more LOC changes.

What do you think?

Ideal configuration setup for multiple sites, environments, and local settings?

Hi there,

This isn't an issue per-say, but I can't quite decide how I want to structure my settings in a way that allows me to use django-configurations.

For context, my project runs multiple sites (via the Django Sites framework), it has multiple environments (Production, Dev, Testing), and also of course, a local settings.

Now, at this time I've structured my settings in the following manner to allow me to achieve most of this, without issue.

DJANGO_SETTINGS_MODULE is set to a file correlating to the site I want to run. e.g., settings.sites.mysite. mysite.py may look something like this:

from myproject.settings import Development, Production

class SiteSettings(object):
     SITE_ID = 1

     @property
     def INSTALLED_APPS(self):
        return ('more','apps') + super(SiteSettings, self).INSTALLED_APPS
     # .... snipped

class Development(SiteSettings, Development):
    pass

class Production(SiteSettings, Production):
    pass

Then, I set DJANGO_CONFIGURATION to either Production or Development. With this approach I was able to very easily separate site settings, a base settings, and various environments without doing a lot of the same thing over and over.

However, I am at a loss as to how I could handle local settings. In this scheme, I would have to set DJANGO_SETTINGS_MODULE to a localsettings module, but then I would have to do some fancy import magic within it to get the environments I need? Not quite sure..

Any help would be much appreciated. Thank you for the great project!

Project will fail with SecretValue() settings not having an environment variable

In a Django project powered by django-configurations 0.4 and config values based on environment variables, the project will fail if you define any setting variable based on SecretValue() not having a value for its environment variable.

Example::

FACEBOOK_API_SECRET = values.SecretValue(environ_name='FACEBOOK_API_SECRET')

Now if the environment variable FACEBOOK_API_SECRET does not contain a value, the project will complain about SECRET_KEY not being set::

$ python manage.py validate --traceback
Traceback (most recent call last):
  File "/path/to/virtualenv/lib/python2.7/site-packages/django/core/management/base.py", line 222, in run_from_argv
    self.execute(*args, **options.__dict__)
  File "/path/to/virtualenv/lib/python2.7/site-packages/django/core/management/base.py", line 249, in execute
    saved_lang = translation.get_language()
  File "/path/to/virtualenv/lib/python2.7/site-packages/django/utils/translation/__init__.py", line 114, in get_language
    return _trans.get_language()
  File "/path/to/virtualenv/lib/python2.7/site-packages/django/utils/translation/__init__.py", line 47, in __getattr__
    if settings.USE_I18N:
  File "/path/to/virtualenv/lib/python2.7/site-packages/django/conf/__init__.py", line 53, in __getattr__
    self._setup(name)
  File "/path/to/virtualenv/lib/python2.7/site-packages/django/conf/__init__.py", line 48, in _setup
    self._wrapped = Settings(settings_module)
  File "/path/to/virtualenv/lib/python2.7/site-packages/django/conf/__init__.py", line 152, in __init__
    raise ImproperlyConfigured("The SECRET_KEY setting must not be empty.")
ImproperlyConfigured: The SECRET_KEY setting must not be empty.

Apache, mod_wsgi, Enironment Variables

I found the following comment "Environment variables for configuration (This won't work with Apache/mod_wsgi)." at pydanny's https://github.com/pydanny/cookiecutter-django.

Since this surprised me, I opened a ticket: cookiecutter/cookiecutter-django#74. Pydanny replied correctly, that any solution for that is outside of the scope of the django project template.

Now I fully understand that the root cause for this issue is NOT related to django-configurations. But as a result, the purpose of django-cofigurations (especially in combination with envdir) is somehow corrupted with mod_wsgi and Apache. So I am wondering, if we can come up with some kind of workaround for the problem.

The root cause is desciribed here: http://httpd.apache.org/docs/2.2/env.html. Grahame Dumpleton has commented on the issue at SO (last anwer): http://stackoverflow.com/questions/19754834/access-apache-setenv-variable-from-django-wsgi-py-file

One workaround is described the the same SO question or also in this post: http://drumcoder.co.uk/blog/2010/nov/12/apache-environment-variables-and-mod_wsgi/. Though Graham had a very clear negative opinion on that. Still would that be a valid option?

Are there any other options? If not so, I would at leat propose to add a section to the cookbook in the docs about mod_wsgi/Apache.

Errors when calling with additional manage.py command, Django 1.4

Hi,
I have seen both #21 and #24, but i'm using Django 1.4.3 in my project and for now i can't update it to a newer version and i want to use you package.

fails:

     $ ./manage.py runserver --insecure

works ok:

     $ ./manage.py runserver

The manage.py is the same as in the docs:

    def main():
        os.environ.setdefault("DJANGO_SETTINGS_MODULE", "{myproject}.settings")
        os.environ.setdefault('DJANGO_CONFIGURATION', 'Development')

        from configurations.management import execute_from_command_line
        execute_from_command_line(sys.argv)

    if __name__ == "__main__":
        main()

Any suggestions how to solve this?

Thanks :)

unable to get STATIC_URL, while I can get it via {% static 'myfile.js' %}

settings.py

from configurations import Configuration, values

Class Production(Configuration):
    # ....
    AWS_STORAGE_BUCKET_NAME = values.SecretValue()
    STATIC_URL = 'https://s3.amazonaws.com/%s/' % AWS_STORAGE_BUCKET_NAME
    # ....

Then in templates:

<link rel="stylesheet" href="{{ STATIC_URL }}/main.css">
<!-- output: https://s3.amazonaws.com/&lt;Value default: None&gt;//main.css"> -->
<link rel="stylesheet" href="{% static 'main.css' %}">
<!-- output: https://s3.amazonaws.com/mybucket/main.css"> -->

I'm using django 1.6 and django-configurations==0.8 on heroku.

So it seems, when the STATIC_URL is set in settings.py. The value of AWS_STORAGE_BUCKET_NAME has not been set, but i think it should.

@jezdez would like confirm if this is a bug or an expected behaviour. If expected behaviour, is there an suggested way to set STATIC_URL value.

Cheers & thanks in advance.

Django 1.3 Support

Hello Jannis,

is there any way to get the configurations working with Django 1.3? We can't bump to 1.4 for several reasons but would like to use django-configurations.

Thanks in advance
Alex

type object 'Command' has no attribute 'inner_run'

Currently using v0.2.1. Not sure what's going on here other than the fact that python manage.py works without Configurations installed.

$ > ./manage.py validate                                                                         ~/Code/Revyver/hello-base hello-base master 7fb98d8
Traceback (most recent call last):
  File "./manage.py", line 33, in <module>
    from configurations.management import execute_from_command_line
  File "/Users/Bryan/.virtualenvs/hello-base/lib/python2.7/site-packages/configurations/management.py", line 3, in <module>
    importer.install()
  File "/Users/Bryan/.virtualenvs/hello-base/lib/python2.7/site-packages/configurations/importer.py", line 85, in install
    inner_run = runserver_module.Command.inner_run
AttributeError: type object 'Command' has no attribute 'inner_run'

Mixin not overriding django default?

This seems like a python issue, but how would you do what I want using mixins? I'm trying to keep various configuration items in separate classes/modules, but I'm unable to override AUTHENTICATION_BACKEND through a mixin.

I've simplified my example below:

$ cat settings/init.py
from configurations import Settings

class DjangoBase(Settings):
pass

class AuthDevelopment(object):
TEST_THIS = "We did include this..."
AUTHENTICATION_BACKENDS = ('a', 'b')

class Development(DjangoBase, AuthDevelopment):
pass

$ ./manage shell
Python 2.7.1 (r271:86832, Jun 21 2011, 22:19:26)
Type "copyright", "credits" or "license" for more information.

IPython 0.13.1 -- An enhanced Interactive Python.
? -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help -> Python's own help system.
object? -> Details about 'object', use 'object??' for extra details.

In [1]: from django.conf import settings

In [2]: settings.AUTHENTICATION_BACKENDS
Out[2]: ('django.contrib.auth.backends.ModelBackend',)

In [3]: settings.TEST_THIS
Out[3]: 'We did include this...'

In [4]:

Works with django-extensions shell_plus --notebook (IPython)?

I'm trying out IPython Notebook for the first time.

I'm not sure if it's a config issue or something with django-configurations, but I get this:

ImproperlyConfigured: django-configurations settings importer wasn't correctly installed. Please use one of the starter functions to install it as mentioned in the docs: http://django-configurations.readthedocs.org/

I'm also running the old version of django-configurations because that still accepts command line options like --notebook when I do: ./manage.py shell_plus.

Thanks,
Shige

Flexibility of DatabaseURLValue

From my understanding, DatabaseURLValue currently can only handle a limited number of database options (as defined here https://docs.djangoproject.com/en/dev/ref/settings/#databases). E.g there is no way to define CONN_MAX_AGE or you cannot define any other database than "default".

Is my understanding correct? If so, I think this is a a rather strong limitation for the usage of django-configurations.

I am happy to provide a patch along the lines of providing an extra options parameter that holds the additional values. Or would you rather recommend to fix that at dj_database_url?

six breaks django configurations

Last version of six==1.4.1 breaks django-configurations==0.2.1

Traceback (most recent call last):
  File "bin/shake_that", line 9, in <module>
    load_entry_point('shake_that==0.2.27', 'console_scripts', 'shake_that')()
  File "/path/to/lib/python2.7/site-packages/shake_that/runner.py", line 10, in main
    from configurations.management import execute_from_command_line
  File "/path/to/lib/python2.7/site-packages/configurations/__init__.py", line 2, in <module>
    from .base import Settings
  File "/path/to/lib/python2.7/site-packages/configurations/base.py", line 37, in <module>
    class Settings(six.with_metaclass(SettingsBase)):
  File "/path/to/lib/python2.7/site-packages/six.py", line 566, in with_metaclass
    return meta("NewBase", bases, {})
  File "/path/to/lib/python2.7/site-packages/configurations/base.py", line 19, in __new__
    if bases != (object,) and bases[0].__name__ != 'NewBase':
IndexError: tuple index out of range

Setting helpers

I'd like to put forward an idea. I have implemented something like this elsewhere (but outside of django-configurations it was a total hack). Sometimes when define settings they depend of the values of other settings. For one project I worked on we used LDAP and a lot of settings referred to a setting that had a domain name in it. We wanted to have that setting be different for each instance of this site, but then all the settings that referred to it needed to be redefined as well.

In django-configurations it might be nice to have something like this:

class Base(Settings):

    DOMAIN = "localhost"

    @property
    def DC(self):
        return ",".join("dc=%s" % part for part in self.DOMAIN.split("."))

    AUTH_LDAP_USER_DN_TEMPLATE = TemplateProperty("uid=%(user)s,ou=users,{DC}")

class Production(Base):

    DOMAIN = "example.com"

TemplateProperty would be a helper that uses the Formatter code in the string module (AKA "foo".format()) to generate a property based on other properties. Using foo.format() vs ``foo % vars` would mean they could refer to the contents of dicts and lists too.

My expectation is that when using my Production settings DC would be dc=example;dc=com and AUTH_LDAP_USER_DN_TEMPLATE would be uid=%(users),ou=users,dc=example,dc=com.

I think this only takes a simple class implementing a property descriptor (and some code to adapt a Settings class object to something to pass to string.Formatter.vformat) but my tests left me with production settings based on the base class values. I think this might be less of a problem if I used the Mixin stuff but it pains me to have to mix in the same mixins in the same order in multiple settings classes!

It would be nice if there was something like TemplateProperty built-in (that worked :D).

Inexplicable install failure

After pip installing django-configurations into a virtualenv, I am getting nothing but install errors. I was able to reproduce it as follows from the command line:

Python 2.7.2 (default, Oct 11 2012, 20:14:37) 
[GCC 4.2.1 Compatible Apple Clang 4.0 (tags/Apple/clang-418.0.60)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from configurations import Settings
>>> Settings.DEBUG
False
>>> Settings.DATABASES
{}
>>> class Base(Settings):
...   DEBUG = True
... 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/m2esoft/.virtualenvs/knuckle_tattoos/lib/python2.7/site-packages/configurations/base.py", line 24, in __new__
    raise ImproperlyConfigured(install_failure)
django.core.exceptions.ImproperlyConfigured: django-configurations settings importer wasn't correctly installed. Please use one of the starter functions to install it as mentioned in the docs: http://django-configurations.readthedocs.org/

Testing with Custom Mixins

How would I add a custom mixin to a certain test? Using @override_settings works currently for any specific settings:

from django.test import TestCase
from django.test.utils import override_settings
from django.conf import settings

@override_settings(INSTALLED_APPS=settings.INSTALLED_APPS + ('tests.apps.base',))
class UniqueBooleanTest(TestCase):
    ...

But how would I add a mixin like Amazon S3 support, to a certain test? I could repeat it within override_settings, but its rather long:

class S3(object):
    @property
    def INSTALLED_APPS(self):
        return (
            'storages',
        ) + super(S3, self).INSTALLED_APPS

    DEFAULT_FILE_STORAGE = 'storages.backends.s3boto.S3BotoStorage'
    AWS_ACCESS_KEY_ID = os.environ.get('AWS_ACCESS_KEY_ID')
    AWS_SECRET_ACCESS_KEY = os.environ.get('AWS_SECRET_ACCESS_KEY')
    AWS_STORAGE_BUCKET_NAME = os.environ.get('AWS_STORAGE_BUCKET_NAME')
    STATICFILES_STORAGE = DEFAULT_FILE_STORAGE

Everything is great, but what about --settings=?

I got this running and I hopefully won't be going back.

I have a use case where I had build settings that had multiple databases set up for migrating content.

I used to something like this:

./manage.py import_content --settings=project.build_settings

There was project/build_settings.py...

Now that I'm moving to django-configurations, I'd like to switch settings as needed without editing manage.py.

Any thoughts?

Thanks!

Consolidate settings view

Due to complexity of reading inherited classes maybe a good idea would be to make a consolidate view of all settings. The first thought is a management command that outputs all declared settings values.

AttributeError: 'Settings' object has no attribute 'ROOT_URLCONF'

The following error is thrown when the application receives the first request after server start.

(myenv) D:\Python\ws\myproj>python manage.py runserver
Validating models...

0 errors found
Django version 1.4.5, using settings 'mysite.settings', configuration 'Local'
Development server is running at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.
Traceback (most recent call last):
  File "C:\Python27\Lib\wsgiref\handlers.py", line 85, in run
    self.result = application(self.environ, self.start_response)
  File "D:\Python\env\myenv\lib\site-packages\django\contrib\staticfiles\handlers.py", line 67, in __call__
    return self.application(environ, start_response)
  File "D:\Python\env\myenv\lib\site-packages\django\core\handlers\wsgi.py", line 241, in __call__
    response = self.get_response(request)
  File "D:\Python\env\myenv\lib\site-packages\django\core\handlers\base.py", line 82, in get_response
    urlconf = settings.ROOT_URLCONF
  File "D:\Python\env\myenv\lib\site-packages\django\utils\functional.py", line 185, in inner
    return func(self._wrapped, *args)
AttributeError: 'Settings' object has no attribute 'ROOT_URLCONF'
[01/Dec/2013 15:50:48] "GET / HTTP/1.1" 500 59

Is it supported in Django 1.4.5?

IndexError with latest six (1.4)

Just upgraded my requirements, which upgraded six from 1.3.0 to 1.4.0. Got the following when starting Django 1.6b2/ Python 2.7.2).

Downgraded to 1.3.0 for now, just wanted to let you know.

Otherwise thanks for a nice library!

Traceback (most recent call last):
  File "manage.py", line 8, in <module>
    from configurations.management import execute_from_command_line
  File "/venv/lib/python2.7/site-packages/configurations/__init__.py", line 2, in <module>
    from .base import Settings
  File "/venv/lib/python2.7/site-packages/configurations/base.py", line 37, in <module>
    class Settings(six.with_metaclass(SettingsBase)):
  File "/venv/lib/python2.7/site-packages/six.py", line 566, in with_metaclass
    return meta("NewBase", bases, {})
  File "/venv/lib/python2.7/site-packages/configurations/base.py", line 19, in __new__
    if bases != (object,) and bases[0].__name__ != 'NewBase':
IndexError: tuple index out of range

Allow call_command import

At the moment you need to use execute_from_command_line to call a specific Django command:

    from configurations.management import execute_from_command_line
    execute_from_command_line([sys.argv[0]] + ["test"])

Adding call_command would be useful to make it easier to programmatically call Django commands using configurations:

  from configurations.management import call_command
  call_command("test", with_some_arg=True)

Can't pass options?

Thank you for the update. I've been looking forward to this for a while. It fixes somethings that didn't work (for me), but I figured out some work-arounds so I'm ok using the last version for now.

So after the new update:

% ./manage.py shell_plus --ipython
Usage: manage.py [options]

manage.py error: no such option: --ipython

This is valid and works in the previous version. Basically any option passed doesn't work.

% ./manage.py syncdb --noinput
Usage: manage.py [options]

manage.py error: no such option: --noinput

Did I need to alter manage.py or anything else as I upgraded from the old version?

Thanks,
Shige

Error when trying to use another app which imports settings (django-debug-toolbar, Django 1.7/master)

(I think this is caused by using django-configurations, but have not verified it without)

The following import from settings.py causes an ImproperlyConfigured error:

from debug_toolbar.middleware import show_toolbar as orig_show_toolbar

ImproperlyConfigured: The SECRET_KEY setting must not be empty.

Some important entries from stepping through this:

> …/django-debug-toolbar/debug_toolbar/middleware.py(14)<module>()
     13 
---> 14 from debug_toolbar.toolbar import DebugToolbar


> …/django-debug-toolbar/debug_toolbar/settings.py(41)<module>()
     40 
---> 41 USER_CONFIG = getattr(settings, 'DEBUG_TOOLBAR_CONFIG', {})

Is it possible for django-configurations to handle this?

Apart from that a workaround might be to use django-configurations's setup method/hook.

Problem using configurations when running multiple sites on the same VPS webserver ...

It would seem that if I have multiple sites sitting on a production VPS, I'm going to have problems with environmental settings like "DJANGO_AWS_ACCESS_KEY_ID" as such items will generally vary from project-to-project.

For your consideration, I'd recommend a changing the convention to include the project name as well (e.g, "DJANGO_PROJECTNAME_AWS_ACCESS_KEY_ID").

Thanks.

Best Way to Set Storage Backend

I am wondering how I would implement settings the switching the storage backend between local and S3.

In my app currently, not using django-configurations, I get a variable called DJANGO_STORAGE from the environment. If it is local then it uses the local storage settings, else if it s3 then it uses those settings. If it is neither, it raises an error. How would you reccomend implementing similar logic with django-configurations?

def get_env_variable(var_name, possible_options=[]):
    try:
        value = os.environ[var_name]
    except KeyError:
        message = "Set the {} environment variable".format(var_name)
        if possible_options:
            message += 'Possible options are {}'.format(str(possible_options))
        raise ImproperlyConfigured(message)
    if possible_options and value not in possible_options:
        raise ImproperlyConfigured(
            "The variable {} must be set to one of the following: {} "
            "It is set to '{}'' instead".format(
                var_name,
                str(possible_options),
                value
            )
        )
    if value.lower() == 'false':
        return False
    if value.lower() == 'true':
        return True
    return value

_storage_backend = get_env_variable(
    'CANADA_STORAGE',
    possible_options=['local', 's3']
)
if _storage_backend == 'local':
    STATICFILES_STORAGE = 'django.contrib.staticfiles.storage.CachedStaticFilesStorage'

    STATIC_URL = '/static/'
    STATIC_ROOT = rel_path('tmp/static')

    MEDIA_URL = '/media/'
    MEDIA_ROOT = rel_path('tmp/media')

elif _storage_backend == 's3':
    DEFAULT_FILE_STORAGE = 'storages.backends.s3boto.S3BotoStorage'
    STATICFILES_STORAGE = 'configs.storage_backends.S3HashedFilesStorage'

    INSTALLED_APPS += (
        'storages',
    )
    AWS_ACCESS_KEY_ID = get_env_variable('AWS_ACCESS_KEY_ID')
    AWS_SECRET_ACCESS_KEY = get_env_variable('AWS_SECRET_ACCESS_KEY')
    AWS_STORAGE_BUCKET_NAME = get_env_variable('AWS_BUCKET')
    AWS_S3_CUSTOM_DOMAIN = AWS_STORAGE_BUCKET_NAME
    _year_in_future = datetime.utcnow() + timedelta(days=365)
    AWS_HEADERS = {
        "Cache-Control": "public, max-age=31536000",
        'Expires': _year_in_future.strftime('%a, %d %b %Y %H:%M:%S UTC')
    }
    AWS_QUERYSTRING_AUTH = False
    AWS_QUERYSTRING_EXPIRE = 600
    AWS_S3_SECURE_URLS = False
    AWS_IS_GZIPPED = True
    AWS_PRELOAD_METADATA = True

    STATIC_URL = 'http://{}/'.format(AWS_S3_CUSTOM_DOMAIN)

Shell variables - How to deal with it?

Firstly, I would give you some background of my common problem:
I want to store variables like SESSION_KEY in my environment variables, probably issuing an export command: export SESSION_KEY="mysessionkey".

Why do I wanna do it? Because with it I can push my settings.py file without worrying with security because the key (SESSION_KEY) would be just available in the server.

# snippet of a function to handle environment variables. not tested but you get the idea.
def get_env_var(env_var):
    try:
        return os.environ[env_var]
    except KeyError:
        raise ImproperlyConfigured("No variable {} was set.".format(env_var))

Function above would take care of non set variables e.g if you set in Test class but not in Prod class configuration.

How can I do it with django-configurations?

installation of 0.3.1 fails

Thanks for making version 0.3.1 to fix of issue #37.
We didn't need to do the actual update to 0.3.1 earlier, but now trying to install 0.3.1, We get this error:

error in setup command: Error parsing django-configurations/setup.cfg:
DistutilsFileError: AUTHORS from the extra_files option in setup.cfg does not exist

django-configurations and django-celery > 3

Celery 2.5.x used to work with django-configurations.

3.0 do not.

it seem it's an issue with djcelery.loaders.

here is the issue on their side:

celery/django-celery#186

is there anyway to run configurations.importer. install() for those applications that rely on django internal importlib.import_module(self.SETTINGS_MODULE)?

Can't run any command

Django 1.5.1
django-configurations 0.2.1

When I run any command it says:

ImproperlyConfigured: The SECRET_KEY setting must not be empty.

But SECRET_KEY is set in Base configuration.

Looks like somehow it does not pick up class-based configs: when I run ./manage.py, only django commands are listed.

Guidelines for Inheritance Order

Does it matter where the configurations.Settings class is inheritied? As in, does it have to be in the last settings class?

I am asking because I have had some trouble, and it might be due to my inheritance structure. I followed your example in aggregation and inheritance. My problem is that settings.DATABASES is improperly configured. Please supply the ENGINE value. Check settings documentation for more details.

###
#settings/canada.py
###
from . import django, apps, development, production, testing

from configurations import Settings


class Canada(django.DjangoDefault,
             django.Email,
             apps.Grappelli,
             apps.Markdown,
             apps.SmartSelects,
             apps.Thumbnail,
             apps.TwitterBootstrap,
             apps.South,
             apps.Compress):
    CANADA_IMAGE_SIZE = 'x300'
    CANADA_FRONTPAGE_IMAGE_SIZE = 'x400'
    CANADA_ADMIN_THUMBS_SIZE = 'x60'

    NAME = 'canada'

    @property
    def INSTALLED_APPS(self):
        return (
            'canada.apps.artists',
            'canada.apps.exhibitions',
            'canada.apps.press',
            'canada.apps.updates',
            'canada.apps.bulkmail',
            'canada.apps.updates',
            'canada.apps.frontpage',
            'canada.apps.info',
            'canada.apps.base'
        ) + super(Canada, self).INSTALLED_APPS

    @property
    def TEMPLATE_CONTEXT_PROCESSORS(self):
        return (
            'canada.apps.base.context_processors.image_size',
        ) + super(Canada, self).TEMPLATE_CONTEXT_PROCESSORS


class LocalSettings(Canada,
                    development.Local,
                    development.Debug,
                    testing.Testing,
                    Settings):
    def __init__(self):
        super(LocalSettings, self).__init__()
        print super(LocalSettings, self).DATABASES


###
#settings/django.py
###
import imp
import os


class RelPath(object):
    def rel_path(self, relative_path):
        '''given any path relative to the `canada` project folder, returns the full path'''

         # find the canada directory
        SITE_ROOT = imp.find_module('canada')[1]
        return os.path.normpath(os.path.join(SITE_ROOT,
                                             relative_path))


class DjangoDefault(RelPath):
    SITE_ID = 1
    SECRET_KEY = os.environ.get('SECRET_KEY', '*YSHFUIH&GAHBJCZKCY)P#R')
    WSGI_APPLICATION = 'manage.application'
    DATE_FORMAT = 'F j, Y'

    @property
    def TEMPLATE_DEBUG(self):
        return super(DjangoDefault, self).DEBUG
...


###
#settings/development.py
###
from .django import RelPath


class SQLite(RelPath):
    @property
    def DATABASES(self):
        db = {
            'default': {
                'ENGINE': 'django.db.backends.sqlite3',
                'NAME': super(SQLite, self).rel_path('../sqlite.db'),
                'USER': '',
                'PASSWORD': '',
                'HOST': '',
                'PORT': '',
            }
        }
        return db

...

class Local(SQLite):
    INTERNAL_IPS = ('127.0.0.1',)
    CSRF_COOKIE_DOMAIN = 'localhost'

When I run any Django command, however, it does print DATABASES : {'default': {'ENGINE': 'django.db.backends.sqlite3', 'NAME': '/Users/saul/projects/django-canadanewyork/sqlite.db', 'HOST': '', 'USER': '', 'PASSWORD': '', 'PORT': ''}}

My configuration is LocalSettings

Celery configuration when configurations have been split over multiple files.

Hi

I've hit a wall attempting to get Celery (3.1.14) to operate with Django 1.7 and django-configurations (0.8) when the configuration classes have been split across multiple files.

By way of example, the https://github.com/pydanny/cookiecutter-django/tree/master/%7B%7Bcookiecutter.repo_name%7D%7D/%7B%7Bcookiecutter.repo_name%7D%7D repo has split the project structure as below:

project_name/
    config/
        __init__.py
        common.py
        local.py
    manage.py

I've put a file celery.py in the config directory per the Celery and django-configuration instructions.

However, no matter what combination of settings/paths/locations for the celery.py or import statements I try -- I constantly get an ImportError saying it's ImproperlyConfigured.

The only time I don't get that error is if I place the from .celery import app as celery_app above the common and local import lines in the config/__init__.py directory in which case the error regards not having a SECRET_KEY which indicates Celery is not loading the configuration/settings properly.

The environment variables in this case are: DJANGO_SETTINGS_ENVIRONMENT=config and DJANGO_CONFIGURATION=Local.

A Gist with summary file info & the error is available here: https://gist.github.com/gciding/6935ee400f903ffd4bdc

Do you have any ideas on what the issue could be or where I should look to fix it (without having to put the files back into a single settings.py file again)?

Cheers

Goran

Using a SecretValue as part of a String

I have a django(1.6.5) project and I am using the django-configurations(0.8) package and I am trying to set the STATIC_URL in the settings.py file with an environment variable by doing:

from configurations import Configuration, values
BUCKET_NAME = values.SecretValue()
STATIC_URL = 'https://s3.amazonaws.com/%s/' % BUCKET_NAME

But the STATIC_URL is set to:

'https://s3.amazonaws.com/<Value default:None>'

which is not valid or intended. I have the correct environment variable set too: DJANGO_BUCKET_NAME='thekey'

Any help would be appreciated

Value with ValidationMixin will raise ValueError if no default assigned

For example,

from configurations import Configuration, values


class Prod(Configuration):
    ...
    MEDIA_URL = values.URLValue()
    ...

Then, export DJANGO_MEDIA_URL='http://www.example.com/media/' and run python manage.py shell, ValueError will be raised.

Traceback (most recent call last):                                                                                                                                                                                               
  File "manage.py", line 11, in <module>                                                                                                                                                                                         
    execute_from_command_line(sys.argv)                                                                                                                                                                                          
  File "/home/phoenix/.virtualenvs/demo/lib/python2.7/site-packages/django/core/management/__init__.py", line 443, in execute_from_command_line                                                                           
    utility.execute()                                                                                                                                                                                                            
  File "/home/phoenix/.virtualenvs/demo/lib/python2.7/site-packages/django/core/management/__init__.py", line 382, in execute                                                                                             
    self.fetch_command(subcommand).run_from_argv(self.argv)                                                                                                                                                                      
  File "/home/phoenix/.virtualenvs/demo/lib/python2.7/site-packages/django/core/management/__init__.py", line 252, in fetch_command                                                                                       
    app_name = get_commands()[subcommand]                                                                                                                                                                                        
  File "/home/phoenix/.virtualenvs/demo/lib/python2.7/site-packages/django/core/management/__init__.py", line 101, in get_commands                                                                                        
    apps = settings.INSTALLED_APPS                                                                                                                                                                                               
  File "/home/phoenix/.virtualenvs/demo/lib/python2.7/site-packages/django/utils/functional.py", line 184, in inner                                                                                                       
    self._setup()                                                                                                                                                                                                                
  File "/home/phoenix/.virtualenvs/demo/lib/python2.7/site-packages/django/conf/__init__.py", line 42, in _setup                                                                                                          
    self._wrapped = Settings(settings_module)                                                                                                                                                                                    
  File "/home/phoenix/.virtualenvs/demo/lib/python2.7/site-packages/django/conf/__init__.py", line 93, in __init__                                                                                                        
    mod = importlib.import_module(self.SETTINGS_MODULE)                                                                                                                                                                          
  File "/home/phoenix/.virtualenvs/demo/lib/python2.7/site-packages/django/utils/importlib.py", line 35, in import_module                                                                                                 
    __import__(name)                                                                                                                                                                                                             
  File "/home/phoenix/.virtualenvs/demo/lib/python2.7/site-packages/configurations/importer.py", line 127, in load_module                                                                                                 
    mod = imp.load_module(fullname, *self.location)                                                                                                                                                                              
  File "/home/phoenix/demo/demo/settings/prod.py", line 7, in <module>                                                                                                                                      
    class Prod(Configuration):                                                                                                                                                                                  
  File "/home/phoenix/demo/demo/settings/prod.py", line 14, in Settings                                                                                                                                     
    MEDIA_URL = values.URLValue()
  File "/home/phoenix/.virtualenvs/demo/lib/python2.7/site-packages/configurations/values.py", line 235, in __init__
    self.to_python(self.default)
  File "/home/phoenix/.virtualenvs/demo/lib/python2.7/site-packages/configurations/values.py", line 241, in to_python
    raise ValueError(self.message.format(value))
ValueError: Cannot interpret URL value None

using Value class to format other Values'

From the template:

class Common(Configuration):
    BASE_DIR = values.PathValue(os.path.dirname(os.path.dirname(__file__)))

    DATABASES = values.DatabaseURLValue('sqlite://%s' % os.path.join(BASE_DIR, 'db.sqlite3'), environ=True)

This does not work for me at all, I get errors in os.path.join because it is effectively being passed an instance of PathValue, which does not repr itself as the value it holds.

In order for this to work there needs to be some form of late execution going on here, because the issue is the statement is evaluated at class creation, before Configuration.setup has resolved all the values.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.