mirror of
https://github.com/jazzband/django-configurations.git
synced 2026-03-16 22:20:27 +00:00
Merge bc11925cdd into 3d0d4216ca
This commit is contained in:
commit
b31ac9df15
6 changed files with 75 additions and 3 deletions
|
|
@ -99,6 +99,7 @@ class Configuration(metaclass=ConfigurationBase):
|
|||
|
||||
"""
|
||||
DOTENV_LOADED = None
|
||||
DOTENV_RELOAD = False
|
||||
|
||||
@classmethod
|
||||
def load_dotenv(cls):
|
||||
|
|
@ -113,6 +114,18 @@ class Configuration(metaclass=ConfigurationBase):
|
|||
# check if the class has DOTENV set whether with a path or None
|
||||
dotenv = getattr(cls, 'DOTENV', None)
|
||||
|
||||
required = True
|
||||
override_env = False
|
||||
# check if the DOTENV is dict, and check all options of it
|
||||
if isinstance(dotenv, dict):
|
||||
# whether we want to override previously set envs
|
||||
override_env = dotenv.get("override", False)
|
||||
# whether we want to error if the file is not found
|
||||
required = dotenv.get("required", True)
|
||||
# whether we want to reload on dotenv, useful if we want to frequently change it
|
||||
cls.DOTENV_RELOAD = dotenv.get("reload", False)
|
||||
dotenv = dotenv.get("path", None)
|
||||
|
||||
# if DOTENV is falsy we want to disable it
|
||||
if not dotenv:
|
||||
return
|
||||
|
|
@ -122,6 +135,8 @@ class Configuration(metaclass=ConfigurationBase):
|
|||
with open(dotenv) as f:
|
||||
content = f.read()
|
||||
except OSError as e:
|
||||
if not required:
|
||||
return
|
||||
raise ImproperlyConfigured("Couldn't read .env file "
|
||||
"with the path {}. Error: "
|
||||
"{}".format(dotenv, e)) from e
|
||||
|
|
@ -137,13 +152,16 @@ class Configuration(metaclass=ConfigurationBase):
|
|||
m3 = re.match(r'\A"(.*)"\Z', val)
|
||||
if m3:
|
||||
val = re.sub(r'\\(.)', r'\1', m3.group(1))
|
||||
os.environ.setdefault(key, val)
|
||||
if override_env:
|
||||
os.environ[key] = val
|
||||
else:
|
||||
os.environ.setdefault(key, val)
|
||||
|
||||
cls.DOTENV_LOADED = dotenv
|
||||
|
||||
@classmethod
|
||||
def pre_setup(cls):
|
||||
if cls.DOTENV_LOADED is None:
|
||||
if cls.DOTENV_LOADED is None or cls.DOTENV_RELOAD:
|
||||
cls.load_dotenv()
|
||||
|
||||
@classmethod
|
||||
|
|
|
|||
|
|
@ -57,6 +57,20 @@ A ``.env`` file is a ``.ini``-style file. It must contain a list of
|
|||
API_KEY1=1234
|
||||
API_KEY2=5678
|
||||
|
||||
``DOTENV`` can also be a dictionary, and then its behavior can be configured more:
|
||||
.. code-block:: python
|
||||
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
|
||||
|
||||
class Dev(Configuration):
|
||||
DOTENV = {
|
||||
"path": str(os.path.join(BASE_DIR, '.env')),
|
||||
# if True, overriddes previously set environmental variables, if False only sets them if they haven't been set before
|
||||
"override": True,
|
||||
# if True errors if the DOTENV is not found at path, if False return
|
||||
"required": False,
|
||||
# if True, reloads DOTENV dynamically for example on hot reload
|
||||
"reload": True,
|
||||
|
||||
Envdir
|
||||
------
|
||||
|
||||
|
|
|
|||
|
|
@ -1 +1,2 @@
|
|||
DJANGO_DOTENV_VALUE='is set'
|
||||
DJANGO_DOTENV_VALUE='is set'
|
||||
DJANGO_DOTENV_OVERRIDE='overridden'
|
||||
|
|
|
|||
12
tests/settings/dot_env_dict.py
Normal file
12
tests/settings/dot_env_dict.py
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
from configurations import Configuration, values
|
||||
|
||||
|
||||
class DotEnvConfiguration(Configuration):
|
||||
|
||||
DOTENV = {
|
||||
'path': 'test_project/.env',
|
||||
'override': True,
|
||||
}
|
||||
|
||||
DOTENV_VALUE = values.Value()
|
||||
DOTENV_OVERRIDE = values.Value("Not overridden")
|
||||
12
tests/settings/dot_env_not_required.py
Normal file
12
tests/settings/dot_env_not_required.py
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
from configurations import Configuration, values
|
||||
|
||||
|
||||
class DotEnvConfiguration(Configuration):
|
||||
|
||||
DOTENV = {
|
||||
'path': 'some_nonexistant_path',
|
||||
'override': True,
|
||||
'required': False,
|
||||
}
|
||||
|
||||
DOTENV_OVERRIDE = values.Value("Not overridden")
|
||||
|
|
@ -13,3 +13,18 @@ class DotEnvLoadingTests(TestCase):
|
|||
self.assertEqual(dot_env.DOTENV_VALUE, 'is set')
|
||||
self.assertEqual(dot_env.DOTENV_VALUE_METHOD, 'is set')
|
||||
self.assertEqual(dot_env.DOTENV_LOADED, dot_env.DOTENV)
|
||||
|
||||
@patch.dict(os.environ, clear=True,
|
||||
DJANGO_CONFIGURATION='DotEnvConfiguration',
|
||||
DJANGO_SETTINGS_MODULE='tests.settings.dot_env_dict')
|
||||
def test_env_dict(self):
|
||||
from tests.settings import dot_env_dict
|
||||
self.assertEqual(dot_env_dict.DOTENV_VALUE, 'is set')
|
||||
self.assertEqual(dot_env_dict.DOTENV_OVERRIDE, 'overridden')
|
||||
|
||||
@patch.dict(os.environ, clear=True,
|
||||
DJANGO_CONFIGURATION='DotEnvConfiguration',
|
||||
DJANGO_SETTINGS_MODULE='tests.settings.dot_env_not_required')
|
||||
def test_env_not_required(self):
|
||||
from tests.settings import dot_env_not_required
|
||||
self.assertEqual(dot_env_not_required.DOTENV_OVERRIDE, 'Not overridden')
|
||||
|
|
|
|||
Loading…
Reference in a new issue