How to customize Django admin with Unfold

Learn how to customize Django admin with Unfold using custom branding, navigation, filters, tabs, actions, dashboards, components, forms, and custom pages.

  • calendar_month 04.09.2026
  • pace 12 minutes

Django admin is a powerful starting point for internal tools and back-office applications, but the default interface is intentionally generic. Most real projects eventually need better navigation, clearer forms, richer filters, custom actions, dashboards, branding, or completely custom admin pages.

Django Unfold extends the standard Django admin instead of replacing it. You continue using familiar concepts such as ModelAdmin, forms, permissions, URLs, and templates while adding a more modern interface and additional customization options.

This guide shows how to customize Django admin with Unfold, starting with the overall appearance and navigation and then moving into model pages, filters, actions, forms, dashboards, and custom views.

Install Django Unfold

Install the package with your preferred Python package manager:

uv add django-unfold

You can also use pip or Poetry:

pip install django-unfold
poetry add django-unfold

Add Unfold before django.contrib.admin in INSTALLED_APPS:

# settings.py

INSTALLED_APPS = [
    "unfold",
    "django.contrib.admin",
    # Other applications
]

Then inherit your admin classes from Unfold's ModelAdmin:

# admin.py

from django.contrib import admin
from unfold.admin import ModelAdmin

from .models import Product


@admin.register(Product)
class ProductAdmin(ModelAdmin):
    pass

This keeps the normal Django admin registration flow while enabling Unfold styling and functionality.

For the complete setup, see the Unfold installation documentation.

Customize Django admin branding

Most global Unfold customization is configured through the UNFOLD dictionary in settings.py.

You can change the site title, sidebar heading, subheading, logo, icon, and other identity-related settings without overriding Django admin templates.

# settings.py

from django.templatetags.static import static


UNFOLD = {
    "SITE_TITLE": "Acme admin",
    "SITE_HEADER": "Acme",
    "SITE_SUBHEADER": "Administration",
    "SITE_SYMBOL": "settings",
    "SITE_ICON": {
        "light": lambda request: static("icon-light.svg"),
        "dark": lambda request: static("icon-dark.svg"),
    },
    "SITE_LOGO": {
        "light": lambda request: static("logo-light.svg"),
        "dark": lambda request: static("logo-dark.svg"),
    },
}

This is usually enough to make the admin feel like part of your own product instead of a separate Django interface.

Unfold can also configure favicons, site links, login-page behavior, environment labels, and other site-level options.

See the Unfold settings documentation for all available values.

Customize colors and dark mode

Unfold includes light and dark themes and allows the overall visual system to be adjusted from settings.

For example, you can force a specific theme:

UNFOLD = {
    "THEME": "dark",
}

When THEME is not forced, users can switch between the available appearance modes from the interface.

You can also customize the primary and base color palettes, border radius, and font colors through the COLORS and BORDER_RADIUS settings.

UNFOLD = {
    "BORDER_RADIUS": "6px",
}

For a complete color palette configuration, use the values documented in Unfold settings.

If you need deeper styling changes, Unfold also supports project-level CSS and Tailwind customization, which we will cover later in this guide.

Customize sidebar navigation

Navigation is one of the biggest differences between the default Django admin and a more complete internal tool.

Unfold lets you define your own sidebar structure instead of relying only on Django's automatically generated application list.

# settings.py

from django.urls import reverse_lazy
from django.utils.translation import gettext_lazy as _


UNFOLD = {
    "SIDEBAR": {
        "show_search": True,
        "show_all_applications": False,
        "navigation": [
            {
                "title": _("Navigation"),
                "separator": True,
                "collapsible": False,
                "items": [
                    {
                        "title": _("Dashboard"),
                        "icon": "dashboard",
                        "link": reverse_lazy("admin:index"),
                    },
                    {
                        "title": _("Products"),
                        "icon": "inventory_2",
                        "link": reverse_lazy(
                            "admin:shop_product_changelist"
                        ),
                    },
                    {
                        "title": _("Orders"),
                        "icon": "shopping_cart",
                        "link": reverse_lazy(
                            "admin:shop_order_changelist"
                        ),
                    },
                ],
            },
        ],
    },
}

