Django Settings Reference
Complete reference for Django settings configuration.
Settings Structure
The Django settings are organized in a modular structure:
config/settings/
├── __init__.py # Settings module marker
├── base.py # Base settings (common to all environments)
├── local.py # Local development settings
├── production.py # Production settings
└── test.py # Test settings
Base Settings (base.py)
Core Configuration
# Base Django configuration
BASE_DIR = Path(__file__).resolve().parent.parent.parent
# Application definition
DJANGO_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.sites',
]
THIRD_PARTY_APPS = [
'rest_framework',
'rest_framework.authtoken',
'corsheaders',
'django_extensions',
'channels',
'celery',
'django_celery_beat',
'django_celery_results',
]
LOCAL_APPS = [
'personal_finance.analytics',
'personal_finance.assets',
'personal_finance.backtesting',
'personal_finance.portfolio',
'personal_finance.realtime',
'personal_finance.tax',
'personal_finance.users',
'personal_finance.core',
]
INSTALLED_APPS = DJANGO_APPS + THIRD_PARTY_APPS + LOCAL_APPS
Application Settings
- SITE_ID
Site framework identifier.
- Default:
1- Type:
int
- ROOT_URLCONF
Root URL configuration module.
- Default:
'config.urls'- Type:
str
- WSGI_APPLICATION
WSGI application path.
- Default:
'config.wsgi.application'- Type:
str
- ASGI_APPLICATION
ASGI application for WebSocket support.
- Default:
'config.asgi.application'- Type:
str
Middleware Configuration
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware',
'django.middleware.security.SecurityMiddleware',
'whitenoise.middleware.WhiteNoiseMiddleware', # Static files
'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',
'personal_finance.core.middleware.RequestLoggingMiddleware',
'personal_finance.core.middleware.ErrorHandlingMiddleware',
]
Custom Middleware
- RequestLoggingMiddleware
Logs incoming requests and responses.
- Location:
personal_finance.core.middleware.RequestLoggingMiddleware- Settings:
Configured via
LOGGINGsettings
- ErrorHandlingMiddleware
Handles application errors and provides consistent responses.
- Location:
personal_finance.core.middleware.ErrorHandlingMiddleware- Settings:
Uses
DEBUGsetting for error detail level
Template Configuration
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [BASE_DIR / 'templates'],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
'personal_finance.core.context_processors.site_settings',
],
},
},
]
Template Context Processors
- site_settings
Adds site-wide configuration to template context.
- Location:
personal_finance.core.context_processors.site_settings- Variables:
SITE_NAME,SITE_VERSION,ENABLE_*feature flags
Database Configuration
Default Database Settings
# Database configuration
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
'OPTIONS': {
'timeout': 20,
'init_command': 'PRAGMA foreign_keys=ON;',
}
}
}
# Database connection age
CONN_MAX_AGE = 0 # Override in production
PostgreSQL Configuration
# PostgreSQL settings (production.py)
import dj_database_url
DATABASES = {
'default': dj_database_url.config(
default='postgresql://localhost:5432/personal_finance',
conn_max_age=int(env('DATABASE_CONN_MAX_AGE', 300))
)
}
Database Connection Pooling
- CONN_MAX_AGE
Database connection persistence in seconds.
- Default:
0(no persistence)- Production:
300(5 minutes)- Range:
0-3600
- DATABASE_OPTIONS
Database-specific connection options.
- SQLite:
timeout,init_command- PostgreSQL:
sslmode,connect_timeout- Example:
{'timeout': 20, 'init_command': 'PRAGMA foreign_keys=ON;'}
Cache Configuration
Cache Framework Setup
# Cache configuration
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
'LOCATION': 'personal-finance-cache',
'OPTIONS': {
'MAX_ENTRIES': 1000,
}
}
}
Redis Cache Configuration
# Redis cache settings (production.py)
CACHES = {
'default': {
'BACKEND': 'django_redis.cache.RedisCache',
'LOCATION': env('REDIS_URL', 'redis://localhost:6379/0'),
'OPTIONS': {
'CLIENT_CLASS': 'django_redis.client.DefaultClient',
'SERIALIZER': 'django_redis.serializers.json.JSONSerializer',
'COMPRESSOR': 'django_redis.compressors.zlib.ZlibCompressor',
'IGNORE_EXCEPTIONS': True,
},
'KEY_PREFIX': 'pf',
'VERSION': 1,
'TIMEOUT': 300, # 5 minutes default
}
}
Cache Settings
- CACHE_TTL
Default cache timeout in seconds.
- Default:
300(5 minutes)- Environment:
CACHE_TTL- Range:
60-3600
- CACHE_MAX_ENTRIES
Maximum number of cache entries.
- Default:
1000- Environment:
CACHE_MAX_ENTRIES- Range:
100-100000
Session Configuration
Session Framework Settings
# Session configuration
SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
SESSION_CACHE_ALIAS = 'default'
SESSION_COOKIE_AGE = 1209600 # 2 weeks
SESSION_COOKIE_NAME = 'pf_sessionid'
SESSION_SAVE_EVERY_REQUEST = False
SESSION_EXPIRE_AT_BROWSER_CLOSE = False
Session Security
- SESSION_COOKIE_SECURE
Require HTTPS for session cookies.
- Default:
False(local),True(production)- Environment:
SESSION_COOKIE_SECURE
- SESSION_COOKIE_HTTPONLY
Prevent JavaScript access to session cookies.
- Default:
True- Security:
Always keep enabled
- SESSION_COOKIE_SAMESITE
SameSite attribute for session cookies.
- Default:
'Lax'- Options:
'Strict','Lax','None'
Static Files Configuration
Static Files Settings
# Static files configuration
STATIC_URL = '/static/'
STATIC_ROOT = BASE_DIR / 'staticfiles'
STATICFILES_DIRS = [
BASE_DIR / 'static',
BASE_DIR / 'personal_finance' / 'static',
]
STATICFILES_FINDERS = [
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
]
Static Files Storage
# Production static files storage
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
# WhiteNoise configuration
WHITENOISE_USE_FINDERS = True
WHITENOISE_AUTOREFRESH = True # Development only
Media Files Configuration
# Media files
MEDIA_URL = '/media/'
MEDIA_ROOT = BASE_DIR / 'media'
# File upload settings
FILE_UPLOAD_MAX_MEMORY_SIZE = 10485760 # 10MB
DATA_UPLOAD_MAX_MEMORY_SIZE = 10485760 # 10MB
DATA_UPLOAD_MAX_NUMBER_FIELDS = 1000
REST Framework Configuration
DRF Settings
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.TokenAuthentication',
'rest_framework.authentication.SessionAuthentication',
],
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated',
],
'DEFAULT_RENDERER_CLASSES': [
'rest_framework.renderers.JSONRenderer',
'rest_framework.renderers.BrowsableAPIRenderer',
],
'DEFAULT_PARSER_CLASSES': [
'rest_framework.parsers.JSONParser',
'rest_framework.parsers.MultiPartParser',
'rest_framework.parsers.FormParser',
],
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 50,
'DEFAULT_FILTER_BACKENDS': [
'django_filters.rest_framework.DjangoFilterBackend',
'rest_framework.filters.SearchFilter',
'rest_framework.filters.OrderingFilter',
],
'DEFAULT_THROTTLE_CLASSES': [
'rest_framework.throttling.AnonRateThrottle',
'rest_framework.throttling.UserRateThrottle',
],
'DEFAULT_THROTTLE_RATES': {
'anon': '100/hour',
'user': '1000/hour',
'login': '5/min',
},
'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.NamespaceVersioning',
'DEFAULT_VERSION': 'v1',
'ALLOWED_VERSIONS': ['v1'],
}
API Authentication Settings
- Token Authentication
Token-based API authentication.
- Tokens:
Auto-generated for users
- Header:
Authorization: Token <token>- Expiry:
Configurable via
API_TOKEN_EXPIRY_HOURS
- Session Authentication
Browser session-based authentication.
- Use Case:
Web interface API calls
- CSRF:
Required for write operations
API Rate Limiting
- DEFAULT_THROTTLE_RATES
Rate limits for different user types.
- Anonymous:
100/hour- Authenticated:
1000/hour- Login:
5/min- Environment:
Override via
API_RATE_LIMIT_*variables
CORS Configuration
Cross-Origin Resource Sharing
# CORS settings
CORS_ALLOWED_ORIGINS = [
'http://localhost:3000', # React dev server
'http://127.0.0.1:3000',
]
CORS_ALLOWED_ORIGIN_REGEXES = [
r"^https://.*\.vercel\.app$", # Vercel deployments
r"^https://.*\.netlify\.app$", # Netlify deployments
]
CORS_ALLOW_CREDENTIALS = True
CORS_ALLOWED_HEADERS = [
'accept',
'accept-encoding',
'authorization',
'content-type',
'dnt',
'origin',
'user-agent',
'x-csrftoken',
'x-requested-with',
]
CORS Settings
- CORS_ALLOW_ALL_ORIGINS
Allow all origins (development only).
- Default:
False- Development:
True- Production:
False
- CORS_ALLOW_CREDENTIALS
Allow credentials in CORS requests.
- Default:
True- Required:
For session authentication
Celery Configuration
Celery Settings
# Celery configuration
CELERY_BROKER_URL = env('CELERY_BROKER_URL', 'redis://localhost:6379/1')
CELERY_RESULT_BACKEND = env('CELERY_RESULT_BACKEND', 'redis://localhost:6379/2')
CELERY_ACCEPT_CONTENT = ['json']
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'
CELERY_TIMEZONE = TIME_ZONE
# Task routing
CELERY_TASK_ROUTES = {
'personal_finance.analytics.tasks.*': {'queue': 'analytics'},
'personal_finance.backtesting.tasks.*': {'queue': 'backtesting'},
'personal_finance.realtime.tasks.*': {'queue': 'realtime'},
}
# Task execution settings
CELERY_TASK_ALWAYS_EAGER = env.bool('CELERY_TASK_ALWAYS_EAGER', False)
CELERY_TASK_EAGER_PROPAGATES = True
CELERY_WORKER_PREFETCH_MULTIPLIER = 1
CELERY_TASK_SOFT_TIME_LIMIT = 300 # 5 minutes
CELERY_TASK_TIME_LIMIT = 600 # 10 minutes
Celery Beat (Scheduling)
# Celery Beat scheduler settings
CELERY_BEAT_SCHEDULER = 'django_celery_beat.schedulers:DatabaseScheduler'
# Periodic tasks
CELERY_BEAT_SCHEDULE = {
'update-market-data': {
'task': 'personal_finance.realtime.tasks.update_market_data',
'schedule': 300.0, # Every 5 minutes during market hours
},
'generate-daily-reports': {
'task': 'personal_finance.analytics.tasks.generate_daily_reports',
'schedule': crontab(hour=0, minute=0), # Daily at midnight
},
'cleanup-old-logs': {
'task': 'personal_finance.core.tasks.cleanup_old_logs',
'schedule': crontab(hour=2, minute=0, day_of_week=0), # Weekly
},
}
Task Configuration
- CELERY_TASK_SOFT_TIME_LIMIT
Soft timeout for tasks in seconds.
- Default:
300(5 minutes)- Range:
60-3600
- CELERY_TASK_TIME_LIMIT
Hard timeout for tasks in seconds.
- Default:
600(10 minutes)- Range:
120-7200
- CELERY_WORKER_CONCURRENCY
Number of worker processes.
- Default:
CPU count
- Environment:
CELERY_WORKER_CONCURRENCY
Channels Configuration
WebSocket Settings
# Channels configuration
CHANNEL_LAYERS = {
'default': {
'BACKEND': 'channels_redis.core.RedisChannelLayer',
'CONFIG': {
'hosts': [env('REDIS_URL', 'redis://localhost:6379/3')],
'capacity': 1500,
'expiry': 60,
},
},
}
WebSocket Routing
# WebSocket URL routing (config/websocket.py)
from django.urls import path
from personal_finance.realtime.consumers import (
PriceUpdateConsumer,
PortfolioConsumer,
NotificationConsumer,
)
websocket_urlpatterns = [
path('ws/prices/', PriceUpdateConsumer.as_asgi()),
path('ws/portfolio/', PortfolioConsumer.as_asgi()),
path('ws/notifications/', NotificationConsumer.as_asgi()),
]
Channels Settings
- CHANNEL_CAPACITY
Maximum messages per channel.
- Default:
1500- Range:
100-10000
- CHANNEL_EXPIRY
Message expiry time in seconds.
- Default:
60- Range:
10-300
Logging Configuration
Logging Setup
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'verbose': {
'format': '{levelname} {asctime} {module} {process:d} {thread:d} {message}',
'style': '{',
},
'simple': {
'format': '{levelname} {message}',
'style': '{',
},
'json': {
'()': 'pythonjsonlogger.jsonlogger.JsonFormatter',
'format': '%(levelname)s %(asctime)s %(module)s %(message)s'
},
},
'handlers': {
'console': {
'class': 'logging.StreamHandler',
'formatter': 'simple',
},
'file': {
'class': 'logging.handlers.RotatingFileHandler',
'filename': BASE_DIR / 'logs' / 'django.log',
'maxBytes': 10485760, # 10MB
'backupCount': 5,
'formatter': 'verbose',
},
'celery': {
'class': 'logging.handlers.RotatingFileHandler',
'filename': BASE_DIR / 'logs' / 'celery.log',
'maxBytes': 10485760,
'backupCount': 3,
'formatter': 'verbose',
},
},
'root': {
'level': 'INFO',
'handlers': ['console', 'file'],
},
'loggers': {
'django': {
'handlers': ['console', 'file'],
'level': env('DJANGO_LOG_LEVEL', 'INFO'),
'propagate': False,
},
'personal_finance': {
'handlers': ['console', 'file'],
'level': env('APPLICATION_LOG_LEVEL', 'INFO'),
'propagate': False,
},
'celery': {
'handlers': ['celery'],
'level': env('CELERY_LOG_LEVEL', 'INFO'),
'propagate': False,
},
},
}
Log Levels and Handlers
- Log Levels
Standard Python logging levels.
- DEBUG:
Detailed diagnostic information
- INFO:
General information messages
- WARNING:
Something unexpected happened
- ERROR:
Serious problem occurred
- CRITICAL:
Very serious error occurred
- File Rotation
Automatic log file rotation settings.
- Max Size:
10MBper file- Backup Count:
5files- Location:
logs/directory
Security Settings
Security Headers
# Security settings
SECURE_BROWSER_XSS_FILTER = True
SECURE_CONTENT_TYPE_NOSNIFF = True
SECURE_HSTS_SECONDS = 31536000 # 1 year
SECURE_HSTS_INCLUDE_SUBDOMAINS = True
SECURE_HSTS_PRELOAD = True
X_FRAME_OPTIONS = 'DENY'
# Content Security Policy
CSP_DEFAULT_SRC = ("'self'",)
CSP_SCRIPT_SRC = ("'self'", "'unsafe-inline'", "cdnjs.cloudflare.com")
CSP_STYLE_SRC = ("'self'", "'unsafe-inline'", "fonts.googleapis.com")
CSP_FONT_SRC = ("'self'", "fonts.gstatic.com")
CSP_IMG_SRC = ("'self'", "data:")
CSRF Protection
- CSRF_COOKIE_SECURE
Require HTTPS for CSRF cookies.
- Default:
False(local),True(production)
- CSRF_COOKIE_SAMESITE
SameSite attribute for CSRF cookies.
- Default:
'Lax'- Options:
'Strict','Lax'
- CSRF_TRUSTED_ORIGINS
Trusted origins for CSRF protection.
- Example:
['https://yourfinance.com']
Password Validation
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
'OPTIONS': {'min_length': 8},
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
Internationalization
I18n Settings
# Internationalization
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Available languages
LANGUAGES = [
('en', 'English'),
('pt-br', 'Portuguese (Brazil)'),
('es', 'Spanish'),
]
# Locale paths
LOCALE_PATHS = [
BASE_DIR / 'locale',
]
Timezone Configuration
- TIME_ZONE
Default timezone for the application.
- Default:
'UTC'- Options:
Any timezone from
pytz.all_timezones- Example:
'America/New_York','Europe/London'
- USE_TZ
Enable timezone support.
- Default:
True- Recommendation:
Always keep enabled
Environment-Specific Settings
Local Development (local.py)
from .base import *
import os
# Development-specific settings
DEBUG = True
SECRET_KEY = env('DJANGO_SECRET_KEY', 'dev-secret-not-for-production')
ALLOWED_HOSTS = ['localhost', '127.0.0.1', '0.0.0.0']
# Database - SQLite for development
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
# Email backend for development
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
# CORS - Allow all origins in development
CORS_ALLOW_ALL_ORIGINS = True
# Disable caching in development
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.dummy.DummyCache',
}
}
# Django Debug Toolbar
if DEBUG:
INSTALLED_APPS += ['debug_toolbar']
MIDDLEWARE += ['debug_toolbar.middleware.DebugToolbarMiddleware']
INTERNAL_IPS = ['127.0.0.1']
Production (production.py)
from .base import *
import dj_database_url
# Production settings
DEBUG = False
SECRET_KEY = env('DJANGO_SECRET_KEY')
ALLOWED_HOSTS = env.list('DJANGO_ALLOWED_HOSTS')
# Database - PostgreSQL
DATABASES = {
'default': dj_database_url.config(
conn_max_age=env.int('DATABASE_CONN_MAX_AGE', 300)
)
}
# Security settings
SECURE_SSL_REDIRECT = True
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
# Static files - WhiteNoise with compression
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
# Email - Production SMTP
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = env('EMAIL_HOST')
EMAIL_PORT = env.int('EMAIL_PORT', 587)
EMAIL_USE_TLS = env.bool('EMAIL_USE_TLS', True)
EMAIL_HOST_USER = env('EMAIL_HOST_USER')
EMAIL_HOST_PASSWORD = env('EMAIL_HOST_PASSWORD')
# Logging - JSON format for production
LOGGING['formatters']['production'] = {
'()': 'pythonjsonlogger.jsonlogger.JsonFormatter',
'format': '%(levelname)s %(asctime)s %(name)s %(message)s'
}
Test Settings (test.py)
from .base import *
# Test-specific settings
DEBUG = False
SECRET_KEY = 'test-secret-key-not-for-production'
# In-memory database for tests
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': ':memory:',
}
}
# Disable migrations for faster tests
class DisableMigrations:
def __contains__(self, item):
return True
def __getitem__(self, item):
return None
MIGRATION_MODULES = DisableMigrations()
# Fast password hasher for tests
PASSWORD_HASHERS = [
'django.contrib.auth.hashers.MD5PasswordHasher',
]
# Disable caching in tests
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.dummy.DummyCache',
}
}
# Eager task execution for tests
CELERY_TASK_ALWAYS_EAGER = True
CELERY_TASK_EAGER_PROPAGATES = True
# Disable real email sending in tests
EMAIL_BACKEND = 'django.core.mail.backends.locmem.EmailBackend'
Custom Settings
Application-Specific Settings
# Personal Finance specific settings
# Feature flags
ENABLE_BACKTESTING = env.bool('ENABLE_BACKTESTING', True)
ENABLE_REALTIME_UPDATES = env.bool('ENABLE_REALTIME_UPDATES', True)
ENABLE_TAX_CALCULATIONS = env.bool('ENABLE_TAX_CALCULATIONS', True)
ENABLE_DATA_PROFILING = env.bool('ENABLE_DATA_PROFILING', True)
ENABLE_ADVANCED_ANALYTICS = env.bool('ENABLE_ADVANCED_ANALYTICS', False)
# Market data settings
MARKET_DATA_PROVIDER = env('MARKET_DATA_PROVIDER', 'yahoo_finance')
YAHOO_FINANCE_API_KEY = env('YAHOO_FINANCE_API_KEY', None)
ALPHA_VANTAGE_API_KEY = env('ALPHA_VANTAGE_API_KEY', None)
# Backtesting settings
BACKTESTING_MAX_LOOKBACK_YEARS = env.int('BACKTESTING_MAX_LOOKBACK_YEARS', 10)
BACKTESTING_DEFAULT_COMMISSION = env.float('BACKTESTING_DEFAULT_COMMISSION', 0.001)
# Real-time update settings
REALTIME_UPDATE_INTERVAL = env.int('REALTIME_UPDATE_INTERVAL', 30)
REALTIME_BATCH_SIZE = env.int('REALTIME_BATCH_SIZE', 50)
# Performance settings
DATABASE_POOL_SIZE = env.int('DATABASE_POOL_SIZE', 5)
CACHE_DEFAULT_TIMEOUT = env.int('CACHE_DEFAULT_TIMEOUT', 300)
Portfolio Settings
# Portfolio management settings
PORTFOLIO_MAX_POSITIONS = env.int('PORTFOLIO_MAX_POSITIONS', 1000)
PORTFOLIO_REBALANCE_THRESHOLD = env.float('PORTFOLIO_REBALANCE_THRESHOLD', 0.05)
PORTFOLIO_CURRENCY_DEFAULT = env('PORTFOLIO_CURRENCY_DEFAULT', 'USD')
# Risk management
RISK_MAX_POSITION_SIZE = env.float('RISK_MAX_POSITION_SIZE', 0.1) # 10% max
RISK_MAX_SECTOR_ALLOCATION = env.float('RISK_MAX_SECTOR_ALLOCATION', 0.25) # 25% max
Analytics Settings
# Analytics configuration
ANALYTICS_LOOKBACK_PERIODS = {
'short': 30, # 30 days
'medium': 90, # 3 months
'long': 365, # 1 year
}
ANALYTICS_BENCHMARK_SYMBOLS = ['SPY', 'QQQ', 'IWM'] # Default benchmarks
ANALYTICS_RISK_FREE_RATE = env.float('ANALYTICS_RISK_FREE_RATE', 0.02) # 2%
Tax Calculation Settings
# Tax calculation settings
TAX_YEAR_START_MONTH = 1 # January
TAX_LONG_TERM_THRESHOLD_DAYS = 365
TAX_WASH_SALE_PERIOD_DAYS = 30
# Default tax rates (can be overridden per user)
TAX_RATES_DEFAULT = {
'short_term': 0.22, # 22%
'long_term': 0.15, # 15%
'qualified_dividend': 0.15, # 15%
}
Settings Validation
Configuration Validation
# settings/validation.py
import os
from django.core.exceptions import ImproperlyConfigured
def validate_production_settings():
\"\"\"Validate production-specific settings.\"\"\"
required_vars = [
'DJANGO_SECRET_KEY',
'DATABASE_URL',
'REDIS_URL',
'EMAIL_HOST',
'EMAIL_HOST_USER',
'EMAIL_HOST_PASSWORD',
]
for var in required_vars:
if not os.environ.get(var):
raise ImproperlyConfigured(f\"Missing required environment variable: {var}\")
# Validate security settings
if not os.environ.get('DJANGO_ALLOWED_HOSTS'):
raise ImproperlyConfigured(\"DJANGO_ALLOWED_HOSTS must be set in production\")
def validate_api_keys():
\"\"\"Validate external API configuration.\"\"\"
if not any([
os.environ.get('YAHOO_FINANCE_API_KEY'),
os.environ.get('ALPHA_VANTAGE_API_KEY'),
]):
import warnings
warnings.warn(\"No market data API keys configured. Using free tier limits.\")
Custom Settings Commands
# management/commands/check_config.py
from django.core.management.base import BaseCommand
from django.conf import settings
from django.core.checks import run_checks
class Command(BaseCommand):
help = \"Check application configuration\"
def add_arguments(self, parser):
parser.add_argument(
'--env',
choices=['local', 'production', 'test'],
help='Check specific environment configuration',
)
def handle(self, *args, **options):
# Run Django system checks
errors = run_checks()
if errors:
self.stdout.write(
self.style.ERROR(f\"Found {len(errors)} configuration errors:\")
)
for error in errors:
self.stdout.write(self.style.ERROR(f\" {error}\"))
else:
self.stdout.write(
self.style.SUCCESS(\"All configuration checks passed!\")
)
# Custom validation
self.check_custom_settings()
def check_custom_settings(self):
\"\"\"Check custom application settings.\"\"\"
# Check feature flags consistency
if settings.ENABLE_REALTIME_UPDATES and not settings.REDIS_URL:
self.stdout.write(
self.style.WARNING(\"Real-time updates enabled but Redis not configured\")
)
# Check API key configuration
if settings.ENABLE_BACKTESTING and not any([
settings.YAHOO_FINANCE_API_KEY,
settings.ALPHA_VANTAGE_API_KEY,
]):
self.stdout.write(
self.style.WARNING(\"Backtesting enabled but no market data API keys configured\")
)
See Also
Environment Configuration Reference - Environment variables reference
Security Configuration - Security configuration details
../api/authentication - API authentication configuration
../deployment/production - Production deployment settings