Usage Guide
Access Patterns
Proxy (Recommended)
from django_app_parameter import app_parameter
title = app_parameter.BLOG_TITLE # → str
year = app_parameter.BIRTH_YEAR # → int
rate = app_parameter.TAX_RATE # → Decimal
config = app_parameter.API_CONFIG # → dict
enabled = app_parameter.FEATURE_FLAG # → bool
launch = app_parameter.LAUNCH_DATE # → date
timeout = app_parameter.TIMEOUT # → timedelta
Pros: Concise, auto-conversion. Cons: Raises exception if missing.
Direct Access
from django_app_parameter.models import Parameter
# Get parameter object and retrieve typed value
param = Parameter.objects.get(slug="BLOG_TITLE")
title = param.get() # Returns str
param = Parameter.objects.get(slug="BIRTH_YEAR")
year = param.get() # Returns int
param = Parameter.objects.get(slug="TAX_RATE")
rate = param.get() # Returns Decimal
Pros: Full access to parameter object for modifications.
Parameter Object
param = Parameter.objects.get(slug="BLOG_TITLE")
print(param.name) # "Blog Title"
print(param.slug) # "BLOG_TITLE"
print(param.value_type) # "STR"
print(param.is_global) # True/False
value = param.get() # Auto-converted
Type Usage
STR (String)
Parameter.objects.create(
name="Site Title",
value="My Site",
value_type=TYPES.STR
)
title = app_parameter.SITE_TITLE # "My Site"
INT (Integer)
Parameter.objects.create(
name="Max Upload Size",
value="5242880",
value_type=TYPES.INT
)
max_size = app_parameter.MAX_UPLOAD_SIZE # 5242880
FLT (Float)
Parameter.objects.create(
name="PI Value",
value="3.14159",
value_type=TYPES.FLT
)
pi = app_parameter.PI_VALUE # 3.14159
Warning: Use DCL for money.
DCL (Decimal)
from decimal import Decimal
Parameter.objects.create(
name="Tax Rate",
value="20.00",
value_type=TYPES.DCL
)
tax_rate = app_parameter.TAX_RATE # Decimal('20.00')
BOO (Boolean)
Parameter.objects.create(
name="Maintenance Mode",
value="false",
value_type=TYPES.BOO
)
if app_parameter.MAINTENANCE_MODE:
return HttpResponse("Under maintenance")
Values: "true"/"false", "1"/"0", "yes"/"no" (case-insensitive).
DATE (Date)
from datetime import date
Parameter.objects.create(
name="Launch Date",
value="2024-12-31",
value_type=TYPES.DATE
)
launch = app_parameter.LAUNCH_DATE # date(2024, 12, 31)
Format: YYYY-MM-DD (ISO 8601).
DATETIME (Date and Time)
from datetime import datetime
Parameter.objects.create(
name="Event Start",
value="2024-12-31T23:59:59",
value_type=TYPES.DATETIME
)
event = app_parameter.EVENT_START # datetime(2024, 12, 31, 23, 59, 59)
Format: ISO 8601 (YYYY-MM-DDTHH:MM:SS).
TIME (Time)
from datetime import time
Parameter.objects.create(
name="Opening Time",
value="09:00:00",
value_type=TYPES.TIME
)
opening = app_parameter.OPENING_TIME # time(9, 0, 0)
Format: HH:MM:SS.
DURATION (Timedelta)
from datetime import timedelta
Parameter.objects.create(
name="Session Timeout",
value="3600", # seconds
value_type=TYPES.DURATION
)
timeout = app_parameter.SESSION_TIMEOUT # timedelta(seconds=3600)
Stored as seconds, returned as timedelta.
URL (Validated URL)
Parameter.objects.create(
name="API Endpoint",
value="https://api.example.com",
value_type=TYPES.URL
)
api_url = app_parameter.API_ENDPOINT # "https://api.example.com"
Validates URL format. Raises ValueError if invalid.
EMAIL (Validated Email)
Parameter.objects.create(
name="Contact Email",
value="contact@example.com",
value_type=TYPES.EMAIL
)
email = app_parameter.CONTACT_EMAIL # "contact@example.com"
Validates email format. Raises ValueError if invalid.
PERCENTAGE (0-100 Float)
Parameter.objects.create(
name="Discount",
value="15.5",
value_type=TYPES.PERCENTAGE
)
discount = app_parameter.DISCOUNT # 15.5
Validates 0-100 range. Raises ValueError if out of range.
LIST (Comma-separated)
Parameter.objects.create(
name="Allowed Tags",
value="python, django, web",
value_type=TYPES.LIST
)
tags = app_parameter.ALLOWED_TAGS # ["python", "django", "web"]
Splits by comma, strips whitespace.
DICT (JSON Dictionary)
Parameter.objects.create(
name="API Settings",
value='{"host": "api.example.com", "port": 443}',
value_type=TYPES.DICT
)
settings = app_parameter.API_SETTINGS # {"host": "api.example.com", "port": 443}
Must be valid JSON object. Raises ValueError if not dict.
JSN (Any JSON)
Parameter.objects.create(
name="Feature Flags",
value='["feature1", "feature2"]',
value_type=TYPES.JSN
)
flags = app_parameter.FEATURE_FLAGS # ["feature1", "feature2"]
Any valid JSON (dict, list, etc.).
PATH (File Path)
from pathlib import Path
Parameter.objects.create(
name="Log Directory",
value="/var/log/myapp",
value_type=TYPES.PATH
)
log_dir = app_parameter.LOG_DIRECTORY # Path("/var/log/myapp")
Returns pathlib.Path object.
Modifying Parameters
Using set()
param = Parameter.objects.get(slug="TAX_RATE")
param.set(Decimal("19.6")) # Type-safe, validates, saves
Validators run automatically before saving.
Using auto_cast
When you have a string value (e.g., from user input) and want to convert it to the parameter’s native type:
param = Parameter.objects.get(slug="TAX_RATE")
param.set("19.6", auto_cast=True) # Converts "19.6" to Decimal, validates, saves
param = Parameter.objects.get(slug="MAX_SIZE")
param.set("1024", auto_cast=True) # Converts "1024" to int, validates, saves
param = Parameter.objects.get(slug="LAUNCH_DATE")
param.set("2024-12-31", auto_cast=True) # Converts to date, validates, saves
This saves you from manually converting types before calling set().
In Admin
Changes take effect immediately. Validators run on save.
Validators
Adding Validators
param = Parameter.objects.get(slug="EMAIL")
# Add validator
param.validators.create(
validator_type="EmailValidator",
validator_params={}
)
# With parameters
param.validators.create(
validator_type="MinValueValidator",
validator_params={"limit_value": 0}
)
Built-in Validators
Value Validators:
MinValueValidator:{"limit_value": 0}MaxValueValidator:{"limit_value": 100}
Length Validators:
MinLengthValidator:{"limit_value": 3}MaxLengthValidator:{"limit_value": 255}
Pattern Validators:
RegexValidator:{"regex": "^[A-Z]+$"}validate_slug: No params
Format Validators:
EmailValidator: No paramsURLValidator: No paramsvalidate_ipv4_address: No paramsvalidate_ipv6_address: No params
File Validators:
FileExtensionValidator:{"allowed_extensions": ["pdf", "jpg"]}
Custom Validators
Define in settings:
# settings.py
DJANGO_APP_PARAMETER = {
'validators': {
'even_number': 'myapp.validators.validate_even_number',
'french_phone': 'myapp.validators.validate_french_phone',
}
}
# myapp/validators.py
from django.core.exceptions import ValidationError
def validate_even_number(value):
if value % 2 != 0:
raise ValidationError(f"{value} is not even")
Use:
param.validators.create(
validator_type="even_number",
validator_params={}
)
Validator JSON Format
For load_param command:
{
"name": "Tax Rate",
"value": "20.0",
"value_type": "DCL",
"validators": [
{
"validator_type": "MinValueValidator",
"validator_params": {"limit_value": 0}
},
{
"validator_type": "MaxValueValidator",
"validator_params": {"limit_value": 100}
}
]
}
In Views
from django.shortcuts import render
from django_app_parameter import app_parameter
from datetime import date
def home(request):
if app_parameter.MAINTENANCE_MODE:
return HttpResponse("Under maintenance", status=503)
launch_date = app_parameter.LAUNCH_DATE
if date.today() < launch_date:
return HttpResponse("Coming soon!")
context = {
'title': app_parameter.SITE_TITLE,
'contact': app_parameter.CONTACT_EMAIL,
'discount': app_parameter.DISCOUNT,
}
return render(request, 'home.html', context)
In Templates
Setup in settings.py:
TEMPLATES = [{
'OPTIONS': {
'context_processors': [
'django_app_parameter.context_processors.add_global_parameter_context',
],
},
}]
Usage:
<title>{{ SITE_TITLE }}</title>
<a href="mailto:{{ CONTACT_EMAIL }}">Contact</a>
{% if MAINTENANCE_MODE %}
<div class="alert">Maintenance scheduled</div>
{% endif %}
Note: Only is_global=True parameters are available in templates. Parameters are passed in their declared format (int, bool, etc.).
Advanced Patterns
Caching
from django.core.cache import cache
def get_cached_param(slug, timeout=3600):
key = f"param_{slug}"
value = cache.get(key)
if value is None:
value = getattr(app_parameter, slug)
cache.set(key, value, timeout)
return value
Default Values
def get_param_or_default(slug, default):
try:
return getattr(app_parameter, slug)
except ImproperlyConfigured:
return default
Dynamic Feature Flags
def feature_enabled(feature_name):
try:
return getattr(app_parameter, f"ENABLE_{feature_name.upper()}")
except ImproperlyConfigured:
return False
Best Practices
Use appropriate types: DATE for dates, DCL for money, PERCENTAGE for percentages
Add validators: Ensure data integrity
Cache frequently accessed params: Reduce DB queries
Don’t store secrets: No encryption
Use descriptive names: Help admins understand purpose
Set is_global carefully: Only for template-needed params
Document in description: Explain purpose and format