Navigation groups can be collapsible and can contain icons, permissions, badges, custom HTML attributes, and links to registered models or custom admin pages.

This makes it possible to organize the sidebar around workflows instead of exposing Django applications exactly as they are structured in code.

Add navigation badges

Sidebar items can display dynamic badges.

For example, you might show the number of pending orders next to the Orders navigation item.

UNFOLD = {
    "SIDEBAR": {
        "navigation": [
            {
                "title": "Sales",
                "items": [
                    {
                        "title": "Orders",
                        "icon": "shopping_cart",
                        "link": reverse_lazy(
                            "admin:shop_order_changelist"
                        ),
                        "badge": "shop.admin.pending_orders_badge",
                        "badge_variant": "warning",
                    },
                ],
            },
        ],
    },
}

The callback can return a value calculated from your application:

# admin.py

from .models import Order


def pending_orders_badge(request):
    return Order.objects.filter(status="pending").count()

Badges are useful for queues, approvals, failed jobs, unread items, or anything else administrators need to notice quickly.

Customize Django admin list views

Unfold still uses Django's familiar ModelAdmin API, so standard options such as list_display, search_fields, ordering, and list_per_page continue to work.

@admin.register(Product)
class ProductAdmin(ModelAdmin):
    list_display = [
        "name",
        "category",
        "price",
        "is_active",
        "created_at",
    ]
    search_fields = ["name", "sku"]
    ordering = ["-created_at"]
    list_per_page = 50

This means you can improve an existing Django admin incrementally. You do not have to rebuild your model administration classes when adopting Unfold.

The difference is that Unfold adds additional UI features on top of these native Django options.

Add advanced filters

The default Django admin filter system works well for basic choices, but more complex internal tools often need text inputs, numeric ranges, date ranges, dropdowns, or autocomplete filters.

Unfold provides these through unfold.contrib.filters.

Add the optional application:

# settings.py

INSTALLED_APPS = [
    "unfold",
    "unfold.contrib.filters",
    "django.contrib.admin",
]

Then use one of the Unfold filter classes:

# admin.py

from django.contrib import admin
from unfold.admin import ModelAdmin
from unfold.contrib.filters.admin import FieldTextFilter

from .models import Product


@admin.register(Product)
class ProductAdmin(ModelAdmin):
    list_filter_submit = True
    list_filter = [
        ("name", FieldTextFilter),
    ]

list_filter_submit = True adds a submit button for filters that use input fields.

Unfold includes filter types for common cases such as:

  • Text search
  • Dropdowns
  • Multiple selections
  • Numeric values and ranges
  • Date and datetime ranges
  • Autocomplete inputs
  • Checkboxes and radio buttons

See the Unfold filters documentation for the complete list.

Organize forms with tabs

Large Django admin forms can become difficult to scan when they contain many fieldsets and inlines.

Unfold adds tab navigation so related groups can be separated visually without splitting the object into multiple pages.

Tabs can be configured for changelists and change forms through the TABS setting.

# settings.py

from django.urls import reverse_lazy
from django.utils.translation import gettext_lazy as _


UNFOLD = {
    "TABS": [
        {
            "models": [
                "shop.product",
            ],
            "items": [
                {
                    "title": _("Products"),
                    "link": reverse_lazy(
                        "admin:shop_product_changelist"
                    ),
                },
                {
                    "title": _("Categories"),
                    "link": reverse_lazy(
                        "admin:shop_category_changelist"
                    ),
                },
            ],
        },
    ],
}

Tabs can also be generated dynamically with a callback when the navigation depends on the current request or object.

For more details, see the documentation for changelist tabs and dynamic tabs.

Show fields conditionally

Complex forms often contain fields that only make sense when another option is enabled.

Unfold supports conditional fields using Alpine.js expressions.

# admin.py

from django.contrib import admin
from unfold.admin import ModelAdmin

from .models import Customer


@admin.register(Customer)
class CustomerAdmin(ModelAdmin):
    conditional_fields = {
        "company_name": "is_company == true",
        "company_id": "is_company == true",
    }

The dependent fields are shown or hidden immediately based on the values in the form.

