How to create a custom Django admin site with Unfold

Learn how to create a custom Django admin site with Unfold, register models with UnfoldAdminSite, configure custom admin URLs, and override the default Django admin site.

  • calendar_month 11.04.2023 Updated: 04.09.2026
  • pace 12 minutes

Django includes a ready-to-use administration interface, but some projects need more control over how the admin site is registered, where it is available, or which models it contains.

Django solves this with the AdminSite class. Django Unfold extends the same concept with UnfoldAdminSite, allowing you to create one or more custom admin sites while keeping the Unfold interface and its functionality.

In this guide, we will create a custom Django admin site with Unfold, register models with it, connect it to a custom URL, and look at how to replace Django's default admin site when needed.

Install Django Unfold

Start by installing django-unfold:

uv add django-unfold

You can also use pip or Poetry:

pip install django-unfold
poetry add django-unfold

For the standard Unfold setup, add unfold before django.contrib.admin:

# settings.py

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

Admin classes should inherit from Unfold's ModelAdmin instead of Django's default ModelAdmin.

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

from .models import Product


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

For the complete setup, see the Unfold installation documentation.

Create a custom Unfold admin site

Unfold provides UnfoldAdminSite, which can be used instead of Django's default AdminSite.

Create a dedicated sites.py file:

# sites.py

from unfold.sites import UnfoldAdminSite


class CustomAdminSite(UnfoldAdminSite):
    pass


custom_admin_site = CustomAdminSite(name="custom_admin")

The name identifies this admin site when Django resolves admin URLs.

You can also customize standard AdminSite properties because UnfoldAdminSite builds on Django's admin site architecture:

# sites.py

from django.utils.translation import gettext_lazy as _
from unfold.sites import UnfoldAdminSite


class CustomAdminSite(UnfoldAdminSite):
    site_title = _("Administration")
    site_header = _("Project administration")
    index_title = _("Dashboard")


custom_admin_site = CustomAdminSite(name="custom_admin")

This gives you a separate Unfold admin site with its own configuration and model registry.

Add the custom admin site to urls.py

Instead of using Django's default admin.site.urls, import the custom site instance:

# urls.py

from django.urls import path

from app.sites import custom_admin_site


urlpatterns = [
    path("admin/", custom_admin_site.urls),
]

The custom Unfold admin site is now available at:

/admin/

The URL itself can be changed to anything required by your project:

urlpatterns = [
    path("backoffice/", custom_admin_site.urls),
]

The admin site would then be available at /backoffice/.

Register models with UnfoldAdminSite

A custom admin site has its own model registry.

This means models have to be registered with custom_admin_site instead of Django's default admin.site.

Use Unfold's ModelAdmin together with Django's @admin.register decorator:

# admin.py

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

from .models import Product
from .sites import custom_admin_site


@admin.register(Product, site=custom_admin_site)
class ProductAdmin(ModelAdmin):
    list_display = ["name", "created_at"]

You can also register a model directly:

from unfold.admin import ModelAdmin

from .models import Product
from .sites import custom_admin_site


class ProductAdmin(ModelAdmin):
    list_display = ["name", "created_at"]


custom_admin_site.register(Product, ProductAdmin)

Using unfold.admin.ModelAdmin is important because Unfold-specific styling and functionality are provided by that class.

Create multiple Unfold admin sites

A Django project can expose more than one admin site.

For example, you might have one administration area for internal staff and another for customers or partners.

Create two instances:

# sites.py

from unfold.sites import UnfoldAdminSite


class InternalAdminSite(UnfoldAdminSite):
    pass


class PartnerAdminSite(UnfoldAdminSite):
    pass


internal_admin_site = InternalAdminSite(name="internal_admin")
partner_admin_site = PartnerAdminSite(name="partner_admin")

Connect both sites in the URL configuration:

# urls.py

from django.urls import path

from app.sites import internal_admin_site, partner_admin_site


