Migration Guide
Migrate your existing Django project to Django-CFG and unlock type-safe configuration, modern admin interface, and powerful built-in features.
โ ๏ธ Note: This guide uses simplified examples. For production, use YAML-based configuration as shown in Configuration Guide and First Project.
Migration Strategiesโ
Choose the migration approach that best fits your project:
Option 1: Fresh Start (Recommended)โ
Best for: New features, major refactoring, or when you want all Django-CFG benefits immediately.
Pros:
- โ Get all Django-CFG features instantly
- โ Clean, modern project structure
- โ No legacy configuration issues
- โ Built-in best practices
Cons:
- โ ๏ธ Requires data migration
- โ ๏ธ More initial work
Option 2: Gradual Migrationโ
Best for: Large existing projects, production systems, or when you need minimal disruption.
Pros:
- โ Minimal disruption to existing code
- โ Gradual feature adoption
- โ Keep existing data and structure
- โ Lower risk
Cons:
- โ ๏ธ Slower to get full benefits
- โ ๏ธ May have configuration conflicts
Option 3: Side-by-Side Comparisonโ
Best for: Learning Django-CFG, evaluating features, or planning a migration.
Pros:
- โ No risk to existing project
- โ Perfect for learning
- โ Easy feature comparison
- โ Can cherry-pick features
Cons:
- โ ๏ธ Doesn't migrate existing project
- โ ๏ธ Requires maintaining two codebases
Option 1: Fresh Start Migrationโ
Step 1: Create New Django-CFG Projectโ
# Create new project with Django-CFG
django-cfg create-project "My Migrated Project"
cd my-migrated-project
Step 2: Export Data from Old Projectโ
# In your old project directory
python manage.py dumpdata --natural-foreign --natural-primary > data_export.json
# Export specific apps (recommended)
python manage.py dumpdata auth.User > users.json
python manage.py dumpdata myapp > myapp_data.json
Step 3: Copy Your Appsโ
# Copy your custom apps to new project
cp -r /path/to/old/project/myapp ./
cp -r /path/to/old/project/anotherapp ./
Step 4: Update Configurationโ
# config.py in new project
from django_cfg import DjangoConfig, DatabaseConfig
class MyConfig(DjangoConfig):
project_name: str = "My Migrated Project"
secret_key: str = "<from-yaml-config>" # Set via environment/config.yaml
debug: bool = False
# Add your custom apps
project_apps: list[str] = [
"myapp",
"anotherapp",
]
# Copy database settings from old project
databases: dict[str, DatabaseConfig] = {
"default": DatabaseConfig(
engine="django.db.backends.postgresql",
name="<from-yaml-config>" # Set via environment/config.yaml,
user="<from-yaml-config>" # Set via environment/config.yaml,
password="<from-yaml-config>" # Set via environment/config.yaml,
host="<from-yaml-config>" # Set via environment/config.yaml,
port=5432,
)
}
config = MyConfig()
Step 5: Import Dataโ
# Run migrations first
python manage.py migrate
# Import your data
python manage.py loaddata users.json
python manage.py loaddata myapp_data.json
Step 6: Test and Verifyโ
# Validate configuration
python manage.py validate_config
# Test your app
python manage.py runserver
# Check admin interface
python manage.py createsuperuser
# Visit http://localhost:8000/admin/
Option 2: Gradual Migrationโ
Step 1: Install Django-CFGโ
# In your existing project
pip install django-cfg
Step 2: Create Configuration Classโ
Create config.py in your project root:
# config.py
from django_cfg import DjangoConfig
from typing import List
class MyConfig(DjangoConfig):
"""Gradual migration configuration"""
# Copy existing settings with type hints
project_name: str = "Existing Project"
secret_key: str = "your-existing-secret-key" # Copy from old settings
debug: bool = True # Copy from old settings
# Copy your INSTALLED_APPS
project_apps: List[str] = [
"myapp",
"anotherapp",
# ... your existing apps
]
# Copy database configuration
# (Convert your existing DATABASES setting)
config = MyConfig()
Step 3: Backup Current Settingsโ
# Backup your current settings
cp settings.py settings_backup.py
Step 4: Replace Settings Fileโ
# settings.py
from config import config
# Import all Django-CFG generated settings
globals().update(config.get_all_settings())
# Keep any custom settings that Django-CFG doesn't handle
CUSTOM_SETTING = "custom_value"
THIRD_PARTY_SETTING = "third_party_value"
# Temporarily keep old settings that you haven't migrated yet
# TODO: Migrate these to config.py
# OLD_SETTING = "old_value"
Step 5: Test Migrationโ
# Test that everything still works
python manage.py check
python manage.py runserver
Step 6: Gradual Feature Adoptionโ
Enable Django-CFG features one by one:
# config.py - Add features gradually
from django_cfg import DjangoConfig, UnfoldConfig, SpectacularConfig
class MyConfig(DjangoConfig):
# ... existing settings ...
# Week 1: Enable beautiful admin
unfold: UnfoldConfig | None = UnfoldConfig()
# Week 2: Enable API documentation
spectacular: SpectacularConfig | None = SpectacularConfig()
# Week 3: Enable built-in modules
enable_support: bool = True
enable_accounts: bool = True
# Week 4: Enable advanced features
enable_newsletter: bool = True
enable_leads: bool = True
Step 7: Clean Up Old Settingsโ
Remove old settings from settings.py as you migrate them to config.py:
# settings.py - Keep getting smaller
from config import config
globals().update(config.get_all_settings())
# Only custom settings remain
CUSTOM_MIDDLEWARE = ["myapp.middleware.CustomMiddleware"]
Option 3: Side-by-Side Comparisonโ
Step 1: Create Reference Projectโ
# Create Django-CFG project for comparison
mkdir django-cfg-reference
cd django-cfg-reference
django-cfg create-project "Reference Project"
Step 2: Compare Configurationsโ
# Compare your old settings.py with config.py
# Look for patterns and improvements
# Old settings.py (500+ lines)
DEBUG = True
SECRET_KEY = "..."
DATABASES = {
"default": {
"ENGINE": "django.db.backends.postgresql",
# ... lots of configuration
}
}
# ... 400+ more lines
# New config.py (50 lines)
class MyConfig(DjangoConfig):
debug: bool = True
secret_key: str = "<from-yaml-config>" # Set via environment/config.yaml
databases: dict[str, DatabaseConfig] = {
"default": DatabaseConfig(
engine="django.db.backends.postgresql",
name="<from-yaml-config>" # Set via environment/config.yaml,
# ... type-safe configuration
)
}
Step 3: Feature Comparisonโ
Test Django-CFG features in the reference project:
# Test admin interface
python manage.py runserver
# Visit http://localhost:8000/admin/
# Test API documentation
# Visit http://localhost:8000/api/docs/
# Test CLI commands
python manage.py info
python manage.py validate_config
Step 4: Plan Migrationโ
Create a migration plan based on your comparison:
# Migration Plan
## Phase 1: Core Configuration (Week 1)
- [ ] Convert settings.py to config.py
- [ ] Add type hints to all settings
- [ ] Test basic functionality
## Phase 2: Admin Interface (Week 2)
- [ ] Enable Unfold admin
- [ ] Customize admin interface
- [ ] Train team on new admin
## Phase 3: API Features (Week 3)
- [ ] Enable API documentation
- [ ] Set up API zones
- [ ] Generate API clients
## Phase 4: Built-in Modules (Week 4)
- [ ] Enable support system
- [ ] Enable user management
- [ ] Enable newsletter system
Common Migration Patternsโ
From django-environโ
# Old (django-environ)
import environ
env = environ.Env()
DEBUG = env.bool('DEBUG', default=False)
SECRET_KEY = env('SECRET_KEY')
DATABASE_URL = env('DATABASE_URL')
# New (Django-CFG)
from django_cfg import DjangoConfig
class MyConfig(DjangoConfig):
debug: bool = False
secret_key: str = "<from-yaml-config>" # Set via environment/config.yaml
database_url: str = "<from-yaml-config>" # Set via environment/config.yaml
From python-decoupleโ
# Old (python-decouple)
from decouple import config
DEBUG = config('DEBUG', default=False, cast=bool)
SECRET_KEY = config('SECRET_KEY')
ALLOWED_HOSTS = config('ALLOWED_HOSTS', cast=lambda v: [s.strip() for s in v.split(',')])
# New (Django-CFG)
from django_cfg import DjangoConfig
from typing import List
class MyConfig(DjangoConfig):
debug: bool = False
secret_key: str = "<from-yaml-config>" # Set via environment/config.yaml
security_domains: List[str] = ["myapp.com"] # Auto-generates ALLOWED_HOSTS, CORS, SSL
From django-configurationsโ
# Old (django-configurations)
from configurations import Configuration
class Development(Configuration):
DEBUG = True
SECRET_KEY = 'dev-key'
# New (Django-CFG)
from django_cfg import DjangoConfig
from .environment import env
class MyConfig(DjangoConfig):
debug: bool = True
secret_key: str = env.secret_key # Loaded from config.yaml
Complex Database Configurationโ
# Old settings.py
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': os.environ.get('DB_NAME'),
'USER': os.environ.get('DB_USER'),
'PASSWORD': os.environ.get('DB_PASSWORD'),
'HOST': os.environ.get('DB_HOST', 'localhost'),
'PORT': os.environ.get('DB_PORT', '5432'),
'OPTIONS': {
'sslmode': 'require',
},
},
'analytics': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': os.environ.get('ANALYTICS_DB_NAME'),
'USER': os.environ.get('ANALYTICS_DB_USER'),
'PASSWORD': os.environ.get('ANALYTICS_DB_PASSWORD'),
'HOST': os.environ.get('ANALYTICS_DB_HOST'),
'PORT': '5432',
}
}
# New config.py
from django_cfg import DjangoConfig
from django_cfg.models import DatabaseConfig
class MyConfig(DjangoConfig):
databases: dict[str, DatabaseConfig] = {
"default": DatabaseConfig(
engine="django.db.backends.postgresql",
name="<from-yaml-config>" # Set via environment/config.yaml,
user="<from-yaml-config>" # Set via environment/config.yaml,
password="<from-yaml-config>" # Set via environment/config.yaml,
host="${DB_HOST:localhost}",
port=5432,
sslmode="require",
),
"analytics": DatabaseConfig(
engine="django.db.backends.postgresql",
name="<from-yaml-config>" # Set via environment/config.yaml,
user="<from-yaml-config>" # Set via environment/config.yaml,
password="<from-yaml-config>" # Set via environment/config.yaml,
host="<from-yaml-config>" # Set via environment/config.yaml,
port=5432,
routing_apps=["analytics", "reports"],
),
}
โ ๏ธ Migration Gotchasโ
1. Custom Middleware Orderโ
# Django-CFG adds its own middleware
# Make sure your custom middleware is compatible
class MyConfig(DjangoConfig):
@property
def middleware(self) -> list:
middleware = super().middleware
# Add your custom middleware in the right position
middleware.insert(0, "myapp.middleware.CustomMiddleware")
return middleware
2. Third-Party App Settingsโ
# Some third-party apps need special settings
# Keep them in settings.py temporarily
# settings.py
from config import config
globals().update(config.get_all_settings())
# Third-party app settings that need special handling
CELERY_BROKER_URL = config.redis_url
CELERY_RESULT_BACKEND = config.redis_url
# TODO: Move to config.py when Django-CFG supports them
3. Static Files in Productionโ
# Make sure static files work in production
class MyConfig(DjangoConfig):
# ... other settings ...
@property
def static_root(self) -> str:
if self.is_production:
return "/var/www/static/"
return super().static_root
๐งช Testing Your Migrationโ
1. Automated Testingโ
# tests/test_migration.py
from django.test import TestCase
from config import config
class MigrationTest(TestCase):
def test_configuration_valid(self):
"""Test that configuration is valid"""
settings = config.get_all_settings()
# Test required settings
self.assertIn("SECRET_KEY", settings)
self.assertIn("DATABASES", settings)
self.assertIn("INSTALLED_APPS", settings)
def test_database_connection(self):
"""Test database connectivity"""
from django.db import connection
with connection.cursor() as cursor:
cursor.execute("SELECT 1")
result = cursor.fetchone()
self.assertEqual(result[0], 1)
def test_admin_accessible(self):
"""Test admin interface"""
response = self.client.get("/admin/")
self.assertEqual(response.status_code, 302) # Redirect to login
2. Manual Testing Checklistโ
# โ
Configuration validation
python manage.py validate_config
# โ
Database connectivity
python manage.py dbshell
# โ
Admin interface
python manage.py runserver
# Visit http://localhost:8000/admin/
# โ
API documentation (if enabled)
# Visit http://localhost:8000/api/docs/
# โ
Static files
python manage.py collectstatic --dry-run
# โ
Your custom functionality
python manage.py test
Migration Benefitsโ
After migration, you'll have:
| Feature | Before | After |
|---|---|---|
| Configuration | 500+ line settings.py | Type-safe config.py |
| Type Safety | None | 100% validated |
| Admin Interface | Basic Django admin | Modern Unfold admin |
| API Docs | Manual setup | Auto-generated |
| User Management | Basic User model | OTP auth + profiles |
| Background Tasks | Manual Celery setup | Built-in Django-RQ |
| Support System | Build from scratch | Ready-to-use |
| Newsletter | Third-party service | Built-in system |
| Lead Management | Custom solution | Built-in CRM |
| Environment Detection | Manual configuration | Automatic |
| CLI Tools | Basic Django commands | Enhanced commands |
| IDE Support | Basic | Full IntelliSense |
Post-Migration Stepsโ
1. Team Trainingโ
# Show team the new features
python manage.py info
python manage.py --help
# Demo the admin interface
python manage.py runserver
# Visit http://localhost:8000/admin/
2. Documentation Updatesโ
Update your project documentation to reflect Django-CFG patterns:
# Old README
1. Copy settings.py.example to settings.py
2. Edit 50+ settings manually
3. Hope everything works
# New README
1. Copy .env.example to .env
2. Edit 5 environment variables
3. Everything just works!
3. CI/CD Updatesโ
# .github/workflows/django.yml
- name: Validate Configuration
run: python manage.py validate_config --strict
- name: Run Enhanced Tests
run: |
python manage.py test
python manage.py check_settings
๐ Troubleshootingโ
Configuration Errorsโ
# Debug configuration issues
python manage.py show_config --debug
python manage.py validate_config --verbose
Import Errorsโ
# If you get import errors, check your PYTHONPATH
import sys
sys.path.insert(0, '/path/to/your/project')
Database Issuesโ
# Check database configuration
python manage.py dbshell
python manage.py migrate --dry-run
See Alsoโ
Migration & Setupโ
Getting Started:
- Installation Guide - Install Django-CFG
- Configuration Guide - Configure your project
- First Project - Complete tutorial
- Django-CFG vs Alternatives - Feature comparison
Migration Resources:
- Troubleshooting - Common migration issues
- Configuration Problems Solved - Real-world fixes
- Production Config - Production migration patterns
Configurationโ
Core Configuration:
- Configuration Models - Complete config API
- Type-Safe Configuration - Pydantic patterns
- Environment Detection - Multi-environment setup
- Environment Variables - Secrets management
Infrastructure:
- Database Configuration - Multi-database migration
- Cache Configuration - Redis/Memcached setup
- Security Settings - CORS, CSRF, SSL migration
Features & Integrationโ
Built-in Apps:
- Built-in Apps Overview - Enable production apps
- User Management - Accounts, Support
- AI Agents - AI workflow automation
Integrations:
- ReArq Integration - Background tasks
- Ngrok Integration - Webhook testing
- Email Module - Email configuration
Tools & Deploymentโ
CLI Tools:
- CLI Introduction - Enhanced management commands
- Core Commands - Essential CLI tools
- Custom Commands - Build your own
Deployment:
- Docker Deployment - Containerized deployment
- Logging Configuration - Production logging
Transform your Django project with Django-CFG! ๐ฏ
TAGS: migration, upgrade, existing-project, gradual-migration, fresh-start DEPENDS_ON: [installation, configuration] USED_BY: [production-config, deployment]