Home > Enterprise >  Unable to read environment variables in Django using django_configurations package
Unable to read environment variables in Django using django_configurations package

Time:04-11

I was using django-environ to manage env variables, everything was working fine, recently I moved to django-configurations.

My settings inherit configurations.Configuration but I am having trouble getting values from .env file. For example, while retrieving DATABASE_NAME it gives the following error: TypeError: object of type 'Value' has no len()

I know the below code returns a value.Value instance instead of a string, but I am not sure why it does so. The same is the case with every other env variable:

My .env. file is as follows:

DEBUG=True
DATABASE_NAME='portfolio_v1'
SECRET_KEY='your-secrete-key'

settings.py file is as follows

 ...
 from configurations import Configuration, values
 DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.postgresql',
            'NAME': values.Value("DATABASE_NAME", environ=True),
 ...

I have verified that my `.env' file exists and is on the valid path.

CodePudding user response:

I spent more time resolving the above issue and found what was missing. Prefixing .env variables is mandatory in django-configuration as a default behavior.

While dealing dict keys, we have to provide environ_name kwarg to the Value instance

NOTE: .env variables should be prefixed with DJANGO_ even if you provide environ_name. If you want to override the prefix you have to provide environ_prefix) i.e.

    DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': values.Value(environ_name="DATABASE_NAME"), # provide DJANGO_DATABASE_NAME='portfolio_v1' in .env file

other use cases are:

VAR = values.Value()   # works, provided DJANGO_VAR='var_value'
VAR = values.Value(environ_prefix='MYSITE')    # works, provided MYSITE_VAR='var_value'
CUSTOM_DICT = {
    'key_1': values.Value(environ_required=True),  # doesn't work
    'key_2': values.Value(environ_name='other_key'), # works if provided DJANGO_key_2='value_2' in .env
}

CodePudding user response:

You are using django-configurations in the wrong way.

See the source code of the Value class:

class Value:
    @property
    def value(self):
       ...
    def __init__(self, default=None, environ=True, environ_name=None,
                 environ_prefix='DJANGO', environ_required=False,
                 *args, **kwargs):
       ...

So you want to have the default value not as "DATABASE_NAME", and your environment variable in your .env file should start with DJANGO_.

Then to use the value you can use the value property, so your settings file should look like:

...
 from configurations import Configuration, values
 DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.postgresql',
            'NAME': values.Value("DEFAULT_VAL").value, 
                    # No need for environ=True since it is default
 ...
  • Related