====================
django-settings-file
====================
.. image:: https://img.shields.io/github/workflow/status/adamchainz/django-settings-file/CI/main?style=for-the-badge
:target: https://github.com/adamchainz/django-settings-file/actions?workflow=CI
.. image:: https://img.shields.io/pypi/v/django-settings-file.svg?style=for-the-badge
:target: https://pypi.org/project/django-settings-file/
.. image:: https://img.shields.io/badge/code%20style-black-000000.svg?style=for-the-badge
:target: https://github.com/psf/black
.. image:: https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white&style=for-the-badge
:target: https://github.com/pre-commit/pre-commit
:alt: pre-commit
Unmaintained (2022-12-07)
-------------------------
I stopped maintaining this package as it has never been popular.
If you want to use the functionality I recommend copying the small amount of code into your project.
----
Let Django use settings from an arbitrary Python file instead of an importable module.
As per `James Pic's idea posted on the django-developers mailing list
<https://groups.google.com/forum/#!msg/django-developers/mzkwaGQtpOk/LZkxLUMwBQAJ>`_.
Requirements
------------
Python 3.7 to 3.11 supported.
Django 3.2 to 4.1 supported.
----
**Want to work smarter and faster?**
Check out my book `Boost Your Django DX <https://adamchainz.gumroad.com/l/byddx>`__ which covers many ways to improve your development experience.
----
Usage
-----
1. Install with ``python -m pip install django-settings-file``.
2. Edit your ``manage.py`` and ``wsgi.py`` to swap out Django's default logic for setting ``DJANGO_SETTINGS_MODULE`` to
instead do:
.. code-block:: python
import django_settings_file
django_settings_file.setup()
3. Add ``os.environ.setdefault('DJANGO_SETTINGS_FILE', '/path/to/default.py')`` before the ``setup()`` call, unless you
can be sure ``DJANGO_SETTINGS_FILE`` will always be defined in your environment. You might need to figure out the
path relative to your ``manage.py`` with some ``os.path`` manipulation.
4. Run it! If ``DJANGO_SETTINGS_MODULE`` is defined, it will raise a ``DjangoSettingsFileError`` with a message about
how only ``DJANGO_SETTINGS_FILE`` is allowed now. If ``DJANGO_SETTINGS_FILE`` is not defined, it will also fail with
a ``DjangoSettingsFileError`` with a message about defining it. Otherwise Django should start with the settings!
How it works
------------
``django-settings-file`` imports the contents of the specified file using the import machinery available on your Python
version (different logic for 2 and 3) and copies it contents into its own module, which Django sees as the settings
file defined via the traditional ``DJANGO_SETTINGS_MODULE``. Nothing about Django is really touched, it's just a
hacky module.
Caveats
-------
* If the Python file defined by ``DJANGO_SETTINGS_FILE`` tries to do any imports, the directory the file is in will not
be on ``PYTHONPATH``, so the author of the settings file might get some surprises.
* Additionally, you might experience other problems from loading a file whilst it's not on ``PYTHONPATH``.
* If you want your settings file to extend another one, it will probably find it easiest to ``import`` the base one
from a location on ``PYTHONPATH``, otherwise it too will have to do use the same import 'hacks' to load the default
settings.
* File paths are not portable between operating systems, so you may need logic to support both Unix and Windows at
once.
* File paths are not portable between ``.py`` and ``.pyc`` files. In most cases this means a ``.pyc`` file will not be
used for settings since it can't be guaranteed to be there, slightly slowing down import time.
* ``DJANGO_SETTINGS_MODULE`` and ``DJANGO_SETTINGS_FILE`` can't both be used by the same project, since the module is
required for the file-based logic. You might be able to allow them both with extra logic, pull requests accepted.
* ``¯\_(ツ)_/¯`` - this is kind of unknown territory, this library has not been tested in any real project, just with
the example project in the test folder.