Skip to main content

Quick Start

Get your first declarative admin up and running in 5 minutes.

Installation

Django Admin module is included with Django-CFG by default. No additional installation required.

Already Installed

If you have django-cfg installed, the admin module is ready to use!

Basic Setup

Step 1: Import Components

from django.contrib import admin
from django_cfg.modules.django_admin import AdminConfig
from django_cfg.modules.django_admin.base import PydanticAdmin
Import Path

Always import PydanticAdmin from .base:

# ✅ Correct
from django_cfg.modules.django_admin.base import PydanticAdmin

# ❌ Wrong
from django_cfg.modules.django_admin import PydanticAdmin # Won't work!

Step 2: Create Your First Admin

Let's say you have a simple Product model:

# models.py
from django.db import models

class Product(models.Model):
name = models.CharField(max_length=200)
price = models.DecimalField(max_digits=10, decimal_places=2)
stock = models.IntegerField()
is_active = models.BooleanField(default=True)
created_at = models.DateTimeField(auto_now_add=True)

Create a declarative admin:

# admin.py
from django.contrib import admin
from django_cfg.modules.django_admin import AdminConfig
from django_cfg.modules.django_admin.base import PydanticAdmin
from .models import Product

# Define configuration
config = AdminConfig(
model=Product,
list_display=["name", "price", "stock", "is_active", "created_at"],
list_filter=["is_active", "created_at"],
search_fields=["name"],
)

# Register admin
@admin.register(Product)
class ProductAdmin(PydanticAdmin):
config = config

That's it! You now have a fully functional admin interface.

Adding Display Fields

Let's enhance the display with specialized field types:

from django_cfg.modules.django_admin import (
AdminConfig,
BadgeField,
BooleanField,
CurrencyField,
DateTimeField,
)
from django_cfg.modules.django_admin.base import PydanticAdmin

config = AdminConfig(
model=Product,

list_display=["name", "price", "stock", "is_active", "created_at"],

# Add specialized display fields
display_fields=[
CurrencyField(
name="price",
title="Price",
currency="USD",
precision=2,
),
BooleanField(
name="is_active",
title="Status",
),
DateTimeField(
name="created_at",
title="Created",
show_relative=True,
),
],

list_filter=["is_active", "created_at"],
search_fields=["name"],
)

@admin.register(Product)
class ProductAdmin(PydanticAdmin):
config = config
What Changed?
  • CurrencyField - Formats price as $1,234.56
  • BooleanField - Shows is_active with ✓/✗ icons
  • DateTimeField - Displays created_at as "2 hours ago"

Adding Icons and Badges

Make your admin more visual with badges and icons:

from django_cfg.modules.django_admin import (
AdminConfig,
BadgeField,
Icons,
)
from django_cfg.modules.django_admin.base import PydanticAdmin

config = AdminConfig(
model=Product,

list_display=["name", "price", "status", "stock_level"],

display_fields=[
BadgeField(
name="status",
title="Status",
variant="primary",
icon=Icons.INVENTORY,
),
BadgeField(
name="stock_level",
title="Stock",
label_map={
"in_stock": "success",
"low_stock": "warning",
"out_of_stock": "danger",
},
icon=Icons.PACKAGE,
),
],
)

@admin.register(Product)
class ProductAdmin(PydanticAdmin):
config = config

Organizing with Fieldsets

Group related fields using fieldsets:

from django_cfg.modules.django_admin import (
AdminConfig,
FieldsetConfig,
)
from django_cfg.modules.django_admin.base import PydanticAdmin

config = AdminConfig(
model=Product,

list_display=["name", "price", "is_active"],

fieldsets=[
FieldsetConfig(
title="Basic Information",
fields=["name", "description"],
),
FieldsetConfig(
title="Pricing & Inventory",
fields=["price", "stock", "sku"],
),
FieldsetConfig(
title="Status",
fields=["is_active", "created_at", "updated_at"],
collapsed=True, # Start collapsed
),
],

readonly_fields=["created_at", "updated_at"],
)

