Skip to Content
FeaturesModulesDjango AdminField TypesDisplay Fields

Display Field Types

Display-focused field types for rich visual presentations in Django Admin, including user avatars, profile displays, external links, images, and image previews with modal zoom.

Overview

Display field types specialize in presenting visual and interactive content:

Field TypePurposeCommon Use Cases
AvatarFieldUser avatars with initials fallbackProfile pictures, user identity
UserFieldUser display with avatarAuthors, assignees, owners
ForeignKeyFieldRelated object with admin link and subtitleMachine, workspace, category relations
LinkFieldText with external link and subtitleUsernames, titles, external resources
ImageFieldImages with captionsQR codes, photos, avatars
ImagePreviewFieldImage preview with modal zoom/panPhotos, thumbnails, media galleries
VideoFieldVideo thumbnail with platform detectionYouTube, Vimeo, direct videos

AvatarField

Display user avatars with automatic fallback to colored initials badge.

Parameters

ParameterTypeDefaultDescription
namestrrequiredField name
titlestr | NoneNoneDisplay title
photo_fieldstrrequiredModel field for photo/avatar image
name_fieldstrrequiredModel field for display name
initials_fieldstrrequiredField for extracting initials
subtitle_fieldstr | NoneNoneOptional subtitle (email, user_id)
avatar_sizeint40Avatar size in pixels
show_as_cardboolFalseShow as user card layout
variant_fieldstr | NoneNoneField to determine badge variant
variant_mapdict[str, str] | NoneNoneMap field values to badge variants
default_variantstr"secondary"Default badge variant
initials_max_lengthint2Maximum initials (1-3)
empty_valuestr"—"Value when None
orderingstr | NoneNoneSort field

Basic Usage

from django_cfg.modules.django_admin import AvatarField # Basic avatar - IMPORTANT: name must be a real model field! AvatarField( name="first_name", # Real model field, not virtual photo_field="photo_file", name_field="display_name", initials_field="first_name", ) # Avatar with subtitle AvatarField( name="username", # Real model field photo_field="avatar", name_field="full_name", initials_field="username", subtitle_field="email", show_as_card=True, ) # Avatar with custom sizing and variant mapping AvatarField( name="first_name", # Real model field photo_field="profile_picture", name_field="name", initials_field="first_name", avatar_size=48, variant_field="user_type", variant_map={ "admin": "success", "user": "secondary", "bot": "info", }, )

Examples

Basic Avatar

