Admin Integration
Django-CFG provides seamless admin integration for MoneyField with automatic widget detection and a dedicated display field.
Overview
No extra mixins needed! PydanticAdmin automatically includes MoneyFieldAdminMixin.
Just inherit from PydanticAdmin and the currency features work out of the box.
| Component | Purpose |
|---|---|
PydanticAdmin | Base admin class (includes MoneyFieldAdminMixin) |
MoneyFieldDisplay | Display field for admin lists |
MoneyFieldWidget | Form widget for editing (auto-applied) |
MoneyFieldDisplay
Compact display field for admin lists. Auto-detects related fields from the base name.
Import
from django_cfg.modules.django_admin import MoneyFieldDisplayBasic Usage
from django_cfg.modules.django_admin import AdminConfig, MoneyFieldDisplay
config = AdminConfig(
model=Vehicle,
list_display=["id", "name", "price"],
display_fields=[
# Auto-detects: price_currency, price_target, price_rate, price_rate_at
MoneyFieldDisplay(
name="price",
title="Price",
),
],
)What it displays:
₩15,700,000 → $10,645.05
Rate: 0.000678 • 2h agoParameters
| Parameter | Type | Default | Description |
|---|---|---|---|
name | str | Required | Base field name (e.g., “price”) |
title | str | None | Column header title |
currency_field | str | {name}_currency | Field with currency code |
target_field | str | {name}_target | Field with converted amount |
target_currency | str | "USD" | Target currency code |
rate_field | str | {name}_rate | Field with exchange rate |
rate_at_field | str | {name}_rate_at | Field with rate timestamp |
show_rate | bool | True | Show rate info line |
precision | int | 2 | Decimal places |
compact | bool | True | Single-line display |
Explicit Field Names
Override auto-detected field names if needed:
MoneyFieldDisplay(
name="price",
title="Price",
currency_field="price_currency",
target_field="price_target",
target_currency="USD",
rate_field="price_rate",
rate_at_field="price_rate_at",
)Display Options
MoneyFieldDisplay(
name="price",
title="Price",
show_rate=False, # Hide rate info line
precision=0, # No decimals
compact=False, # Multi-line display
)MoneyFieldWidget
Auto-applied to MoneyField in admin forms. No configuration needed.
Visual Layout
┌─────────────────────────────────────────────────────────────┐
│ Amount │ Currency │
│ ┌──────────────────────┐ │ ┌──────────────────────────┐ │
│ │ 50,000,000 │ │ │ KRW ▼ │ │
│ └──────────────────────┘ │ └──────────────────────────┘ │
│ → $33,900 | 1 KRW = 0.000678 USD • 2h ago [rates ↗] │
└─────────────────────────────────────────────────────────────┘Features
- Amount input (2/3 width) + Currency dropdown (1/3 width)
- Live conversion updates as you type (Alpine.js)
- Rate info with timestamp (“2h ago”)
- Link to CurrencyRate admin for rate management
- Dark mode support
Live Recalculation
When you change currency or amount:
- Widget reads rates from embedded JSON (passed at render)
- Alpine.js recalculates conversion
- Display updates instantly (no server roundtrip)
Complete Example
from django.contrib import admin
from django_cfg.modules.django_admin import (
AdminConfig,
MoneyFieldDisplay,
FieldsetConfig,
ShortUUIDField,
BadgeField,
)
from django_cfg.modules.django_admin.base import PydanticAdmin
from .models import Vehicle
config = AdminConfig(
model=Vehicle,
# Performance
select_related=["source", "brand"],
# List view columns
list_display=["id", "name", "price", "status"],
# Display field configurations
display_fields=[
ShortUUIDField(name="id", title="ID"),
# MoneyFieldDisplay - auto-detects all price-related fields
MoneyFieldDisplay(
name="price",
title="Price",
),
BadgeField(
name="status",
title="Status",
label_map={
"active": "success",
"sold": "danger",
},
),
],
# Form fieldsets
fieldsets=[
FieldsetConfig(
title="Basic Info",
fields=["name", "status"],
),
FieldsetConfig(
title="Pricing",
fields=["price"], # MoneyFieldWidget auto-applied
),
],
)
@admin.register(Vehicle)
class VehicleAdmin(PydanticAdmin):
"""PydanticAdmin includes MoneyFieldAdminMixin automatically."""
config = configHow MoneyFieldAdminMixin Works
MoneyFieldAdminMixin is automatically included in PydanticAdmin. Here’s what it provides:
1. Auto-Detection of MoneyField
On admin init, it scans the model for MoneyField instances and registers related fields.
2. Readonly Fields
Automatically adds _target, _rate, _rate_at as readonly fields:
def get_readonly_fields(self, request, obj=None):
readonly = list(super().get_readonly_fields(request, obj))
for field_name in self._get_money_field_names():
for suffix in ["_target", "_rate", "_rate_at"]:
aux_field = f"{field_name}{suffix}"
if self._field_exists(aux_field):
readonly.append(aux_field)
return readonly3. Widget Assignment
Replaces default widget with MoneyFieldWidget:
def formfield_for_dbfield(self, db_field, request, **kwargs):
if db_field.__class__.__name__ == "MoneyField":
kwargs["widget"] = MoneyFieldWidget(
default_currency=current_currency,
target_currency=target_currency,
)
return super().formfield_for_dbfield(db_field, request, **kwargs)4. Currency Saving
Handles currency field saving from POST data:
def save_model(self, request, obj, form, change):
for field_name in self._get_money_field_names():
currency_key = f"{field_name}_currency"
if currency_key in request.POST:
setattr(obj, currency_key, request.POST[currency_key])
super().save_model(request, obj, form, change)Currency Symbols
MoneyFieldDisplay includes built-in currency symbols:
| Code | Symbol |
|---|---|
| USD | $ |
| EUR | € |
| GBP | £ |
| JPY | ¥ |
| KRW | ₩ |
| CNY | ¥ |
| RUB | ₽ |
| BTC | ₿ |
| ETH | Ξ |
Unknown currencies display as "CODE " (code + space).
Troubleshooting
Widget Not Appearing
Make sure you’re using PydanticAdmin:
from django_cfg.modules.django_admin.base import PydanticAdmin
@admin.register(Vehicle)
class VehicleAdmin(PydanticAdmin): # ✅ Correct
config = configCurrency Not Saving
Check that the form includes the currency field in POST data. The widget automatically handles this.
Conversion Shows “N/A”
- Check that rates exist in
CurrencyRatetable - Click “Update All Rates” in CurrencyRate admin
- Verify
price_currencyhas a value
See Also
- Quick Start - Get started in 5 minutes
- MoneyField - Model field deep dive
- API Reference - Complete API documentation