Extensions
New in Django-CFG 2.0 Extensions are self-contained, auto-discovered Django apps that simplify your configuration and enable code reuse across projects.
What are Extensions?
Extensions are modular Django applications that configure and register themselves automatically. Instead of managing everything in your main DjangoConfig, extensions live in their own directories and integrate seamlessly with your project.
The Problem Extensions Solve
Before Extensions (Legacy):
# api/config.py - Everything in one massive file ❌
class MyProjectConfig(DjangoConfig):
# Payment processing config
payments: PaymentsConfig = PaymentsConfig(
crypto_api_key="...",
crypto_webhook_secret="...",
enabled=True
)
# Lead management config
leads: LeadsConfig = LeadsConfig(
telegram_enabled=True,
email_enabled=True
)
# Support system config
support: SupportConfig = SupportConfig(
ticket_auto_assign=True,
sla_hours=24
)
# Manual app registration
project_apps: list[str] = [
"extensions.apps.payments",
"extensions.apps.leads",
"extensions.apps.support",
]
# Manual middleware
custom_middleware: list[str] = [
"extensions.apps.payments.middleware.PaymentMiddleware",
]After Extensions (Modern):
# api/config.py - Clean and focused ✅
class MyProjectConfig(DjangoConfig):
# Only core Django configuration
project_name: str = "My SaaS Platform"
secret_key: str = env.secret_key
databases: Dict[str, DatabaseConfig] = {
"default": DatabaseConfig.from_url(url=env.database.url)
}
# Your custom project apps (not extensions)
project_apps: list[str] = ["core", "apps.profiles"]
# Extensions are auto-discovered! ✨# extensions/apps/payments/__cfg__.py - Self-contained ✅
from django_cfg.extensions.configs.apps import BaseExtensionSettings
class PaymentsSettings(BaseExtensionSettings):
enabled: bool = True
crypto_api_key: str = env.payments.api_key
settings = PaymentsSettings() # This line enables the extension!Key Benefits
1. Separation of Concerns
Each extension manages its own configuration, keeping your main DjangoConfig small and focused.
2. Auto-Discovery
Extensions automatically register themselves - no manual INSTALLED_APPS or URL pattern configuration needed.
3. Reusability
Create an extension once, use it across multiple projects. Share extensions with your team or the community.
4. Type Safety
Full Pydantic validation for all extension settings, catching configuration errors before runtime.
5. Easy Customization
Override base extension settings in your project without modifying the extension code.
Extension Types
Django-CFG supports two types of extensions:
App Extensions
Full Django applications with models, views, and database migrations.
Examples:
payments- Payment processing (Stripe, crypto providers)leads- Lead management and contact formssupport- Support ticket systemnewsletter- Email campaign managementknowbase- Knowledge base articles
Location: extensions/apps/{name}/
Module Extensions
Utility modules without database models, providing reusable functionality.
Examples:
currency- Currency conversion utilitiesanalytics- Analytics helperstelegram- Telegram bot utilities
Location: extensions/modules/{name}/
Backend vs Frontend Extensions
Django-CFG features a dual-layer extension architecture:
Backend Extensions (Django)
Python-based Django apps that provide REST APIs, database models, and business logic.
Created with: __cfg__.py configuration file
Learn more: Backend Extensions Guide
Frontend Extensions (TypeScript/React)
npm packages that provide React components, TypeScript API clients, and UI widgets.
Created with: @djangocfg/ext-base CLI
Learn more: Frontend Extensions Guide
Extension Lifecycle
1. Create
Generate a new extension with the CLI or manually create the directory structure.
# Backend extension
mkdir -p extensions/apps/my-extension# Frontend extension
pnpm dlx @djangocfg/ext-base create2. Configure
Add a __cfg__.py file to enable and configure the extension.
# extensions/apps/my-extension/__cfg__.py
from django_cfg.extensions.configs.apps.base import BaseExtensionSettings
class MyExtensionSettings(BaseExtensionSettings):
name = "my-extension"
version = "1.0.0"
description = "My awesome extension"
settings = MyExtensionSettings() # Enable it!3. Develop
Add models, views, admin, URLs, and other Django components.
extensions/apps/my-extension/
├── __cfg__.py # Configuration (required)
├── apps.py # Django AppConfig
├── models.py # Database models
├── admin.py # Admin interface
├── urls.py # Routes → /cfg/my-extension/
├── views.py # ViewSets and views
└── migrations/ # Database migrations4. Use
The extension auto-registers and is immediately available in your project.
# URLs automatically available
curl http://localhost:8000/cfg/my-extension/api/
# Admin navigation appears automatically
# Middleware registers automatically
# Background tasks schedule automaticallyWhen to Use Extensions
✅ Use Extensions For:
- Reusable functionality that could be shared across projects
- Self-contained features with their own models and APIs
- Third-party integrations (payments, CRM, support)
- Optional features that can be enabled/disabled
- Marketplace-ready packages for distribution
❌ Use Project Apps For:
- Core business logic specific to your project
- One-off features that won’t be reused
- Tightly coupled components that depend on project structure
- Prototype features still in heavy development
Quick Start Example
Let’s create a simple “Analytics” extension:
Step 1: Create Directory
mkdir -p extensions/apps/analytics
touch extensions/apps/analytics/__cfg__.pyStep 2: Configure Extension
# extensions/apps/analytics/__cfg__.py
from django_cfg.extensions.configs.apps.base import (
BaseExtensionSettings,
NavigationSection,
NavigationItem,
)
class AnalyticsSettings(BaseExtensionSettings):
# Manifest
name: str = "analytics"
version: str = "1.0.0"
description: str = "Analytics tracking and dashboards"
author: str = "My Team"
# Django integration
django_app_label: str = "analytics" # Becomes "cfg_analytics"
url_prefix: str = "analytics" # URLs at /cfg/analytics/
# Features
admin_enabled: bool = True
has_migrations: bool = True
# Google Analytics config
ga_tracking_id: str = "UA-XXXXX-Y"
# Admin navigation
navigation = NavigationSection(
title="Analytics",
icon="analytics",
items=[
NavigationItem(
title="Dashboard",
app="analytics",
model="pageview",
),
],
)
settings = AnalyticsSettings()Step 3: Add Django App Files
# extensions/apps/analytics/apps.py
from django.apps import AppConfig
from .__cfg__ import settings
class AnalyticsConfig(AppConfig):
default_auto_field = "django.db.models.BigAutoField"
name = "extensions.apps.analytics"
label = settings.full_app_label # "cfg_analytics"
verbose_name = "Analytics"# extensions/apps/analytics/models.py
from django.db import models
class PageView(models.Model):
url = models.CharField(max_length=500)
timestamp = models.DateTimeField(auto_now_add=True)
user_agent = models.TextField()
class Meta:
ordering = ["-timestamp"]Step 4: Run Migrations
python manage.py makemigrations cfg_analytics
python manage.py migrateStep 5: It Just Works! ✨
- ✅ App added to
INSTALLED_APPSautomatically - ✅ URLs available at
/cfg/analytics/ - ✅ Admin navigation appears in sidebar
- ✅ Models ready to use
- ✅ No manual configuration needed!
Extension Auto-Discovery
Extensions are discovered automatically by scanning:
extensions/apps/- App extensions (with models)extensions/modules/- Module extensions (utilities)
Requirements:
- Directory must contain
__cfg__.pyfile - File must have a
settingsvariable settingsmust be an instance ofBaseExtensionSettingsorBaseModuleSettings
Discovery happens at Django startup, so new extensions are available immediately after creating __cfg__.py.
Extension Features
Extensions can include:
🎨 Admin UI
- Custom admin navigation with icons
- Admin views and actions
- Custom admin templates
🔗 URL Routing
- Automatic URL registration
- Convention-based patterns:
urls.py→/cfg/{prefix}/urls_admin.py→/cfg/{prefix}/admin/urls_system.py→/cfg/{prefix}/system/
⚙️ Dynamic Settings
- Runtime configuration with Constance
- Settings editable in admin
- Type-safe field definitions
📅 Scheduled Tasks
- Background job scheduling with Django-RQ
- Cron and interval schedules
- Task monitoring in admin
🔌 Middleware
- Custom middleware auto-inserted
- Correct ordering guaranteed
- Per-extension middleware isolation
📦 Dependencies
- Declare required extensions
- Specify pip package requirements
- Automatic dependency checking
Next Steps
Examples
Simple Extension (No Database)
# extensions/modules/django-currency/__cfg__.py
from django_cfg.extensions.configs.modules.base import BaseModuleSettings
class CurrencySettings(BaseModuleSettings):
name = "currency"
version = "1.0.0"
# Exchange rate API
api_key: str = env.currency.api_key
settings = CurrencySettings()Extension with Dependencies
# extensions/apps/crm/__cfg__.py
class CRMSettings(BaseExtensionSettings):
name = "crm"
# Requires other extensions
requires = ["leads", "support"]
# Requires pip packages
pip_requires = ["salesforce-api>=2.0"]
settings = CRMSettings()Extension with Scheduled Tasks
# extensions/apps/backup/__cfg__.py
from django_cfg.extensions.configs.apps import BaseExtensionSettings
from django_cfg.extensions.configs.apps.base import ExtensionScheduleConfig
class BackupSettings(BaseExtensionSettings):
schedules = [
ExtensionScheduleConfig(
func="extensions.apps.backup.tasks.daily_backup",
schedule_type="interval",
interval=86400, # 24 hours
description="Daily database backup",
),
]
settings = BackupSettings()Community Extensions
Coming Soon: Extension Marketplace Discover, install, and share extensions with the Django-CFG community.
Browse available extensions in the the django-cfg repo or create your own!
FAQ
Q: What’s the difference between extensions and project apps?
Extensions are reusable, self-contained features that could be shared across projects. They use the cfg_ namespace and auto-register themselves.
Project apps are your custom business logic specific to one project. They’re listed in project_apps and use your own naming.
Q: Can I have both backend and frontend extensions?
Yes! Most extensions have both:
- Backend extension provides the API
- Frontend extension provides the UI components
- They work together seamlessly
Q: Do I need to register extensions in INSTALLED_APPS?
No! Extensions auto-register themselves when you add settings = ExtensionSettings() to __cfg__.py.
Q: Can I disable an extension temporarily?
Yes, either:
- Remove/comment out the
settings = ...line in__cfg__.py - Set
enabled: bool = Falsein extension settings
Q: Can extensions depend on each other?
Yes! Use the requires: list[str] field in extension settings to declare dependencies.
Ready to build your first extension? Check out the Backend Extensions Guide for a step-by-step tutorial!