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.
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.
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.
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.
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/.
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.
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.
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.
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.
Use a separate UnfoldAdminSite instance when:
Override the default admin site when:
admin.site registrations should continue to workFor 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.
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 UnfoldAdminSiteadmin.py registers models with the siteurls.py exposes the site under a URLsettings.py contains the global Unfold configurationDjango 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.