django-environ: Diccionarios anidados

Publicado el 27 de febrero de 2025 por Cristian Torres

Hace poco estaba tratando de encontrar la forma de cargar una serie de diccionarios anidados usando django-environ, al estilo de la configuración para la base de datos en django.

Para ser más preciso intentaba cargar una serie de nombres, llaves y secretos para buckets en S3.

.env
AWS_S3_BUCKETS='BUCKET1=name=bucket1;key_id=key_id1;secret=secret1,BUCKET2=name=bucket2;key_id=key_id2,secret=secret2'

El problema es que django-environ no puede realizar la carga de diccionarios anidados, pero, sí puede cargar listas y “parsear” diccionarios anidados (1 nivel de anidación máximo), si juntamos esas dos capacidades podemos crear una nueva definición de variables para este tipo.

Para cargar este nuevo tipo de valores necesitamos hacerlo en nuestro código de la siguiente manera:

settings.py
import environ
env = environ.Env()
env.read_env('path/to/.env')
...
AWS_S3_BUCKETS = {
key: env.parse_value(value, {})
for (key, value) in dict([
dictionary.split("=", 1) # 1
for dictionary in env.list('AWS_S3_BUCKETS')
]).items()
}
...

El formato de cada diccionario anidado dentro de la variable en el archivo .env sería el siguiente:

nested_dict1=subkey1_for_nested_dict1=value;subkey2_for_nested_dict1=value

Y así lo podemos para cada diccionario anidado, usando , como separador.

.env
AWS_S3_BUCKETS='BUCKET1=name=bucket1;key_id=key_id1;secret=secret1,BUCKET2=name=bucket2;key_id=key_id2;secret=secret2'

ADVERTENCIA

Este código no es seguro, no lo uses en producción sin antes hacer las validaciones necesarias.