A helper for organizing Django project settings by relying on well established programming patterns.
Find a file
Pavel Savchenko 3883cc4fe4 Docs: explicitly describe property in patterns.rst (#189)
Hopefully this saves time for new users of django-configuration (like myself), who "just needed" to lazily evaluate a string inside a dictionary.

This doubles as an example for `RAVEN_CONFIG` which was the whole reason I was here in the first place... The actual problem I faced was that a setting remains of type `values.Value` when nested inside a dictionary. Which results in a weird issues like this:

```
2018-02-24T20:59:26.125208+00:00 app[web.1]: Traceback (most recent call last):
2018-02-24T20:59:26.125364+00:00 app[web.1]:     self.client.http_context(self.get_http_context(environ))
2018-02-24T20:59:26.125215+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.6/site-packages/raven/middleware.py", line 98, in __call__
2018-02-24T20:59:26.125368+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.6/site-packages/raven/contrib/django/models.py", line 54, in <lambda>
2018-02-24T20:59:26.125482+00:00 app[web.1]:     __getattr__ = lambda x, o: getattr(get_client(), o)
2018-02-24T20:59:26.125486+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.6/site-packages/raven/contrib/django/models.py", line 134, in get_client
2018-02-24T20:59:26.125613+00:00 app[web.1]:     instance = Client(**options)
2018-02-24T20:59:26.125618+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.6/site-packages/raven/contrib/django/client.py", line 147, in __init__
2018-02-24T20:59:26.125769+00:00 app[web.1]:     Client.__init__(self, *args, **kwargs)
2018-02-24T20:59:26.125771+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.6/site-packages/raven/base.py", line 171, in __init__
2018-02-24T20:59:26.125927+00:00 app[web.1]:     self.set_dsn(dsn, transport)
2018-02-24T20:59:26.125929+00:00 app[web.1]:   File "/app/.heroku/python/lib/python3.6/site-packages/raven/base.py", line 251, in set_dsn
2018-02-24T20:59:26.126063+00:00 app[web.1]:     if dsn not in self._transport_cache:
2018-02-24T20:59:26.126076+00:00 app[web.1]: TypeError: unhashable type: 'Value'
```
2018-02-27 21:43:18 +01:00
configurations Drop unmaintained version of django and python 2017-09-30 14:37:38 +02:00
docs Docs: explicitly describe property in patterns.rst (#189) 2018-02-27 21:43:18 +01:00
test_project Merge remote-tracking branch 'joke2k/dot-env' 2015-01-06 22:34:29 +01:00
tests Fix Django 2.0: use new url syntax (#182) 2017-10-05 02:42:34 +02:00
.coveragerc .coveragerc: use include instead of multiple sources (#183) 2017-10-07 18:03:03 +02:00
.gitignore Drop unmaintained version of django and python 2017-09-30 14:37:38 +02:00
.travis.yml Fix Django 2.0: use new url syntax (#182) 2017-10-05 02:42:34 +02:00
AUTHORS Updated authors and license. 2013-04-11 17:14:40 +02:00
CONTRIBUTING.md Typo 2016-03-21 14:40:28 -04:00
LICENSE Happy New Year! 2014-01-16 19:00:40 +01:00
MANIFEST.in included license (#176) 2017-09-23 22:58:44 +02:00
README.rst Convert readthedocs links for their .org -> .io migration for hosted projects 2016-06-11 10:56:42 +01:00
setup.cfg Revert "Use py.test." 2015-02-13 16:43:55 +01:00
setup.py Drop unmaintained version of django and python 2017-09-30 14:37:38 +02:00
tox.ini qa: run flake8 against tests (#180) 2017-10-07 12:32:20 +02:00

django-configurations
=====================

.. image:: https://travis-ci.org/jazzband/django-configurations.svg?branch=master
   :alt: Build Status
   :target: https://travis-ci.org/jazzband/django-configurations

.. image:: https://jazzband.co/static/img/badge.svg
   :alt: Jazzband
   :target: https://jazzband.co/

.. image:: https://codecov.io/github/jazzband/django-configurations/coverage.svg?branch=master
   :alt: Codecov
   :target: https://codecov.io/github/jazzband/django-configurations?branch=master

django-configurations eases Django project configuration by relying
on the composability of Python classes. It extends the notion of
Django's module based settings loading with well established
object oriented programming patterns.

Check out the `documentation`__ for more complete examples.

.. __: https://django-configurations.readthedocs.io/en/latest/


Quickstart
----------

Install django-configurations:

.. code-block:: console

    pip install django-configurations

Then subclass the included ``configurations.Configuration`` class in your
project's **settings.py** or any other module you're using to store the
settings constants, e.g.:

.. code-block:: python

    # mysite/settings.py

    from configurations import Configuration

    class Dev(Configuration):
        DEBUG = True

Set the ``DJANGO_CONFIGURATION`` environment variable to the name of the class
you just created, e.g. in bash:

.. code-block:: console

    export DJANGO_CONFIGURATION=Dev

and the ``DJANGO_SETTINGS_MODULE`` environment variable to the module
import path as usual, e.g. in bash:

.. code-block:: console

    export DJANGO_SETTINGS_MODULE=mysite.settings

*Alternatively* supply the ``--configuration`` option when using Django
management commands along the lines of Django's default ``--settings``
command line option, e.g.::

    python manage.py runserver --settings=mysite.settings --configuration=Dev

To enable Django to use your configuration you now have to modify your
**manage.py** or **wsgi.py** script to use django-configurations's versions
of the appropriate starter functions, e.g. a typical **manage.py** using
django-configurations would look like this:

.. code-block:: python

    #!/usr/bin/env python

    import os
    import sys

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

        from configurations.management import execute_from_command_line

        execute_from_command_line(sys.argv)

Notice in line 10 we don't use the common tool
``django.core.management.execute_from_command_line`` but instead
``configurations.management.execute_from_command_line``.

The same applies to your **wsgi.py** file, e.g.:

.. code-block:: python

    import os

    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mysite.settings')
    os.environ.setdefault('DJANGO_CONFIGURATION', 'Dev')

    from configurations.wsgi import get_wsgi_application

    application = get_wsgi_application()

Here we don't use the default ``django.core.wsgi.get_wsgi_application``
function but instead ``configurations.wsgi.get_wsgi_application``.

That's it! You can now use your project with ``manage.py`` and your favorite
WSGI enabled server.