# ๐ Django-CFG: Developer-First Django Configuration
[](https://pypi.org/project/django-cfg/)
[](https://pypi.org/project/django-cfg/)
[](https://github.com/markolofsen/django-cfg/blob/main/LICENSE)
[](https://pypi.org/project/django-cfg/)
**Transform your Django configuration from 100+ lines of boilerplate to clean, type-safe YAML + Python configuration.**
Django-CFG is a revolutionary Django configuration system that provides developer-first experience through Pydantic v2 models, YAML configuration files, intelligent automation, and zero boilerplate.
## โจ Key Features
- ๐ฏ **90% Less Boilerplate** - Replace massive `settings.py` with clean config classes
- ๐ **100% Type Safety** - All configuration through Pydantic v2 models
- ๐ **YAML Configuration** - Environment-specific settings in readable YAML files
- ๐ซ **Zero Raw Dicts** - No more error-prone dictionary configurations
- ๐ง **Smart Defaults** - Environment-aware defaults (Redis for prod, Memory for dev)
- ๐ก **IDE Support** - Full autocomplete and validation in your IDE
- ๐จ **Beautiful Admin** - Pre-configured Django Unfold with Tailwind CSS
- ๐ **API Generation** - Automatic OpenAPI/Swagger with Django Revolution
- ๐ฆ **Easy Migration** - Gradual migration from existing Django projects
## ๐ Quick Start
### Installation
```bash
pip install django-cfg
```
### Before (Traditional Django - 100+ lines)
```python
# settings.py - Traditional Django configuration ๐ข
import os
from pathlib import Path
BASE_DIR = Path(__file__).resolve().parent.parent
SECRET_KEY = os.environ.get('SECRET_KEY', 'dev-key')
DEBUG = os.environ.get('DEBUG', 'False') == 'True'
ALLOWED_HOSTS = ['localhost', '127.0.0.1']
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'drf_spectacular',
'corsheaders',
'myapp',
]
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware',
'django.middleware.security.SecurityMiddleware',
'whitenoise.middleware.WhiteNoiseMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': os.environ.get('DATABASE_NAME', 'mydb'),
'USER': os.environ.get('DATABASE_USER', 'postgres'),
'PASSWORD': os.environ.get('DATABASE_PASSWORD', ''),
'HOST': os.environ.get('DATABASE_HOST', 'localhost'),
'PORT': os.environ.get('DATABASE_PORT', '5432'),
}
}
CACHES = {
'default': {
'BACKEND': 'django_redis.cache.RedisCache',
'LOCATION': os.environ.get('REDIS_URL', 'redis://localhost:6379/1'),
'OPTIONS': {
'CLIENT_CLASS': 'django_redis.client.DefaultClient',
}
}
}
REST_FRAMEWORK = {
'DEFAULT_SCHEMA_CLASS': 'drf_spectacular.openapi.AutoSchema',
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.SessionAuthentication',
'rest_framework_simplejwt.authentication.JWTAuthentication',
],
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated',
],
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 20
}
SPECTACULAR_SETTINGS = {
'TITLE': 'My API',
'DESCRIPTION': 'My API description',
'VERSION': '1.0.0',
'SERVE_INCLUDE_SCHEMA': False,
}
# ... 50+ more lines of configuration
```
### After (Django-CFG - Clean & Simple)
#### 1. Environment Configuration (`config.dev.yaml`)
```yaml
# Development Environment Configuration
secret_key: "django-insecure-550e8400-e29b-41d4-a716-446655440000-dev-key"
debug: true
# Database
database:
url: "postgresql://postgres:postgres@localhost:5432/myapp"
url_analytics: "postgresql://postgres:postgres@localhost:5432/analytics"
# Application URLs
app:
name: "MyApp"
domain: "localhost"
api_url: "http://localhost:8000"
site_url: "http://localhost:3000"
# Email
email:
backend: "smtp"
host: "smtp.gmail.com"
port: 587
username: "hello@myapp.com"
password: "app-password"
use_tls: true
default_from: "MyApp <hello@myapp.com>"
# Telegram Bot
telegram:
bot_token: "your-bot-token"
group_id: -123456789
# Cache
redis_url: "redis://localhost:6379/1"
```
#### 2. Application Configuration (`config.py`)
```python
from typing import List, Dict
from django_cfg import (
DjangoConfig,
DatabaseConnection,
DatabaseRoutingRule,
CacheBackend,
UnfoldConfig,
UnfoldTheme,
RevolutionConfig,
ZoneConfig,
EmailConfig,
TelegramConfig,
)
from .environment import env
class MyAppConfig(DjangoConfig):
"""๐ Complete production-ready configuration using django_cfg"""
# === Project Information ===
project_name: str = "MyApp"
project_version: str = "1.0.0"
site_url: str = env.app.site_url
api_url: str = env.app.api_url
# === Core Settings (from YAML) ===
secret_key: str = env.secret_key
debug: bool = env.debug
# === Security ===
security_domains: List[str] = [
"https://myapp.com",
"https://api.myapp.com",
"http://localhost:3000", # Development
"http://localhost:8000",
]
# === Custom User Model ===
auth_user_model: str = "accounts.CustomUser"
# === Project Apps ===
project_apps: List[str] = [
"accounts",
"products",
"orders",
"analytics",
]
# === Multi-Database Setup ===
databases: Dict[str, DatabaseConnection] = {
"default": DatabaseConnection(
engine="django.db.backends.postgresql",
**env.database.parse_url(env.database.url),
connect_timeout=10,
sslmode="prefer",
),
"analytics": DatabaseConnection(
engine="django.db.backends.postgresql",
**env.database.parse_url(env.database.url_analytics),
connect_timeout=10,
sslmode="prefer",
),
}
# === Database Routing ===
database_routing: List[DatabaseRoutingRule] = [
DatabaseRoutingRule(
apps=["analytics"],
database="analytics",
operations=["read", "write"],
),
]
# === Redis Cache ===
cache_default: CacheBackend = CacheBackend(
redis_url=env.redis_url,
timeout=300,
)
cache_sessions: CacheBackend = CacheBackend(
redis_url=env.redis_url.replace("/1", "/2"),
timeout=1800, # 30 minutes
)
# === Email Configuration ===
email: EmailConfig = EmailConfig(
host=env.email.host,
port=env.email.port,
username=env.email.username,
password=env.email.password,
use_tls=env.email.use_tls,
default_from_email=env.email.default_from,
)
# === Telegram Notifications ===
telegram: TelegramConfig = TelegramConfig(
bot_token=env.telegram.bot_token,
chat_id=env.telegram.group_id,
parse_mode="HTML",
)
# === Beautiful Admin Interface ===
unfold: UnfoldConfig = UnfoldConfig(
theme=UnfoldTheme(
site_title="MyApp Admin",
site_header="MyApp",
site_subheader="Management Dashboard",
theme="auto", # Auto light/dark theme
dashboard_callback="myapp.dashboard.main_callback",
),
)
# === API Configuration with Revolution ===
revolution: RevolutionConfig = RevolutionConfig(
api_prefix="api",
drf_title="MyApp API",
drf_description="RESTful API with automatic OpenAPI generation",
drf_version="1.0.0",
zones={
"public": ZoneConfig(
apps=["products"],
title="Public API",
description="Public product catalog",
public=True,
auth_required=False,
),
"client": ZoneConfig(
apps=["accounts", "orders"],
title="Client API",
description="User accounts and orders",
public=True,
auth_required=True,
),
"admin": ZoneConfig(
apps=["analytics"],
title="Admin API",
description="Analytics and reporting",
public=False,
auth_required=True,
),
},
)
# Initialize configuration
config = MyAppConfig()
```
#### 3. Django Settings (`settings.py`) - Just 3 Lines!
```python
"""Ultra-minimal settings powered by django_cfg"""
from .config import config
# Apply ALL Django settings from django_cfg
globals().update(config.get_all_settings())
```
## ๐ก What You Get Automatically
โ
**All Django core apps and middleware configured**
โ
**Environment detection (dev/prod/test/staging)**
โ
**Smart cache backend selection (Redis/Memory)**
โ
**Security settings based on your domains**
โ
**Complete type safety and validation**
โ
**Beautiful Django Unfold admin with Tailwind CSS**
โ
**Automatic OpenAPI/Swagger documentation**
โ
**Multi-database routing**
โ
**Session management**
โ
**CORS configuration**
โ
**Static files with WhiteNoise**
โ
**Email and Telegram notifications**
## ๐๏ธ Real-World Production Example
Here's a complete configuration from CarAPIS - a production automotive platform:
```python
class CarAPISConfig(DjangoConfig):
"""๐ CarAPIS Production Configuration"""
project_name: str = "CarAPIS"
project_version: str = "2.0.0"
# === 4 Production Databases ===
databases: Dict[str, DatabaseConnection] = {
"default": DatabaseConnection(
engine="django.db.backends.postgresql",
**env.database.parse_url(env.database.url),
connect_timeout=10,
sslmode="prefer",
),
"cars": DatabaseConnection(
**env.database.parse_url(env.database.url_cars),
),
"cars_new": DatabaseConnection(
**env.database.parse_url(env.database.url_cars_new),
),
"cars_server": DatabaseConnection(
**env.database.parse_url(env.database.url_cars_server),
),
}
# === Smart Database Routing ===
database_routing: List[DatabaseRoutingRule] = [
DatabaseRoutingRule(
apps=["parsers"],
database="cars",
operations=["read", "write"],
),
DatabaseRoutingRule(
apps=["customs"],
database="cars_new",
operations=["read", "write"],
),
]
# === Multi-Zone API ===
revolution: RevolutionConfig = RevolutionConfig(
api_prefix="apix",
drf_title="CarAPIS",
drf_description="Advanced Car Import/Export Platform API",
zones={
"client": ZoneConfig(
apps=["accounts", "billing", "payments"],
title="Client API",
public=True,
auth_required=False,
),
"internal": ZoneConfig(
apps=["mailer", "services"],
title="Internal API",
public=False,
auth_required=True,
),
"customs": ZoneConfig(
apps=["data_customs"],
title="Customs API",
description="Customs calculations",
public=True,
),
},
)
# === Beautiful Admin Dashboard ===
unfold: UnfoldConfig = UnfoldConfig(
theme=UnfoldTheme(
site_title="CarAPIS Admin",
site_header="CarAPIS",
site_subheader="Automotive Data Platform",
theme="auto",
dashboard_callback="api.dashboard.callbacks.main_dashboard_callback",
),
)
config = CarAPISConfig()
```
## ๐ง Environment Intelligence
Django-CFG automatically detects your environment and applies appropriate settings:
| Environment | Cache Backend | Email Backend | Database SSL | Debug Mode | Static Files |
|-------------|---------------|---------------|--------------|------------|--------------|
| **Development** | Memory/Redis | Console | Optional | True | Django Dev Server |
| **Testing** | Dummy Cache | In-Memory | Disabled | False | Static Files |
| **Staging** | Redis | SMTP | Required | False | WhiteNoise |
| **Production** | Redis | SMTP | Required | False | WhiteNoise |
## ๐ Built-in Integrations
### ๐จ Django Unfold Admin
Beautiful, modern admin interface with Tailwind CSS, dark mode, and dashboard widgets.
### ๐ Django Revolution API
Automatic API generation with OpenAPI/Swagger documentation and zone-based architecture.
### ๐ง Email & Notifications
SMTP, Telegram bot integration with environment-specific backends.
### ๐๏ธ Multi-Database Support
Smart database routing with connection pooling and SSL configuration.
### โก Redis Caching
Production-ready caching with separate cache backends for different use cases.
## ๐ Migration Guide
### Step 1: Install django-cfg
```bash
pip install django-cfg
```
### Step 2: Create YAML configuration
```yaml
# config.dev.yaml
secret_key: "your-secret-key"
debug: true
database:
url: "postgresql://user:pass@localhost:5432/mydb"
```
### Step 3: Create configuration class
```python
# config.py
from django_cfg import DjangoConfig
from .environment import env
class MyConfig(DjangoConfig):
project_name: str = "My Project"
secret_key: str = env.secret_key
debug: bool = env.debug
config = MyConfig()
```
### Step 4: Update settings.py
```python
# settings.py
from .config import config
globals().update(config.get_all_settings())
```
### Step 5: Test
```bash
python manage.py check
python manage.py runserver
```
## ๐งช Testing
Django-CFG includes comprehensive testing utilities:
```python
def test_my_config():
config = MyConfig()
settings = config.get_all_settings()
assert "SECRET_KEY" in settings
assert settings["DEBUG"] is False
assert "myapp" in settings["INSTALLED_APPS"]
assert "SPECTACULAR_SETTINGS" in settings
```
## ๐ Advanced Features
### Environment-Specific Configuration
```yaml
# config.prod.yaml
debug: false
database:
url: "${DATABASE_URL}"
redis_url: "${REDIS_URL}"
# config.dev.yaml
debug: true
database:
url: "postgresql://postgres:postgres@localhost:5432/myapp"
```
### Multi-Environment Support
```python
# Automatic environment detection
IS_DEV = os.environ.get("IS_DEV", "").lower() in ("true", "1", "yes")
IS_PROD = os.environ.get("IS_PROD", "").lower() in ("true", "1", "yes")
IS_TEST = "test" in sys.argv
```
### Custom Dashboard Callbacks
```python
def main_dashboard_callback(request, context):
"""Custom admin dashboard with real-time data"""
return [
{
"title": "System Status",
"metric": "98.5%",
"footer": "Uptime last 30 days",
},
{
"title": "Active Users",
"metric": "1,234",
"footer": "Online now",
},
]
```
## ๐ค Contributing
We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md).
### Development Setup
```bash
git clone https://github.com/markolofsen/django-cfg.git
cd django-cfg
poetry install
poetry run pytest
```
## ๐ License
MIT License - see [LICENSE](LICENSE) file for details.
## ๐ Acknowledgments
- **Django** - The web framework for perfectionists with deadlines
- **Pydantic** - Data validation using Python type hints
- **Django Unfold** - Beautiful admin interface
- **Django Revolution** - API generation and management
---
**Made with โค๏ธ by the UnrealOS Team**
*Django-CFG: Because configuration should be simple, safe, and powerful.*
Raw data
{
"_id": null,
"home_page": null,
"name": "django-cfg",
"maintainer": null,
"docs_url": null,
"requires_python": "<4.0,>=3.10",
"maintainer_email": "UnrealOS Team <dev@unrealos.com>",
"keywords": "configuration, developer-experience, django, pydantic, settings, type-safety",
"author": null,
"author_email": "UnrealOS Team <dev@unrealos.com>",
"download_url": "https://files.pythonhosted.org/packages/1e/d8/035b2b3a011e05aa676f2deb33b2de061ceeed9617da02df757f5e5aca35/django_cfg-1.1.1.tar.gz",
"platform": null,
"description": "# \ud83d\ude80 Django-CFG: Developer-First Django Configuration\n\n[](https://pypi.org/project/django-cfg/)\n[](https://pypi.org/project/django-cfg/)\n[](https://github.com/markolofsen/django-cfg/blob/main/LICENSE)\n[](https://pypi.org/project/django-cfg/)\n\n**Transform your Django configuration from 100+ lines of boilerplate to clean, type-safe YAML + Python configuration.**\n\nDjango-CFG is a revolutionary Django configuration system that provides developer-first experience through Pydantic v2 models, YAML configuration files, intelligent automation, and zero boilerplate.\n\n## \u2728 Key Features\n\n- \ud83c\udfaf **90% Less Boilerplate** - Replace massive `settings.py` with clean config classes\n- \ud83d\udd12 **100% Type Safety** - All configuration through Pydantic v2 models \n- \ud83d\udcc4 **YAML Configuration** - Environment-specific settings in readable YAML files\n- \ud83d\udeab **Zero Raw Dicts** - No more error-prone dictionary configurations\n- \ud83e\udde0 **Smart Defaults** - Environment-aware defaults (Redis for prod, Memory for dev)\n- \ud83d\udca1 **IDE Support** - Full autocomplete and validation in your IDE\n- \ud83c\udfa8 **Beautiful Admin** - Pre-configured Django Unfold with Tailwind CSS\n- \ud83d\udd04 **API Generation** - Automatic OpenAPI/Swagger with Django Revolution\n- \ud83d\udce6 **Easy Migration** - Gradual migration from existing Django projects\n\n## \ud83d\ude80 Quick Start\n\n### Installation\n\n```bash\npip install django-cfg\n```\n\n### Before (Traditional Django - 100+ lines)\n\n```python\n# settings.py - Traditional Django configuration \ud83d\ude22\nimport os\nfrom pathlib import Path\n\nBASE_DIR = Path(__file__).resolve().parent.parent\nSECRET_KEY = os.environ.get('SECRET_KEY', 'dev-key')\nDEBUG = os.environ.get('DEBUG', 'False') == 'True'\nALLOWED_HOSTS = ['localhost', '127.0.0.1']\n\nINSTALLED_APPS = [\n 'django.contrib.admin',\n 'django.contrib.auth',\n 'django.contrib.contenttypes',\n 'django.contrib.sessions',\n 'django.contrib.messages',\n 'django.contrib.staticfiles',\n 'rest_framework',\n 'drf_spectacular',\n 'corsheaders',\n 'myapp',\n]\n\nMIDDLEWARE = [\n 'corsheaders.middleware.CorsMiddleware',\n 'django.middleware.security.SecurityMiddleware',\n 'whitenoise.middleware.WhiteNoiseMiddleware',\n 'django.contrib.sessions.middleware.SessionMiddleware',\n 'django.middleware.common.CommonMiddleware',\n 'django.middleware.csrf.CsrfViewMiddleware',\n 'django.contrib.auth.middleware.AuthenticationMiddleware',\n 'django.contrib.messages.middleware.MessageMiddleware',\n 'django.middleware.clickjacking.XFrameOptionsMiddleware',\n]\n\nDATABASES = {\n 'default': {\n 'ENGINE': 'django.db.backends.postgresql',\n 'NAME': os.environ.get('DATABASE_NAME', 'mydb'),\n 'USER': os.environ.get('DATABASE_USER', 'postgres'),\n 'PASSWORD': os.environ.get('DATABASE_PASSWORD', ''),\n 'HOST': os.environ.get('DATABASE_HOST', 'localhost'),\n 'PORT': os.environ.get('DATABASE_PORT', '5432'),\n }\n}\n\nCACHES = {\n 'default': {\n 'BACKEND': 'django_redis.cache.RedisCache',\n 'LOCATION': os.environ.get('REDIS_URL', 'redis://localhost:6379/1'),\n 'OPTIONS': {\n 'CLIENT_CLASS': 'django_redis.client.DefaultClient',\n }\n }\n}\n\nREST_FRAMEWORK = {\n 'DEFAULT_SCHEMA_CLASS': 'drf_spectacular.openapi.AutoSchema',\n 'DEFAULT_AUTHENTICATION_CLASSES': [\n 'rest_framework.authentication.SessionAuthentication',\n 'rest_framework_simplejwt.authentication.JWTAuthentication',\n ],\n 'DEFAULT_PERMISSION_CLASSES': [\n 'rest_framework.permissions.IsAuthenticated',\n ],\n 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',\n 'PAGE_SIZE': 20\n}\n\nSPECTACULAR_SETTINGS = {\n 'TITLE': 'My API',\n 'DESCRIPTION': 'My API description',\n 'VERSION': '1.0.0',\n 'SERVE_INCLUDE_SCHEMA': False,\n}\n\n# ... 50+ more lines of configuration\n```\n\n### After (Django-CFG - Clean & Simple)\n\n#### 1. Environment Configuration (`config.dev.yaml`)\n\n```yaml\n# Development Environment Configuration\nsecret_key: \"django-insecure-550e8400-e29b-41d4-a716-446655440000-dev-key\"\ndebug: true\n\n# Database\ndatabase:\n url: \"postgresql://postgres:postgres@localhost:5432/myapp\"\n url_analytics: \"postgresql://postgres:postgres@localhost:5432/analytics\"\n\n# Application URLs\napp:\n name: \"MyApp\"\n domain: \"localhost\"\n api_url: \"http://localhost:8000\"\n site_url: \"http://localhost:3000\"\n\n# Email\nemail:\n backend: \"smtp\"\n host: \"smtp.gmail.com\"\n port: 587\n username: \"hello@myapp.com\"\n password: \"app-password\"\n use_tls: true\n default_from: \"MyApp <hello@myapp.com>\"\n\n# Telegram Bot\ntelegram:\n bot_token: \"your-bot-token\"\n group_id: -123456789\n\n# Cache\nredis_url: \"redis://localhost:6379/1\"\n```\n\n#### 2. Application Configuration (`config.py`)\n\n```python\nfrom typing import List, Dict\nfrom django_cfg import (\n DjangoConfig,\n DatabaseConnection,\n DatabaseRoutingRule,\n CacheBackend,\n UnfoldConfig,\n UnfoldTheme,\n RevolutionConfig,\n ZoneConfig,\n EmailConfig,\n TelegramConfig,\n)\nfrom .environment import env\n\n\nclass MyAppConfig(DjangoConfig):\n \"\"\"\ud83d\ude80 Complete production-ready configuration using django_cfg\"\"\"\n\n # === Project Information ===\n project_name: str = \"MyApp\"\n project_version: str = \"1.0.0\"\n site_url: str = env.app.site_url\n api_url: str = env.app.api_url\n\n # === Core Settings (from YAML) ===\n secret_key: str = env.secret_key\n debug: bool = env.debug\n\n # === Security ===\n security_domains: List[str] = [\n \"https://myapp.com\",\n \"https://api.myapp.com\",\n \"http://localhost:3000\", # Development\n \"http://localhost:8000\",\n ]\n\n # === Custom User Model ===\n auth_user_model: str = \"accounts.CustomUser\"\n\n # === Project Apps ===\n project_apps: List[str] = [\n \"accounts\",\n \"products\",\n \"orders\",\n \"analytics\",\n ]\n\n # === Multi-Database Setup ===\n databases: Dict[str, DatabaseConnection] = {\n \"default\": DatabaseConnection(\n engine=\"django.db.backends.postgresql\",\n **env.database.parse_url(env.database.url),\n connect_timeout=10,\n sslmode=\"prefer\",\n ),\n \"analytics\": DatabaseConnection(\n engine=\"django.db.backends.postgresql\",\n **env.database.parse_url(env.database.url_analytics),\n connect_timeout=10,\n sslmode=\"prefer\",\n ),\n }\n\n # === Database Routing ===\n database_routing: List[DatabaseRoutingRule] = [\n DatabaseRoutingRule(\n apps=[\"analytics\"],\n database=\"analytics\",\n operations=[\"read\", \"write\"],\n ),\n ]\n\n # === Redis Cache ===\n cache_default: CacheBackend = CacheBackend(\n redis_url=env.redis_url,\n timeout=300,\n )\n\n cache_sessions: CacheBackend = CacheBackend(\n redis_url=env.redis_url.replace(\"/1\", \"/2\"),\n timeout=1800, # 30 minutes\n )\n\n # === Email Configuration ===\n email: EmailConfig = EmailConfig(\n host=env.email.host,\n port=env.email.port,\n username=env.email.username,\n password=env.email.password,\n use_tls=env.email.use_tls,\n default_from_email=env.email.default_from,\n )\n\n # === Telegram Notifications ===\n telegram: TelegramConfig = TelegramConfig(\n bot_token=env.telegram.bot_token,\n chat_id=env.telegram.group_id,\n parse_mode=\"HTML\",\n )\n\n # === Beautiful Admin Interface ===\n unfold: UnfoldConfig = UnfoldConfig(\n theme=UnfoldTheme(\n site_title=\"MyApp Admin\",\n site_header=\"MyApp\",\n site_subheader=\"Management Dashboard\",\n theme=\"auto\", # Auto light/dark theme\n dashboard_callback=\"myapp.dashboard.main_callback\",\n ),\n )\n\n # === API Configuration with Revolution ===\n revolution: RevolutionConfig = RevolutionConfig(\n api_prefix=\"api\",\n drf_title=\"MyApp API\",\n drf_description=\"RESTful API with automatic OpenAPI generation\",\n drf_version=\"1.0.0\",\n zones={\n \"public\": ZoneConfig(\n apps=[\"products\"],\n title=\"Public API\",\n description=\"Public product catalog\",\n public=True,\n auth_required=False,\n ),\n \"client\": ZoneConfig(\n apps=[\"accounts\", \"orders\"],\n title=\"Client API\",\n description=\"User accounts and orders\",\n public=True,\n auth_required=True,\n ),\n \"admin\": ZoneConfig(\n apps=[\"analytics\"],\n title=\"Admin API\",\n description=\"Analytics and reporting\",\n public=False,\n auth_required=True,\n ),\n },\n )\n\n\n# Initialize configuration\nconfig = MyAppConfig()\n```\n\n#### 3. Django Settings (`settings.py`) - Just 3 Lines!\n\n```python\n\"\"\"Ultra-minimal settings powered by django_cfg\"\"\"\n\nfrom .config import config\n\n# Apply ALL Django settings from django_cfg\nglobals().update(config.get_all_settings())\n```\n\n## \ud83d\udca1 What You Get Automatically\n\n\u2705 **All Django core apps and middleware configured** \n\u2705 **Environment detection (dev/prod/test/staging)** \n\u2705 **Smart cache backend selection (Redis/Memory)** \n\u2705 **Security settings based on your domains** \n\u2705 **Complete type safety and validation** \n\u2705 **Beautiful Django Unfold admin with Tailwind CSS** \n\u2705 **Automatic OpenAPI/Swagger documentation** \n\u2705 **Multi-database routing** \n\u2705 **Session management** \n\u2705 **CORS configuration** \n\u2705 **Static files with WhiteNoise** \n\u2705 **Email and Telegram notifications**\n\n## \ud83c\udfd7\ufe0f Real-World Production Example\n\nHere's a complete configuration from CarAPIS - a production automotive platform:\n\n```python\nclass CarAPISConfig(DjangoConfig):\n \"\"\"\ud83d\ude80 CarAPIS Production Configuration\"\"\"\n\n project_name: str = \"CarAPIS\"\n project_version: str = \"2.0.0\"\n \n # === 4 Production Databases ===\n databases: Dict[str, DatabaseConnection] = {\n \"default\": DatabaseConnection(\n engine=\"django.db.backends.postgresql\",\n **env.database.parse_url(env.database.url),\n connect_timeout=10,\n sslmode=\"prefer\",\n ),\n \"cars\": DatabaseConnection(\n **env.database.parse_url(env.database.url_cars),\n ),\n \"cars_new\": DatabaseConnection(\n **env.database.parse_url(env.database.url_cars_new),\n ),\n \"cars_server\": DatabaseConnection(\n **env.database.parse_url(env.database.url_cars_server),\n ),\n }\n\n # === Smart Database Routing ===\n database_routing: List[DatabaseRoutingRule] = [\n DatabaseRoutingRule(\n apps=[\"parsers\"],\n database=\"cars\",\n operations=[\"read\", \"write\"],\n ),\n DatabaseRoutingRule(\n apps=[\"customs\"],\n database=\"cars_new\",\n operations=[\"read\", \"write\"],\n ),\n ]\n\n # === Multi-Zone API ===\n revolution: RevolutionConfig = RevolutionConfig(\n api_prefix=\"apix\",\n drf_title=\"CarAPIS\",\n drf_description=\"Advanced Car Import/Export Platform API\",\n zones={\n \"client\": ZoneConfig(\n apps=[\"accounts\", \"billing\", \"payments\"],\n title=\"Client API\",\n public=True,\n auth_required=False,\n ),\n \"internal\": ZoneConfig(\n apps=[\"mailer\", \"services\"],\n title=\"Internal API\",\n public=False,\n auth_required=True,\n ),\n \"customs\": ZoneConfig(\n apps=[\"data_customs\"],\n title=\"Customs API\",\n description=\"Customs calculations\",\n public=True,\n ),\n },\n )\n\n # === Beautiful Admin Dashboard ===\n unfold: UnfoldConfig = UnfoldConfig(\n theme=UnfoldTheme(\n site_title=\"CarAPIS Admin\",\n site_header=\"CarAPIS\",\n site_subheader=\"Automotive Data Platform\",\n theme=\"auto\",\n dashboard_callback=\"api.dashboard.callbacks.main_dashboard_callback\",\n ),\n )\n\nconfig = CarAPISConfig()\n```\n\n## \ud83d\udd27 Environment Intelligence\n\nDjango-CFG automatically detects your environment and applies appropriate settings:\n\n| Environment | Cache Backend | Email Backend | Database SSL | Debug Mode | Static Files |\n|-------------|---------------|---------------|--------------|------------|--------------|\n| **Development** | Memory/Redis | Console | Optional | True | Django Dev Server |\n| **Testing** | Dummy Cache | In-Memory | Disabled | False | Static Files |\n| **Staging** | Redis | SMTP | Required | False | WhiteNoise |\n| **Production** | Redis | SMTP | Required | False | WhiteNoise |\n\n## \ud83d\udcca Built-in Integrations\n\n### \ud83c\udfa8 Django Unfold Admin\nBeautiful, modern admin interface with Tailwind CSS, dark mode, and dashboard widgets.\n\n### \ud83d\udd04 Django Revolution API\nAutomatic API generation with OpenAPI/Swagger documentation and zone-based architecture.\n\n### \ud83d\udce7 Email & Notifications\nSMTP, Telegram bot integration with environment-specific backends.\n\n### \ud83d\uddc4\ufe0f Multi-Database Support\nSmart database routing with connection pooling and SSL configuration.\n\n### \u26a1 Redis Caching\nProduction-ready caching with separate cache backends for different use cases.\n\n## \ud83d\udd04 Migration Guide\n\n### Step 1: Install django-cfg\n```bash\npip install django-cfg\n```\n\n### Step 2: Create YAML configuration\n```yaml\n# config.dev.yaml\nsecret_key: \"your-secret-key\"\ndebug: true\ndatabase:\n url: \"postgresql://user:pass@localhost:5432/mydb\"\n```\n\n### Step 3: Create configuration class\n```python\n# config.py\nfrom django_cfg import DjangoConfig\nfrom .environment import env\n\nclass MyConfig(DjangoConfig):\n project_name: str = \"My Project\"\n secret_key: str = env.secret_key\n debug: bool = env.debug\n\nconfig = MyConfig()\n```\n\n### Step 4: Update settings.py\n```python\n# settings.py\nfrom .config import config\nglobals().update(config.get_all_settings())\n```\n\n### Step 5: Test\n```bash\npython manage.py check\npython manage.py runserver\n```\n\n## \ud83e\uddea Testing\n\nDjango-CFG includes comprehensive testing utilities:\n\n```python\ndef test_my_config():\n config = MyConfig()\n settings = config.get_all_settings()\n \n assert \"SECRET_KEY\" in settings\n assert settings[\"DEBUG\"] is False\n assert \"myapp\" in settings[\"INSTALLED_APPS\"]\n assert \"SPECTACULAR_SETTINGS\" in settings\n```\n\n## \ud83d\udcda Advanced Features\n\n### Environment-Specific Configuration\n```yaml\n# config.prod.yaml\ndebug: false\ndatabase:\n url: \"${DATABASE_URL}\"\nredis_url: \"${REDIS_URL}\"\n\n# config.dev.yaml \ndebug: true\ndatabase:\n url: \"postgresql://postgres:postgres@localhost:5432/myapp\"\n```\n\n### Multi-Environment Support\n```python\n# Automatic environment detection\nIS_DEV = os.environ.get(\"IS_DEV\", \"\").lower() in (\"true\", \"1\", \"yes\")\nIS_PROD = os.environ.get(\"IS_PROD\", \"\").lower() in (\"true\", \"1\", \"yes\")\nIS_TEST = \"test\" in sys.argv\n```\n\n### Custom Dashboard Callbacks\n```python\ndef main_dashboard_callback(request, context):\n \"\"\"Custom admin dashboard with real-time data\"\"\"\n return [\n {\n \"title\": \"System Status\",\n \"metric\": \"98.5%\",\n \"footer\": \"Uptime last 30 days\",\n },\n {\n \"title\": \"Active Users\", \n \"metric\": \"1,234\",\n \"footer\": \"Online now\",\n },\n ]\n```\n\n## \ud83e\udd1d Contributing\n\nWe welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md).\n\n### Development Setup\n\n```bash\ngit clone https://github.com/markolofsen/django-cfg.git\ncd django-cfg\npoetry install\npoetry run pytest\n```\n\n## \ud83d\udcc4 License\n\nMIT License - see [LICENSE](LICENSE) file for details.\n\n## \ud83d\ude4f Acknowledgments\n\n- **Django** - The web framework for perfectionists with deadlines\n- **Pydantic** - Data validation using Python type hints \n- **Django Unfold** - Beautiful admin interface\n- **Django Revolution** - API generation and management\n\n---\n\n**Made with \u2764\ufe0f by the UnrealOS Team**\n\n*Django-CFG: Because configuration should be simple, safe, and powerful.*\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Developer-first Django configuration with Pydantic v2 models and intelligent automation (Django 4.2+ required)",
"version": "1.1.1",
"project_urls": {
"Changelog": "https://github.com/markolofsen/django-cfg/blob/main/CHANGELOG.md",
"Documentation": "https://django-cfg.readthedocs.io",
"Homepage": "https://github.com/markolofsen/django-cfg",
"Issues": "https://github.com/markolofsen/django-cfg/issues",
"Repository": "https://github.com/markolofsen/django-cfg.git"
},
"split_keywords": [
"configuration",
" developer-experience",
" django",
" pydantic",
" settings",
" type-safety"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "08a3929ecfb668721ea4f2e209f35ec0d47d7765aa5ae8b9e41029d219399ddb",
"md5": "410423cab6f837a9cb6e9c5e7b80515f",
"sha256": "15128fac22cc4751918e932bf7f72df63c0cc4b08112952568b01bf8d7434876"
},
"downloads": -1,
"filename": "django_cfg-1.1.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "410423cab6f837a9cb6e9c5e7b80515f",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": "<4.0,>=3.10",
"size": 143696,
"upload_time": "2025-08-22T05:30:05",
"upload_time_iso_8601": "2025-08-22T05:30:05.361678Z",
"url": "https://files.pythonhosted.org/packages/08/a3/929ecfb668721ea4f2e209f35ec0d47d7765aa5ae8b9e41029d219399ddb/django_cfg-1.1.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "1ed8035b2b3a011e05aa676f2deb33b2de061ceeed9617da02df757f5e5aca35",
"md5": "279d1856b4a74d77a861177d741d75da",
"sha256": "ccfe0283ab78c4d799edde270d9cd3c9a5e3c9dbf10d7985dfbc0bdb5b494bea"
},
"downloads": -1,
"filename": "django_cfg-1.1.1.tar.gz",
"has_sig": false,
"md5_digest": "279d1856b4a74d77a861177d741d75da",
"packagetype": "sdist",
"python_version": "source",
"requires_python": "<4.0,>=3.10",
"size": 107775,
"upload_time": "2025-08-22T05:30:07",
"upload_time_iso_8601": "2025-08-22T05:30:07.285331Z",
"url": "https://files.pythonhosted.org/packages/1e/d8/035b2b3a011e05aa676f2deb33b2de061ceeed9617da02df757f5e5aca35/django_cfg-1.1.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-08-22 05:30:07",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "markolofsen",
"github_project": "django-cfg",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"requirements": [
{
"name": "PyYAML",
"specs": [
[
">=",
"6.0"
]
]
},
{
"name": "cachetools",
"specs": [
[
">=",
"6.1.0"
]
]
},
{
"name": "click",
"specs": [
[
">=",
"8.2.0"
]
]
},
{
"name": "colorlog",
"specs": [
[
">=",
"6.9.0"
]
]
},
{
"name": "dj-database-url",
"specs": [
[
">=",
"3.0.0"
]
]
},
{
"name": "django-constance",
"specs": [
[
">=",
"4.3.2"
]
]
},
{
"name": "django-cors-headers",
"specs": [
[
">=",
"4.7.0"
]
]
},
{
"name": "django-extensions",
"specs": [
[
">=",
"4.1"
]
]
},
{
"name": "django-filter",
"specs": [
[
">=",
"25.0"
]
]
},
{
"name": "django-json-widget",
"specs": [
[
">=",
"2.0.3"
]
]
},
{
"name": "django-redis",
"specs": [
[
">=",
"6.0.0"
]
]
},
{
"name": "django-revolution",
"specs": [
[
">=",
"1.0.30"
]
]
},
{
"name": "django-unfold",
"specs": [
[
">=",
"0.64.0"
]
]
},
{
"name": "djangorestframework-simplejwt",
"specs": [
[
">=",
"5.5.0"
]
]
},
{
"name": "djangorestframework-simplejwt",
"specs": [
[
">=",
"5.5.0"
]
]
},
{
"name": "djangorestframework",
"specs": [
[
">=",
"3.16.0"
]
]
},
{
"name": "drf-nested-routers",
"specs": [
[
">=",
"0.94.2"
]
]
},
{
"name": "drf-spectacular-sidecar",
"specs": [
[
">=",
"2025.8.1"
]
]
},
{
"name": "drf-spectacular",
"specs": [
[
">=",
"0.28.0"
]
]
},
{
"name": "hiredis",
"specs": [
[
">=",
"2.0.0"
]
]
},
{
"name": "loguru",
"specs": [
[
">=",
"0.7.0"
]
]
},
{
"name": "psycopg2-binary",
"specs": [
[
">=",
"2.9.0"
]
]
},
{
"name": "pyTelegramBotAPI",
"specs": [
[
">=",
"4.28.0"
]
]
},
{
"name": "pydantic-yaml",
"specs": [
[
">=",
"1.6.0"
]
]
},
{
"name": "pydantic",
"specs": [
[
">=",
"2.11"
],
[
"<",
"3.0"
]
]
},
{
"name": "pydantic",
"specs": [
[
">=",
"2.11"
],
[
"<",
"3.0"
]
]
},
{
"name": "questionary",
"specs": [
[
">=",
"2.1.0"
]
]
},
{
"name": "redis",
"specs": [
[
">=",
"5.0.0"
]
]
},
{
"name": "rich",
"specs": [
[
">=",
"14.1.0"
]
]
},
{
"name": "whitenoise",
"specs": [
[
">=",
"6.8.0"
]
]
}
],
"lcname": "django-cfg"
}