display_fields=[ AvatarField( name="username", # Real model field photo_field="photo", name_field="username", initials_field="first_name", ), ]

Renders as:

  • Photo if available
  • Colored badge with initials if no photo

User Card

display_fields=[ AvatarField( name="first_name", # Real model field photo_field="avatar", name_field="full_name", initials_field="first_name", subtitle_field="email", show_as_card=True, avatar_size=48, ), ]

Renders as: User card with avatar/initials, name, and email

Dynamic Colors

display_fields=[ AvatarField( name="username", # Real model field photo_field="photo", name_field="name", initials_field="username", variant_field="role", variant_map={ "admin": "success", "moderator": "primary", "user": "secondary", "bot": "info", }, default_variant="secondary", ), ]

Renders as: Initials badge color changes based on user role

IMPORTANT: Use Real Model Fields The name parameter MUST be a real model field, not a virtual field or @property!

❌ Wrong:

AvatarField( name="user_avatar", # Virtual field - doesn't exist in model ... )

✅ Correct:

AvatarField( name="first_name", # Real CharField in model photo_field="photo_file", name_field="display_name", # Can be @property initials_field="first_name", ... )

The name field is used by Django’s queryset system. Other fields like name_field, initials_field, subtitle_field can be properties or methods.

Automatic Fallback AvatarField automatically:

  • Shows photo if photo_field has value
  • Falls back to colored initials badge if no photo
  • Extracts initials from initials_field (e.g., “John Doe” → “JD”)
  • Uses variant mapping for dynamic badge colors

Use Cases Perfect for:

  • User lists (authors, assignees, owners)
  • Profile displays
  • Activity feeds
  • Comment sections
  • Any user-related display where visual identity matters

UserField

Display user information with avatar and optional header styling.

Parameters

ParameterTypeDefaultDescription
namestrrequiredField name (must be ForeignKey to User)
titlestr | NoneNoneDisplay title
headerboolFalseShow with avatar
empty_valuestr"—"Value when None
orderingstr | NoneNoneSort field (e.g., "user__username")

Basic Usage

from django_cfg.modules.django_admin import UserField # Simple user display UserField( name="author", title="Author", ordering="author__username", ) # User with avatar header UserField( name="owner", title="Owner", header=True, ordering="owner__username", )

Examples

Basic User

display_fields=[ UserField( name="author", title="Author", ordering="author__username", ), ]

Renders as: Username only

User with Avatar

display_fields=[ UserField( name="owner", title="Owner", header=True, ordering="owner__username", ), ]

Renders as: Avatar + Username in header style

Multiple Users

display_fields=[ UserField(name="created_by", title="Created By", header=True), UserField(name="assigned_to", title="Assigned To"), UserField(name="approved_by", title="Approved By"), ]

Requires User Relation UserField only works with ForeignKey fields pointing to the User model. Ensure select_related includes the user field for optimal performance.

ForeignKeyField

Display ForeignKey relations with customizable display and optional link to related object’s admin page.

Parameters

ParameterTypeDefaultDescription
namestrrequiredForeignKey field name
titlestr | NoneNoneDisplay title
link_fieldstr"id"Field for link (usually 'id' or 'pk')
display_fieldstrrequiredField to display (e.g., 'name', 'title')
link_to_adminboolTrueCreate link to admin page
link_iconstr | NoneNoneMaterial icon next to link
link_targetstr"_self"Link target (_blank, _self)
subtitle_fieldstr | NoneNoneSingle field for subtitle
subtitle_fieldslist[str] | NoneNoneMultiple fields for subtitle
subtitle_templatestr | NoneNoneTemplate with {field_name} placeholders
subtitle_separatorstr" • "Separator for multiple fields
show_null_as_emptyboolTrueShow empty value when FK is null
null_displaystr"—"Value to display when FK is null
subtitle_css_classstr"text-sm text-gray-500"CSS classes for subtitle
orderingstr | NoneNoneSort field

Basic Usage

from django_cfg.modules.django_admin import ForeignKeyField, Icons # Basic FK display ForeignKeyField( name="machine", display_field="name", ) # FK with custom link field ForeignKeyField( name="workspace", link_field="id", display_field="name", ) # FK with admin link and icon ForeignKeyField( name="category", display_field="name", link_to_admin=True, link_icon=Icons.OPEN_IN_NEW, ) # FK with subtitle (single field) ForeignKeyField( name="machine", display_field="name", subtitle_field="hostname", link_to_admin=True, ) # FK with subtitle template ForeignKeyField( name="workspace", display_field="name", subtitle_template="{description}{member_count} members", )

Examples

Basic FK Display

display_fields=[ ForeignKeyField( name="machine", display_field="name", title="Machine", ), ]

Renders as: Machine name with link to machine admin page

FK with Subtitle

display_fields=[ ForeignKeyField( name="machine", display_field="name", subtitle_field="hostname", title="Machine", ordering="machine__name", ), ]

Renders as:

Machine Name ↗ machine.example.com

FK with Multiple Subtitle Fields

display_fields=[ ForeignKeyField( name="workspace", display_field="name", subtitle_fields=["description", "member_count"], subtitle_separator=" • ", title="Workspace", ), ]

Renders as:

My Workspace ↗ Team workspace • 5 members

FK with Template Subtitle

display_fields=[ ForeignKeyField( name="workspace", display_field="name", subtitle_template="{description}{member_count} members", title="Workspace", ), ]

Renders as:

Development Team ↗ Development workspace • 12 members
from django_cfg.modules.django_admin import Icons display_fields=[ ForeignKeyField( name="user", display_field="username", subtitle_field="email", link_to_admin=True, link_icon=Icons.OPEN_IN_NEW, title="User", ), ]

Renders as:

john_doe 🔗 [email protected]
display_fields=[ ForeignKeyField( name="category", display_field="name", link_to_admin=False, # No link title="Category", ), ]

Renders as: Plain text without link

Automatic Admin Link By default (link_to_admin=True), ForeignKeyField automatically creates a link to the related object’s admin change page using the format /admin/{app_label}/{model_name}/{pk}/change/.

Optimize with select_related Always use select_related for ForeignKey fields to avoid N+1 queries:

config = AdminConfig( model=Session, select_related=["machine", "workspace", "user"], # Important! display_fields=[ ForeignKeyField(name="machine", display_field="name"), ForeignKeyField(name="workspace", display_field="name"), ] )

Subtitle Options

ForeignKeyField supports three mutually exclusive subtitle options:

# Option 1: Single field ForeignKeyField( name="machine", display_field="name", subtitle_field="hostname", # Shows hostname below name ) # Option 2: Multiple fields with separator ForeignKeyField( name="workspace", display_field="name", subtitle_fields=["description", "member_count"], subtitle_separator=" • ", # Joins with " • " ) # Option 3: Template with placeholders ForeignKeyField( name="workspace", display_field="name", subtitle_template="{description}{member_count} members", )

Use Cases

ForeignKeyField is perfect for:

  • Related objects: Machine, workspace, category, product
  • Entity relations: User assignments, parent-child relationships
  • Navigation: Quick access to related object admin pages
  • Context display: Show additional info about related object

Real-World Example

from django_cfg.modules.django_admin import ( AdminConfig, ForeignKeyField, BadgeField, DateTimeField, Icons, ) session_config = AdminConfig( model=Session, # Optimize queries select_related=["machine", "workspace", "user"], list_display=["id", "machine", "workspace", "status", "created_at"], display_fields=[ ForeignKeyField( name="machine", display_field="name", subtitle_field="hostname", link_to_admin=True, link_icon=Icons.COMPUTER, title="Machine", ordering="machine__name", ), ForeignKeyField( name="workspace", display_field="name", subtitle_template="{description}{member_count} members", link_to_admin=True, title="Workspace", ), BadgeField(name="status", label_map={...}), DateTimeField(name="created_at", show_relative=True), ], )

vs LinkField

  • ForeignKeyField: For Django ForeignKey relations with automatic admin links
  • LinkField: For external URLs and custom links

Use ForeignKeyField when working with Django model relations.

LinkField

Display text as clickable link with optional icon and subtitle.

Parameters

ParameterTypeDefaultDescription
namestrrequiredField name (text to display)
titlestr | NoneNoneDisplay title
link_fieldstrrequiredModel field containing the URL
link_iconstr | NoneNoneMaterial icon to display next to link
link_targetstr"_blank"Link target (_blank, _self, etc.)
subtitle_fieldstr | NoneNoneSingle field for subtitle
subtitle_fieldslist[str] | NoneNoneMultiple fields for subtitle
subtitle_templatestr | NoneNoneTemplate with {field_name} placeholders
subtitle_separatorstr" • "Separator for multiple fields
subtitle_css_classstr"text-sm text-gray-500"CSS for subtitle
empty_valuestr"—"Value when None
orderingstr | NoneNoneSort field

Basic Usage

from django_cfg.modules.django_admin import LinkField, Icons # Basic link LinkField( name="username", title="Username", link_field="profile_url", ) # Link with icon LinkField( name="display_name", title="User", link_field="telegram_link", link_icon=Icons.OPEN_IN_NEW, ) # Link with subtitle from single field LinkField( name="title", title="Article", link_field="url", link_icon=Icons.ARTICLE, subtitle_field="author", ) # Link with subtitle from multiple fields LinkField( name="display_name", title="User Info", link_field="telegram_link", link_icon=Icons.OPEN_IN_NEW, subtitle_fields=["full_name", "phone"], ordering="username", )

Examples

display_fields=[ LinkField( name="website_url", title="Website", link_field="website_url", # Can link to itself link_icon=Icons.OPEN_IN_NEW, ), ]

Renders as:

https://example.com 🔗

Telegram User

# Real-world example: Telegram user with link # NOTE: display_name is a @property, use a real model field instead! display_fields=[ LinkField( name="username", # Real model field title="User Info", link_field="telegram_link", link_icon=Icons.OPEN_IN_NEW, subtitle_fields=["full_name", "phone"], subtitle_separator=" • ", ordering="username", ), ]

Renders as:

@username 🔗 John Doe • +1234567890

Template Subtitle

display_fields=[ LinkField( name="channel_title", title="Channel", link_field="channel_url", link_icon=Icons.OPEN_IN_NEW, subtitle_template="ID: {channel_id} • Subscribers: {subscriber_count}", ), ]

Renders as:

My Channel 🔗 ID: 123456 • Subscribers: 1,234

Subtitle Options

LinkField supports three mutually exclusive subtitle options:

# Option 1: Single field LinkField( name="username", link_field="profile_url", subtitle_field="email", # Shows email below username ) # Option 2: Multiple fields with separator LinkField( name="display_name", link_field="telegram_link", subtitle_fields=["full_name", "phone", "email"], subtitle_separator=" • ", # Joins with " • " ) # Option 3: Template with placeholders LinkField( name="product_name", link_field="product_url", subtitle_template="Price: ${price} | Stock: {stock_count}", )

Use Cases

LinkField is perfect for:

  • External links: Links to external websites, profiles, resources
  • User profiles: Telegram users, social media profiles
  • Resources: Articles, documents, API endpoints
  • Channel/Group links: Telegram channels, Discord servers

Real-World Example

from django_cfg.modules.django_admin import AdminConfig, LinkField, Icons telegram_user_config = AdminConfig( model=TelegramUser, list_display=["first_name", "username", "status_badges", "messages_badge"], display_fields=[ LinkField( name="username", # Real model field title="User Info", link_field="telegram_link", link_icon=Icons.OPEN_IN_NEW, subtitle_fields=["full_name", "phone"], ordering="username", ), ], )

Declarative Approach LinkField eliminates the need for @computed_field with raw HTML. Everything is configured declaratively with type-safe parameters.

No Raw HTML Required Unlike manual @computed_field implementations, LinkField handles all HTML generation internally. You just configure the fields and it renders properly.

ImageField

Display images from URLs with optional captions and styling.

Parameters

ParameterTypeDefaultDescription
namestrrequiredField name (or method name)
titlestr | NoneNoneDisplay title
widthstr | NoneNoneImage width (e.g., "200px")
heightstr | NoneNoneImage height (e.g., "200px")
max_widthstr"200px"Maximum width
max_heightstr | NoneNoneMaximum height
border_radiusstr | NoneNoneBorder radius (e.g., "50%", "8px")
captionstr | NoneNoneStatic caption text
caption_fieldstr | NoneNoneModel field to use as caption
caption_templatestr | NoneNoneTemplate with {field_name} placeholders
alt_textstr"Image"Alt text for image
empty_valuestr"—"Value when None

Basic Usage

from django_cfg.modules.django_admin import ImageField # Simple image ImageField( name="photo_url", title="Photo", max_width="200px", ) # Image with static caption ImageField( name="thumbnail", title="Thumbnail", max_width="100px", caption="Product Image", ) # Image with caption from field ImageField( name="avatar_url", title="Avatar", width="50px", height="50px", border_radius="50%", caption_field="username", )

Examples

QR Code

# QR code with template caption display_fields=[ ImageField( name="get_qr_code_url", # Can be a method title="QR Code", max_width="200px", caption_template="Scan to pay: <code>{pay_address}</code>", ), ]

Result:

<img src="https://api.qrserver.com/..." alt="Image" style="max-width: 200px;"> <br><small>Scan to pay: <code>0x1234...5678</code></small>

Circular Avatar

# Circular avatar with username display_fields=[ ImageField( name="profile_picture", title="Avatar", width="50px", height="50px", border_radius="50%", caption_field="full_name", ), ]

Result:

<img src="/media/avatars/john.jpg" alt="Image" style="width: 50px; height: 50px; border-radius: 50%;"> <br><small>John Doe</small>

Product Photo

# Product photo with multiple fields in caption display_fields=[ ImageField( name="image_url", title="Product", max_width="150px", max_height="150px", caption_template="{name} - ${price}", ), ]

Result:

<img src="/media/products/laptop.jpg" alt="Image" style="max-width: 150px; max-height: 150px;"> <br><small>Laptop Pro - $1299</small>

Method Support

ImageField supports both model fields and methods:

class Payment(models.Model): pay_address = models.CharField(max_length=100) def get_qr_code_url(self, size=200): """Generate QR code URL dynamically.""" from urllib.parse import quote data = quote(self.pay_address) return f"https://api.qrserver.com/v1/create-qr-code/?size={size}x{size}&data={data}" # Use method in ImageField ImageField( name="get_qr_code_url", # Method will be called automatically title="Payment QR", max_width="200px", caption_template="Address: <code>{pay_address}</code>", )

Caption Templates

Use {field_name} placeholders in caption_template:

# Single field caption_template="Scan: {address}" # Multiple fields caption_template="User: {username} | ID: {user_id}" # With HTML caption_template="Pay to: <code>{wallet_address}</code>"

Styling

Control image appearance with CSS properties:

# Fixed size ImageField(width="100px", height="100px") # Maximum constraints ImageField(max_width="300px", max_height="200px") # Circular/rounded ImageField(border_radius="50%") # Circle ImageField(border_radius="8px") # Rounded corners # Combined ImageField( width="80px", height="80px", border_radius="50%", max_width="100px", )

ImagePreviewField

Display images with clickable thumbnails that open a fullscreen modal with zoom and pan capabilities.

Features

  • Click to preview - Thumbnail opens fullscreen modal
  • Mouse wheel zoom - Scroll to zoom in/out
  • Drag to pan - Click and drag to move zoomed image
  • Image info panel - Shows dimensions, filename, format
  • Keyboard support - Escape to close
  • Smart conditions - Show preview only when condition is met
  • Global modal - Single modal instance per page (not duplicated)

Parameters

ParameterTypeDefaultDescription
namestrrequiredField name (ImageField/FileField/URL)
titlestr | NoneNoneDisplay title
thumbnail_max_widthint200Max thumbnail width in pixels
thumbnail_max_heightint150Max thumbnail height in pixels
border_radiusint8Border radius in pixels
show_infoboolTrueShow image info in modal
zoom_enabledboolTrueEnable mouse wheel zoom
zoom_minfloat0.5Minimum zoom level
zoom_maxfloat5.0Maximum zoom level
zoom_stepfloat0.1Zoom step per scroll
pan_enabledboolTrueEnable drag to pan
captionstr | NoneNoneStatic caption text
caption_fieldstr | NoneNoneModel field for caption
caption_templatestr | NoneNoneTemplate with {field} placeholders
url_methodstr | NoneNoneModel method that returns URL
condition_fieldstr | NoneNoneField to check for showing preview
condition_valueAny | list[Any]TrueExpected value(s) for condition. Can be a single value or list of values.
fallback_textstr | NoneNoneText when condition not met
empty_valuestr"—"Value when None

Basic Usage

from django_cfg.modules.django_admin import ImagePreviewField # Simple preview for ImageField ImagePreviewField( name="photo", title="Photo", thumbnail_max_width=150, ) # Smaller thumbnails ImagePreviewField( name="thumbnail", title="Preview", thumbnail_max_width=100, thumbnail_max_height=100, ) # Circular preview (avatar style) ImagePreviewField( name="avatar", title="Avatar", thumbnail_max_width=80, thumbnail_max_height=80, border_radius=40, # Half of width for circle )

Smart Preview with Conditions

Show preview only for images, fallback for other file types:

# Preview only for images, show badge for other files ImagePreviewField( name="file", title="Media", url_method="get_download_url", # Use method to get URL condition_field="is_image", # Only show preview if is_image=True fallback_text="Not an image", # Badge text for non-images ) # Preview only for specific media types ImagePreviewField( name="media_file", title="Preview", condition_field="media_type", condition_value="photo", # Only for photos fallback_text="No preview", ) # Preview for multiple types (list of values) ImagePreviewField( name="result_url", title="Result", condition_field="task_type", condition_value=["image", "portrait", "composite"], # All image-based types fallback_text="—", )

Examples

Basic Preview

display_fields=[ ImagePreviewField( name="photo", title="Photo", thumbnail_max_width=150, thumbnail_max_height=150, ), ]

Renders as: Clickable thumbnail → fullscreen modal with zoom/pan

Smart Preview

# TelegramMedia admin - preview only for images display_fields=[ ImagePreviewField( name="file", title="Preview", thumbnail_max_width=100, thumbnail_max_height=100, url_method="get_download_url", condition_field="is_image", fallback_text="Not image", ), ]

Renders as:

  • For images: Clickable thumbnail with preview
  • For videos/docs: Badge “Not image”

With Caption

display_fields=[ ImagePreviewField( name="product_image", title="Product", thumbnail_max_width=200, caption_field="product_name", ), ]

Renders as: Thumbnail with product name below

Auto-Preview for ImageField in Fieldsets

ImageField and FileField in readonly_fields automatically get preview functionality:

config = AdminConfig( model=Product, readonly_fields=["id", "photo", "created_at"], # photo gets auto-preview! fieldsets=[ FieldsetConfig( title="Media", fields=["photo"], # Will show clickable preview with modal ), ], )

Automatic for readonly_fields Any ImageField or FileField in readonly_fields automatically gets the preview modal. No configuration needed!

URL Resolution

ImagePreviewField supports multiple ways to get the image URL:

# 1. Direct ImageField/FileField ImagePreviewField(name="photo") # Uses photo.url # 2. URL CharField ImagePreviewField(name="image_url") # Uses field value directly # 3. Model method ImagePreviewField( name="file", url_method="get_download_url", # Calls obj.get_download_url() ) # 4. Property ImagePreviewField(name="thumbnail_url") # Uses @property value

Real-World Example

from django_cfg.modules.django_admin import ( AdminConfig, ImagePreviewField, ShortUUIDField, BadgeField, DateTimeField, ) telegram_media_config = AdminConfig( model=TelegramMedia, list_display=["id", "file", "media_type", "storage_status", "created_at"], display_fields=[ ShortUUIDField(name="id"), ImagePreviewField( name="file", title="Preview", thumbnail_max_width=100, thumbnail_max_height=100, url_method="get_download_url", condition_field="is_image", fallback_text="Not image", ), BadgeField(name="media_type", label_map={...}), DateTimeField(name="created_at", show_relative=True), ], readonly_fields=["id", "file", "created_at"], # file gets auto-preview in fieldsets! )

The preview modal includes:

  • Zoom controls: +/- buttons and percentage display
  • Reset zoom: Click percentage to reset to 100%
  • Pan: Drag image when zoomed in
  • Image info: Filename, dimensions (WxH), format
  • Keyboard: Escape to close
  • Hint: “Scroll to zoom • Drag to pan • Esc to close”

Styling

# Small thumbnails for list view ImagePreviewField( thumbnail_max_width=80, thumbnail_max_height=80, border_radius=4, ) # Larger preview ImagePreviewField( thumbnail_max_width=200, thumbnail_max_height=150, border_radius=8, ) # Circular (avatar style) ImagePreviewField( thumbnail_max_width=60, thumbnail_max_height=60, border_radius=30, # Half for circle )

vs ImageField

  • ImageField: Simple display, no interactivity
  • ImagePreviewField: Clickable with fullscreen modal, zoom, pan, info panel

Use ImagePreviewField when users need to examine images in detail.

Advanced: ImagePreviewDisplay in computed_field

For custom logic use ImagePreviewDisplay.render():

from django_cfg.modules.django_admin import ImagePreviewDisplay, computed_field @computed_field("Preview") def custom_preview(self, obj): if not obj.is_image: return self.html.badge("No preview", variant="secondary") return ImagePreviewDisplay.render( obj.get_download_url(), config={'thumbnail_max_width': '100px', 'thumbnail_max_height': '100px'} )

VideoField

Display video thumbnails with automatic platform detection for YouTube, Vimeo, and direct video URLs.

Parameters

ParameterTypeDefaultDescription
namestrrequiredField name containing video URL
titlestr | NoneNoneDisplay title
thumbnail_widthint200Thumbnail width in pixels
thumbnail_heightint112Thumbnail height (16:9 ratio)
border_radiusint8Border radius in pixels
show_inlineboolFalseShow inline player instead of thumbnail
show_platformboolTrueShow platform badge (YT, Vimeo)
fallback_textstr | NoneNoneText for invalid URLs
empty_valuestr"—"Value when None

Supported Platforms

  • YouTube: youtube.com, youtu.be, youtube.com/shorts
  • Vimeo: vimeo.com
  • Direct: .mp4, .webm, .ogg, .mov files

Basic Usage

from django_cfg.modules.django_admin import VideoField # Simple video thumbnail VideoField(name="video_url") # Custom size VideoField( name="promo_video", thumbnail_width=320, thumbnail_height=180, ) # Inline player (embedded) VideoField( name="tutorial_video", show_inline=True, )

Examples

display_fields=[ VideoField( name="youtube_url", title="Video", thumbnail_width=200, ), ]

Renders as:

  • YouTube thumbnail with play button overlay
  • Platform badge “YT” in corner
  • Click opens video in new tab

Advanced: VideoDisplay in computed_field

from django_cfg.modules.django_admin import VideoDisplay, computed_field @computed_field("Media") def media_preview(self, obj): if obj.media_type == 'video': return VideoDisplay.render(obj.media_url) return self.html.badge("Not video", variant="secondary")

Combining Display Fields

Mix display field types for rich admin displays:

from django_cfg.modules.django_admin import ( AdminConfig, AvatarField, BadgeField, CurrencyField, DateTimeField, Icons, LinkField, UserField, ) config = AdminConfig( model=Order, select_related=["user", "product"], list_display=["order_number", "user", "product", "total", "status", "created_at"], display_fields=[ AvatarField( name="user", # In this case, user is a ForeignKey field, which is valid title="Customer", photo_field="profile_picture", name_field="username", initials_field="first_name", subtitle_field="email", show_as_card=True, ordering="user__username", ), UserField( name="assigned_to", title="Assigned To", header=True, ordering="assigned_to__username", ), LinkField( name="product_name", title="Product", link_field="product_url", link_icon=Icons.OPEN_IN_NEW, subtitle_template="SKU: {product_sku}", ), BadgeField( name="status", title="Status", label_map={ "pending": "warning", "shipped": "primary", "delivered": "success", }, icon=Icons.SHOPPING_CART, ), ], )

Best Practices

1. Use Real Model Fields for name

# ✅ Good - Real model field AvatarField( name="first_name", # CharField in model photo_field="photo", name_field="display_name", # Can be @property initials_field="first_name", ) # ❌ Bad - Virtual field AvatarField( name="user_avatar", # Doesn't exist in model ... )
# ✅ Good - Include ForeignKey relations config = AdminConfig( model=Order, select_related=["user", "assigned_to"], # Important! display_fields=[ UserField(name="user", header=True), UserField(name="assigned_to"), ], )
# ✅ Good - External links open in new tab LinkField( name="website", link_field="url", link_target="_blank", # Default ) # ✅ Good - Internal links stay in same tab LinkField( name="related_order", link_field="order_admin_url", link_target="_self", )

4. Choose the Right Avatar Strategy

# For user listings - use AvatarField AvatarField( name="username", photo_field="photo", name_field="full_name", initials_field="first_name", show_as_card=True, # Rich display ) # For ForeignKey relations - use UserField UserField( name="author", # ForeignKey to User header=True, # Show avatar )

5. Image Caption Best Practices

# ✅ Good - Informative captions ImageField( name="qr_code", caption_template="Scan to pay: <code>{address}</code>", ) # ✅ Good - Field-based captions ImageField( name="photo", caption_field="description", ) # ⚠️ OK - Static captions ImageField( name="thumbnail", caption="Product Image", )

Next Steps

Last updated on