urlpatterns = [
    path("admin/", internal_admin_site.urls),
    path("partners/", partner_admin_site.urls),
]

Models can then be registered with one site, both sites, or neither.

@admin.register(Product, site=internal_admin_site)
class InternalProductAdmin(ModelAdmin):
    list_display = ["name", "cost", "created_at"]


@admin.register(Product, site=partner_admin_site)
class PartnerProductAdmin(ModelAdmin):
    list_display = ["name", "created_at"]

This makes it possible to expose different fields, actions, filters, and functionality depending on the administration area.

Customize the admin dashboard

Because UnfoldAdminSite is still based on Django's admin site architecture, you can customize the admin index as well.

For a custom dashboard, create:

templates/admin/index.html

Unfold provides a DASHBOARD_CALLBACK setting for passing additional data into this template:

# settings.py

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

Then define the callback:

# views.py

from .models import Product


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

    return context

The custom value is now available inside the dashboard template.

For a complete walkthrough, see How to build a custom Django admin dashboard.

Override the default Django admin site with Unfold

Creating a separate UnfoldAdminSite instance is useful when you want explicit control over model registration or multiple admin sites.

Another option is to replace Django's default django.contrib.admin.site globally.

This allows existing registrations such as:

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

to keep working without specifying site=custom_admin_site everywhere.

When overriding the default admin site, Unfold must be installed using unfold.apps.BasicAppConfig instead of the regular unfold application.

First create the custom site class:

# sites.py

from unfold.sites import UnfoldAdminSite


class CustomAdminSite(UnfoldAdminSite):
    pass

Create a custom Django AdminConfig:

# apps.py

from django.contrib.admin.apps import AdminConfig


class CustomAdminConfig(AdminConfig):
    default_site = "app.sites.CustomAdminSite"

Then update INSTALLED_APPS:

# settings.py

INSTALLED_APPS = [
    "unfold.apps.BasicAppConfig",
    "app.apps.CustomAdminConfig",  # replaces django.contrib.admin
    # Other applications
]

Your URL configuration can continue using Django's normal admin.site object:

# urls.py

from django.contrib import admin
from django.urls import path


urlpatterns = [
    path("admin/", admin.site.urls),
]

Django will now create the default admin.site using your CustomAdminSite, which inherits from Unfold's UnfoldAdminSite.

Separate admin site or override the default?

Use a separate UnfoldAdminSite instance when:

  • You need multiple admin areas
  • Each admin site should expose different models
  • You want separate URL namespaces
  • Model registrations should explicitly target a specific site

Override the default admin site when:

  • The project only needs one primary admin area
  • Existing admin.site registrations should continue to work
  • You want to replace the default Django admin site globally

For most projects that only need Unfold as the main administration interface, the standard Unfold installation is enough. A custom UnfoldAdminSite is mainly useful when you need multiple admin sites or custom site-level behavior.

Suggested project structure

A project using a custom Unfold admin site can keep the site definition separate from model registrations:

app/
├── __init__.py
├── admin.py
├── models.py
└── sites.py

project/
├── settings.py
└── urls.py

The responsibilities are then clear:

  • sites.py defines the custom UnfoldAdminSite
  • admin.py registers models with the site
  • urls.py exposes the site under a URL
  • settings.py contains the global Unfold configuration

Conclusion

Django Unfold supports custom admin sites through UnfoldAdminSite, so you can use Django's existing AdminSite architecture without giving up the Unfold interface.

For a separate administration area, create an UnfoldAdminSite instance, register models with it, and connect its URLs directly.

If you want to replace Django's default admin.site instead, use a custom AdminConfig together with unfold.apps.BasicAppConfig.

Both approaches let you keep Django's native admin architecture while building more specialized administration interfaces with Unfold.

Django admin theme built with Tailwind CSS to bring modern look and feel to your admin interface. Already contains several built-in features for smooth developer experience.

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