From 7937ac7134ceff86c1100262fd1a56f7ee20253d Mon Sep 17 00:00:00 2001 From: S4NKALP Date: Thu, 27 Nov 2025 21:09:36 +0545 Subject: [PATCH] refactor(config): replace python-dotenv with django-environ for settings management --- djinit/templates/config/asgi.j2 | 7 ++-- djinit/templates/config/settings/base.j2 | 5 ++- .../templates/config/settings/production.j2 | 39 ++++++++----------- djinit/templates/config/wsgi.j2 | 8 ++-- djinit/templates/project/manage_py.j2 | 7 +++- djinit/templates/project/requirements.j2 | 2 +- 6 files changed, 35 insertions(+), 33 deletions(-) diff --git a/djinit/templates/config/asgi.j2 b/djinit/templates/config/asgi.j2 index 80dff82..aa7df17 100644 --- a/djinit/templates/config/asgi.j2 +++ b/djinit/templates/config/asgi.j2 @@ -1,10 +1,11 @@ """generated with djinit""" import os -from dotenv import load_dotenv +import environ from django.core.asgi import get_asgi_application -load_dotenv() +env = environ.Env() +environ.Env.read_env() -os.environ.setdefault("DJANGO_SETTINGS_MODULE", os.getenv("DJANGO_SETTINGS_MODULE", "core.settings.production")) +os.environ.setdefault("DJANGO_SETTINGS_MODULE", env("DJANGO_SETTINGS_MODULE", default="core.settings.production")) application = get_asgi_application() diff --git a/djinit/templates/config/settings/base.j2 b/djinit/templates/config/settings/base.j2 index 777cc36..25797c9 100644 --- a/djinit/templates/config/settings/base.j2 +++ b/djinit/templates/config/settings/base.j2 @@ -7,9 +7,10 @@ import os from datetime import timedelta from pathlib import Path -from dotenv import load_dotenv +import environ -load_dotenv() +env = environ.Env() +environ.Env.read_env() # Build paths inside the project like this: BASE_DIR / 'subdir'. BASE_DIR = Path(__file__).resolve().parent.parent.parent diff --git a/djinit/templates/config/settings/production.j2 b/djinit/templates/config/settings/production.j2 index f18c6a7..a2ab0f6 100644 --- a/djinit/templates/config/settings/production.j2 +++ b/djinit/templates/config/settings/production.j2 @@ -1,18 +1,17 @@ """generated with djinit""" from .base import * -import os import dj_database_url DEBUG = False -SECRET_KEY = os.getenv('SECRET_KEY') -ALLOWED_HOSTS = os.getenv('ALLOWED_HOSTS', '').split(',') +SECRET_KEY = env('SECRET_KEY') +ALLOWED_HOSTS = env.list('ALLOWED_HOSTS', default=[]) # Database {% if use_database_url %} # Using dj_database_url (recommended for production) DATABASES = { - 'default': dj_database_url.parse(os.getenv('DATABASE_URL')) + 'default': env.db('DATABASE_URL') } {% else %} # Using individual database parameters @@ -20,26 +19,22 @@ DATABASES = { 'default': { {% if database_type == 'mysql' %} 'ENGINE': 'django.db.backends.mysql', - 'PORT': os.getenv('DB_PORT', '3306'), + 'PORT': env('DB_PORT', default='3306'), {% else %} 'ENGINE': 'django.db.backends.postgresql', - 'PORT': os.getenv('DB_PORT', '5432'), + 'PORT': env('DB_PORT', default='5432'), {% endif %} - 'NAME': os.getenv('DB_NAME'), - 'USER': os.getenv('DB_USER'), - 'PASSWORD': os.getenv('DB_PASSWORD'), - 'HOST': os.getenv('DB_HOST'), - 'HOST': os.getenv('DB_HOST'), + 'NAME': env('DB_NAME'), + 'USER': env('DB_USER'), + 'PASSWORD': env('DB_PASSWORD'), + 'HOST': env('DB_HOST'), } } {% endif %} # CORS settings for production # Filter out empty strings from FRONTEND_URL -frontend_urls = os.getenv("FRONTEND_URL", "") -CORS_ALLOWED_ORIGINS = [ - origin.strip() for origin in frontend_urls.split(",") if origin.strip() -] +CORS_ALLOWED_ORIGINS = env.list('FRONTEND_URL', default=[]) CORS_ALLOW_CREDENTIALS = True # Additional CORS security for production @@ -47,13 +42,13 @@ CORS_ALLOW_PRIVATE_NETWORK = False # Email settings EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' -EMAIL_HOST = os.getenv('EMAIL_HOST') -EMAIL_PORT = int(os.getenv('EMAIL_PORT', 587)) -EMAIL_USE_TLS = os.getenv('EMAIL_USE_TLS', 'True').lower() == 'true' -EMAIL_HOST_USER = os.getenv('EMAIL_HOST_USER') -EMAIL_HOST_PASSWORD = os.getenv('EMAIL_HOST_PASSWORD') -DEFAULT_FROM_EMAIL = os.environ.get("EMAIL_HOST_USER") -SERVER_EMAIL = os.environ.get("EMAIL_HOST_USER") +EMAIL_HOST = env('EMAIL_HOST') +EMAIL_PORT = env.int('EMAIL_PORT', default=587) +EMAIL_USE_TLS = env.bool('EMAIL_USE_TLS', default=True) +EMAIL_HOST_USER = env('EMAIL_HOST_USER') +EMAIL_HOST_PASSWORD = env('EMAIL_HOST_PASSWORD') +DEFAULT_FROM_EMAIL = env('EMAIL_HOST_USER') +SERVER_EMAIL = env('EMAIL_HOST_USER') # Security settings for production SECURE_SSL_REDIRECT = True diff --git a/djinit/templates/config/wsgi.j2 b/djinit/templates/config/wsgi.j2 index 8f48013..22bf67e 100644 --- a/djinit/templates/config/wsgi.j2 +++ b/djinit/templates/config/wsgi.j2 @@ -1,10 +1,12 @@ """generated with djinit""" import os -from dotenv import load_dotenv +import environ from django.core.wsgi import get_wsgi_application -load_dotenv() -os.environ.setdefault("DJANGO_SETTINGS_MODULE", os.getenv("DJANGO_SETTINGS_MODULE", "core.settings.production")) +env = environ.Env() +environ.Env.read_env() + +os.environ.setdefault("DJANGO_SETTINGS_MODULE", env("DJANGO_SETTINGS_MODULE", default="core.settings.production")) application = get_wsgi_application() diff --git a/djinit/templates/project/manage_py.j2 b/djinit/templates/project/manage_py.j2 index 422a555..079cfdc 100644 --- a/djinit/templates/project/manage_py.j2 +++ b/djinit/templates/project/manage_py.j2 @@ -6,7 +6,7 @@ import os import sys -from dotenv import load_dotenv +import environ def main(): @@ -25,5 +25,8 @@ def main(): if __name__ == "__main__": - load_dotenv() + env = environ.Env() + # Read .env file, if it exists + environ.Env.read_env() + main() diff --git a/djinit/templates/project/requirements.j2 b/djinit/templates/project/requirements.j2 index c7d522f..381a0b7 100644 --- a/djinit/templates/project/requirements.j2 +++ b/djinit/templates/project/requirements.j2 @@ -3,7 +3,7 @@ #--------------------------------------------------# Django -python-dotenv +django-environ django-jazzmin djangorestframework djangorestframework_simplejwt