This is useful for:

  • Billing options
  • Company-specific information
  • Delivery settings
  • Optional metadata
  • Status-dependent form sections

Conditional fields help reduce visual clutter and make large Django admin forms easier to understand.

See conditional fields for more examples.

Customize inlines

Unfold provides its own inline classes that extend Django's standard inline administration.

from unfold.admin import TabularInline

from .models import OrderItem


class OrderItemInline(TabularInline):
    model = OrderItem

On top of regular Django inline behavior, Unfold supports additional capabilities such as sortable and paginated inlines.

Sortable inlines

For models with a position field, records can be reordered directly from the admin interface:

from unfold.admin import TabularInline


class ProductImageInline(TabularInline):
    model = ProductImage
    ordering_field = "position"
    hide_ordering_field = True

The ordering field should be backed by an appropriate model field, such as a PositiveIntegerField.

Paginated inlines

Large related datasets can be divided into pages:

from unfold.admin import TabularInline


class OrderItemInline(TabularInline):
    model = OrderItem
    per_page = 20

This can significantly improve usability when a parent object has hundreds of related records.

See the sortable inline and paginated inline documentation for complete configuration details.

Add custom actions

Django actions are useful for bulk operations, but important actions are often hidden inside the standard action dropdown.

Unfold extends Django actions and allows them to appear in different parts of the interface.

# admin.py

from django.contrib import admin
from django.db.models import QuerySet
from django.http import HttpRequest
from unfold.admin import ModelAdmin
from unfold.decorators import action

from .models import Product


@admin.register(Product)
class ProductAdmin(ModelAdmin):
    actions_list = ["publish"]

    @action(description="Publish", icon="publish")
    def publish(
        self,
        request: HttpRequest,
        queryset: QuerySet,
    ):
        queryset.update(is_active=True)

Unfold supports several action locations:

  • Global changelist actions
  • Row actions
  • Detail-page actions
  • Submit-line actions

Actions can also use icons, visual variants, custom permissions, and custom URLs.

This makes important workflows much more visible than keeping every operation in a single dropdown.

See the Unfold actions documentation for all action types.

Build a custom Django admin dashboard

The default Django admin homepage mainly acts as navigation. With Unfold, you can turn it into a dashboard for your application.

Create:

templates/admin/index.html

and configure a callback:

# settings.py

UNFOLD = {
    "DASHBOARD_CALLBACK": "app.views.dashboard_callback",
}

The callback can pass your own application data into the template:

# views.py

from shop.models import Order, Product


def dashboard_callback(request, context):
    context.update(
        {
            "orders_count": Order.objects.count(),
            "products_count": Product.objects.count(),
        }
    )

    return context

You can then render the values using Unfold components, charts, tables, cards, and your own templates.

For a complete implementation, read How to build a custom Django admin dashboard with Unfold.

Build dashboards with Unfold components

Unfold includes a reusable component library for building custom interfaces that match the rest of the admin.

Available components include elements such as:

  • Cards
  • Tables
  • Charts
  • Buttons
  • Links
  • Progress indicators
  • Trackers
  • Cohort visualizations

For example, a simple card can be rendered directly from a Django template:

{% load unfold %}

{% component "unfold/components/card.html" with title="Orders" %}
    {{ orders_count }}
{% endcomponent %}

Components are useful beyond dashboards. They can also be used in custom views and other templates where you want to preserve the same design system.

See the Unfold components documentation for available components and examples.

Create custom admin pages

Not every internal workflow belongs to a ModelAdmin changelist or change form.

Unfold provides UnfoldModelAdminViewMixin for creating custom pages that remain visually integrated with the admin interface.

# admin.py

from django.urls import path
from django.views.generic import TemplateView
from unfold.admin import ModelAdmin
from unfold.views import UnfoldModelAdminViewMixin


class SalesReportView(
    UnfoldModelAdminViewMixin,
    TemplateView,
):
    title = "Sales report"
    permission_required = ()
    template_name = "admin/sales_report.html"


class ProductAdmin(ModelAdmin):
    def get_urls(self):
        custom_view = self.admin_site.admin_view(
            SalesReportView.as_view(model_admin=self)
        )

        return super().get_urls() + [
            path(
                "sales-report/",
                custom_view,
                name="sales_report",
            ),
        ]