@admin.register(Product)
class ProductAdmin(PydanticAdmin):
config = config

Query Optimization

Optimize database queries with built-in support:

config = AdminConfig(
model=Order,

# Optimize queries
select_related=["user", "product"],
prefetch_related=["items"],

list_display=["id", "user", "product", "total"],
)
Automatic Optimization

The admin automatically applies select_related and prefetch_related to all queries. No need to override get_queryset()!

Working with JSON Fields

Automatically get a rich JSON editor for all JSONField models:

from django.db import models
from django_cfg.modules.django_admin import (
AdminConfig,
JSONWidgetConfig,
)

# Model with JSON fields
class BotConfig(models.Model):
name = models.CharField(max_length=100)
settings = models.JSONField(default=dict) # Auto-applied JSON editor
schema = models.JSONField(null=True)

# Configure JSON widgets
config = AdminConfig(
model=BotConfig,

# Customize JSON editor per field
widgets=[
JSONWidgetConfig(
field="settings",
mode="tree", # Interactive tree editor
height="400px",
),
JSONWidgetConfig(
field="schema",
mode="view", # Read-only display
height="500px",
show_copy_button=True, # Copy button for easy copying
),
],

fieldsets=[
FieldsetConfig(
title="Configuration",
fields=["name", "settings", "schema"],
),
],
)
JSON Widget Modes
  • tree - Interactive tree view for editing complex JSON
  • code - Text editor with syntax highlighting
  • view - Read-only display with copy button

Common Patterns

User Admin

from django_cfg.modules.django_admin import (
AdminConfig,
BadgeField,
BooleanField,
DateTimeField,
Icons,
UserField,
)

config = AdminConfig(
model=User,

list_display=["username", "email", "is_active", "date_joined"],

display_fields=[
UserField(
name="username",
title="User",
header=True, # Show with avatar
),
BooleanField(name="is_active", title="Active"),
BooleanField(name="is_staff", title="Staff"),
DateTimeField(name="date_joined", title="Joined"),
],

list_filter=["is_active", "is_staff", "date_joined"],
search_fields=["username", "email", "first_name", "last_name"],
)

E-commerce Order

config = AdminConfig(
model=Order,

select_related=["user", "shipping_address"],
prefetch_related=["items"],

list_display=["order_number", "user", "total", "status", "created_at"],

display_fields=[
UserField(name="user", header=True),
CurrencyField(name="total", currency="USD", precision=2),
BadgeField(
name="status",
label_map={
"pending": "warning",
"processing": "info",
"shipped": "primary",
"delivered": "success",
"cancelled": "danger",
},
icon=Icons.SHOPPING_CART,
),
DateTimeField(name="created_at", show_relative=True),
],

list_filter=["status", "created_at"],
search_fields=["order_number", "user__email"],
)

Blog Post

config = AdminConfig(
model=Post,

select_related=["author", "category"],

list_display=["title", "author", "category", "status", "published_at"],

display_fields=[
BadgeField(
name="status",
label_map={"draft": "secondary", "published": "success"},
icon=Icons.ARTICLE,
),
BadgeField(
name="category",
variant="info",
icon=Icons.CATEGORY,
),
DateTimeField(name="published_at", show_relative=True),
],

fieldsets=[
FieldsetConfig(title="Content", fields=["title", "slug", "content"]),
FieldsetConfig(title="Meta", fields=["author", "category", "tags"]),
FieldsetConfig(title="Publishing", fields=["status", "published_at"]),
],

list_filter=["status", "category", "published_at"],
search_fields=["title", "content"],
prepopulated_fields={"slug": ("title",)},
)

Next Steps

📚 Learn More

🚀 Advanced Features

  • Custom actions and bulk operations
  • Import/Export integration
  • Advanced filtering - Custom filters and third-party integrations
  • Custom widgets and renderers
Pro Tip

Start simple with basic AdminConfig, then gradually add display fields, fieldsets, and optimizations as needed. The declarative approach makes it easy to iterate!