The page template can extend the regular Unfold admin layout and use the same components as dashboards.

Custom pages are useful for:

  • Reports
  • Import or export workflows
  • Configuration screens
  • Operational tools
  • Data summaries
  • Multi-step internal workflows

See the custom pages documentation for a full example.

Add custom styles and JavaScript

When configuration and components are not enough, Unfold allows project-level styles and scripts to be loaded globally.

# settings.py

from django.templatetags.static import static


UNFOLD = {
    "STYLES": [
        lambda request: static("css/admin.css"),
    ],
    "SCRIPTS": [
        lambda request: static("js/admin.js"),
    ],
}

This is useful for small design adjustments or interactions that are specific to your project.

For larger UI work, Unfold can also be combined with a project-level Tailwind stylesheet so your own templates can use the same utility-based workflow as the rest of the interface.

Avoid overriding large parts of the generated admin HTML when a configuration option, component, or template block can solve the same problem more cleanly.

Use a custom Unfold admin site

If your project needs multiple admin areas or custom site-level behavior, Unfold provides UnfoldAdminSite.

# sites.py

from unfold.sites import UnfoldAdminSite


class CustomAdminSite(UnfoldAdminSite):
    pass


custom_admin_site = CustomAdminSite(
    name="custom_admin",
)

This is useful when different groups of users need different model registries, URLs, or administration interfaces.

We cover this separately in How to create a custom Django admin site with Unfold.

Customize Django admin without rebuilding it

The main advantage of Unfold is that these customizations remain built on top of Django admin.

You still use:

  • Django models
  • Django permissions
  • ModelAdmin
  • Django forms
  • Admin URLs
  • Admin templates
  • Existing third-party Django packages

Unfold changes how those pieces are presented and adds tools for workflows that would otherwise require more template, CSS, and JavaScript work.

This makes it possible to start with a standard Django admin and progressively turn it into a more complete internal application.

Go further with Unfold Studio

If you want to customize the visual identity further or start from complete dashboard examples, Unfold Studio provides premium tools and examples built specifically for Unfold.

Studio is useful when you want to move faster on branding and dashboard implementation while keeping the underlying functionality in Django and Unfold.

You can also explore the Unfold live demo to see dashboards, filters, actions, forms, navigation, and other customization options working together.

Django admin customization FAQ

Can I customize Django admin with Unfold without replacing Django admin?

Yes. Unfold builds on Django admin and uses the same ModelAdmin, models, forms, permissions, and URL architecture. Existing admin configuration can usually be migrated incrementally.

How do I change Django admin colors and branding?

Use the UNFOLD settings to configure site titles, logos, icons, color palettes, border radius, and theme behavior. Custom CSS can also be loaded for project-specific adjustments.

Can I customize Django admin navigation?

Yes. Unfold provides configurable sidebar navigation with groups, icons, permissions, badges, collapsible sections, and links to model pages or custom views.

Can I add a dashboard to Django admin?

Yes. Unfold supports custom admin/index.html templates together with DASHBOARD_CALLBACK for injecting application data. Its component library can be used to build cards, charts, tables, and other dashboard elements.

Can I create custom pages inside Django admin?

Yes. Unfold provides view mixins and templates for adding custom admin pages while preserving the existing sidebar, permissions, design system, and other admin UI.

Can I add advanced filters to Django admin?

Yes. Unfold adds filter classes for text inputs, dropdowns, numeric ranges, date ranges, autocomplete fields, checkboxes, and other filtering patterns beyond Django's default filters.

Conclusion

Django admin customization with Unfold can range from a few branding settings to a complete internal application with custom navigation, dashboards, advanced filters, dynamic forms, actions, and dedicated admin pages.

You do not have to implement everything at once. Start by replacing the default ModelAdmin classes with Unfold, configure the site branding and navigation, and then add the features that solve real workflow problems for your users.

Because Unfold keeps Django's administration architecture underneath, your project can become significantly more customized without giving up the models, permissions, forms, and admin APIs that already make Django productive.

© 2023 - 2026 Created by unfoldadmin.com. All rights reserved.