Как зарегистрировать модель в Django Admin
Как зарегистрировать модель в Django Admin: admin.site.register, @admin.register, unregister, свой AdminSite, ошибки AlreadyRegistered и NotRegistered.
Содержание · 12 разделов
- Где регистрировать модели: admin.py и autodiscover
- admin.site.register: три формы вызова
- Декоратор @admin.register
- Как зарегистрировать несколько моделей
- Регистрация в своём AdminSite
- unregister и перерегистрация: User и Group
- Ошибки регистрации и их тексты
- AlreadyRegistered: The model … is already registered
- NotRegistered: The model … is not registered
- ImproperlyConfigured: абстрактная модель
- admin.E039: связанная модель не зарегистрирована
- Модель не видна в админке: чек-лист
- Названия в меню: verbose_name и имя приложения
- Порядок моделей и приложений в меню
- Частые вопросы
- Можно ли зарегистрировать одну модель дважды с разными настройками?
- Как скрыть модель из меню, но оставить её для autocomplete?
- Как разбить большой admin.py на несколько файлов?
- Можно ли регистрировать модели в models.py?
- Как сделать так, чтобы связанные объекты редактировались на странице модели?
- Итог
Чтобы модель появилась в Django Admin, зарегистрируйте её в файле admin.py своего приложения: admin.site.register(Book) или декоратором @admin.register(Book) над классом ModelAdmin. Django сам импортирует admin.py всех приложений из INSTALLED_APPS, поэтому больше ничего подключать не нужно — после перезапуска сервера модель появится на главной странице админки.
# library/admin.py
from django.contrib import admin
from .models import Author, Book
admin.site.register(Author) # стандартный интерфейс
@admin.register(Book) # интерфейс со своими настройками
class BookAdmin(admin.ModelAdmin):
list_display = ["title", "author", "is_available"]
Ниже — все варианты регистрации, свой AdminSite, снятие и замена регистрации встроенных моделей User и Group, реальные тексты ошибок и чек-лист на случай, если модель в админке не видна. Примеры проверены на Django 6.1 и 5.2 LTS. Как включить админку и создать первого администратора, рассказано в полном руководстве по Django Admin.
Где регистрировать модели: admin.py и autodiscover
Команда startapp создаёт в папке приложения, рядом с models.py, файл admin.py с заготовкой from django.contrib import admin — регистрация пишется в нём. Модуль никто не импортирует вручную: при старте проекта приложение django.contrib.admin вызывает admin.autodiscover(), а тот по очереди импортирует модуль admin каждого приложения из INSTALLED_APPS.
Из этого следуют три правила:
- файл должен называться именно
admin.py(или быть пакетомadmin/с__init__.py) и лежать в папке приложения; - приложение должно стоять в
INSTALLED_APPS, иначе егоadmin.pyне загрузится; - модули загружаются в порядке
INSTALLED_APPS— это важно, когда вы снимаете регистрацию чужой модели (об этом ниже, в разделе проunregister()).
Ошибка импорта в admin.py не проходит молча: проект не запустится, а python manage.py check покажет причину, например опечатку в имени модели:
ImportError: cannot import name 'Boook' from 'library.models' (...\library\models.py). Did you mean: 'Book'?
Совет: если автопоиск не нужен, замените в
INSTALLED_APPSстроку"django.contrib.admin"на"django.contrib.admin.apps.SimpleAdminConfig". Тогда модулиadmin.pyне импортируются автоматически: импортируйте их сами или вызовитеadmin.autodiscover()там, где это нужно.
admin.site.register: три формы вызова
admin.site — сайт админки по умолчанию, тот, что подключён в urls.py строкой path("admin/", admin.site.urls). Его метод register() принимает модель (или список моделей), необязательный класс ModelAdmin и необязательные опции.
Только модель. Django подставит базовый ModelAdmin: список с одной колонкой (результат __str__), форма со всеми редактируемыми полями. Для справочников этого часто достаточно:
admin.site.register(Author)
Модель и класс настроек. Класс наследуется от admin.ModelAdmin и описывает колонки списка, фильтры, поиск, форму:
class BookAdmin(admin.ModelAdmin):
list_display = ["title", "author", "is_available"]
list_filter = ["is_available"]
search_fields = ["title"]
admin.site.register(Book, BookAdmin)
Модель и опции без класса. Именованные аргументы превращаются в атрибуты класса, который Django создаст сам:
admin.site.register(Genre, list_display=["name"], search_fields=["name"])
type(admin.site.get_model_admin(Genre)).__name__ # → 'GenreAdmin'
Третья форма удобна для пары опций, но как только настроек становится больше, отдельный класс читается лучше. Все опции ModelAdmin — колонки, фильтры, формы, инлайны — собраны в упомянутом выше руководстве.
Декоратор @admin.register
Декоратор делает то же самое, что admin.site.register(Book, BookAdmin), но регистрация стоит прямо над классом и не теряется в конце файла:
@admin.register(Book)
class BookAdmin(admin.ModelAdmin):
list_display = ["title", "author", "is_available"]
Декоратор принимает несколько моделей и именованный аргумент site — сайт админки, если он не стандартный:
@admin.register(Genre, Publisher) # один класс настроек на две модели
class DictionaryAdmin(admin.ModelAdmin):
list_display = ["name"]
search_fields = ["name"]
Класс под декоратором обязан наследоваться от admin.ModelAdmin. Если забыть базовый класс, проект не запустится:
ValueError: Wrapped class must subclass ModelAdmin.
| Способ | Когда подходит |
|---|---|
admin.site.register(Model) | справочник, которому хватает стандартного интерфейса |
admin.site.register(Model, Admin) | класс настроек описан в другом модуле или переиспользуется |
admin.site.register(Model, **opts) | одна-две опции, отдельный класс избыточен |
@admin.register(Model) | основной вариант для модели со своим ModelAdmin |
@admin.register(Model, site=...) | регистрация в собственном AdminSite |
Как зарегистрировать несколько моделей
register() принимает не только модель, но и список. Так удобно подключать справочники одной строкой:
admin.site.register([Genre, Publisher])
Если у моделей общие настройки, передайте их в декоратор вместе, как в примере с DictionaryAdmin выше.
Чтобы зарегистрировать все модели приложения, переберите их через реестр приложений и пропустите уже зарегистрированные — иначе получите AlreadyRegistered:
from django.apps import apps
from django.contrib import admin
from .models import Book
@admin.register(Book)
class BookAdmin(admin.ModelAdmin):
list_display = ["title", "author", "is_available"]
# Остальные модели приложения — со стандартным ModelAdmin
for model in apps.get_app_config("library").get_models():
if not admin.site.is_registered(model):
admin.site.register(model)
Цикл стоит в конце файла, после всех явных регистраций. Пользуйтесь им осторожно: в админку попадут и служебные модели, которые редакторам видеть не нужно.
Регистрация в своём AdminSite
Второй сайт админки нужен, когда разным сотрудникам требуется отдельный интерфейс со своим набором моделей и своим адресом: например, каталог для контент-менеджеров рядом с основной админкой. Создайте экземпляр AdminSite и регистрируйте модели в нём, а не в admin.site:
# library/admin.py
from django.contrib import admin
from .models import Author, Book
class LibraryAdminSite(admin.AdminSite):
site_header = "Библиотека: каталог"
site_title = "Каталог"
index_title = "Разделы каталога"
library_site = LibraryAdminSite(name="library_admin")
@admin.register(Book, site=library_site)
class BookAdmin(admin.ModelAdmin):
list_display = ["title", "author"]
library_site.register(Author)
# config/urls.py
from django.contrib import admin
from django.urls import path
from library.admin import library_site
urlpatterns = [
path("admin/", admin.site.urls),
path("catalog/", library_site.urls),
]
Модели из library_site открываются по адресу /catalog/ и не появляются в /admin/ — у каждого сайта свой реестр. Имя сайта задаёт пространство имён URL: reverse("library_admin:library_book_changelist") вернёт /catalog/library/book/.
Стандартный сайт тоже можно заменить своим классом, например чтобы поменять порядок моделей во всей админке. Для этого служит AdminConfig.default_site — пример есть ниже, в разделе о порядке. Как AdminSite строит маршруты и как добавить на сайт свои страницы, разобрано в статье «Как устроен Django Admin».
unregister и перерегистрация: User и Group
Встроенные модели уже зарегистрированы приложением django.contrib.auth. Чтобы убрать их из админки или заменить настройки, сначала снимите регистрацию методом unregister().
Убрать «Группы» из меню:
# library/admin.py
from django.contrib import admin
from django.contrib.auth.models import Group
admin.site.unregister(Group)
Заменить интерфейс пользователей своим: наследуйтесь от UserAdmin, чтобы сохранить формы смены пароля и наборы полей, и зарегистрируйте модель заново:
from django.contrib import admin
from django.contrib.auth.admin import GroupAdmin, UserAdmin
from django.contrib.auth.models import Group, User
admin.site.unregister(User)
admin.site.unregister(Group)
@admin.register(User)
class MyUserAdmin(UserAdmin):
list_display = ["username", "email", "is_staff", "last_login"]
list_filter = ["is_staff", "is_active", "groups"]
@admin.register(Group)
class MyGroupAdmin(GroupAdmin):
list_display = ["name", "users_count"]
@admin.display(description="Пользователей")
def users_count(self, obj):
return obj.user_set.count()
Код работает, только если приложение с ним стоит в INSTALLED_APPS ниже django.contrib.auth. Если поставить его выше, admin.py загрузится раньше, чем auth зарегистрирует свои модели, и проект упадёт с NotRegistered.
С собственной моделью пользователя (AUTH_USER_MODEL) встроенный User заменён, и Django его в админке не регистрирует. Свою модель нужно зарегистрировать самостоятельно, обычно с подклассом UserAdmin.
Проверить состояние реестра можно в shell:
python manage.py shell -v0 -c "from django.contrib import admin; from library.models import Book; print(admin.site.is_registered(Book), admin.site.get_model_admin(Book))"
# → True library.BookAdmin
На macOS и Linux вместо python может понадобиться python3. Метод is_registered() отвечает, есть ли модель в реестре, а get_model_admin() возвращает её экземпляр ModelAdmin или выбрасывает NotRegistered.
Ошибки регистрации и их тексты
Все ошибки ниже возникают при запуске проекта, ещё до первого запроса: их покажут runserver, migrate и python manage.py check.
AlreadyRegistered: The model … is already registered
Модель регистрируют второй раз в одном и том же сайте. Текст зависит от того, как прошла первая регистрация. Если без своего класса:
django.contrib.admin.exceptions.AlreadyRegistered: The model Book is already registered in app 'library'.
Если с классом BookAdmin:
django.contrib.admin.exceptions.AlreadyRegistered: The model Book is already registered with 'library.BookAdmin'.
Частые причины:
- над классом стоит
@admin.register(Book), а в конце файла осталсяadmin.site.register(Book, BookAdmin)— оставьте что-то одно; - модель уже зарегистрировало другое приложение. Для встроенного пользователя это выглядит так:
The model User is already registered with 'auth.UserAdmin'.Сначала вызовитеadmin.site.unregister(User); - цикл автоматической регистрации стоит раньше явной регистрации — перенесите его в конец файла или проверяйте
is_registered().
NotRegistered: The model … is not registered
unregister() вызван для модели, которой нет в реестре:
django.contrib.admin.exceptions.NotRegistered: The model Group is not registered
Обычно приложение с unregister() стоит в INSTALLED_APPS выше того, что регистрирует модель. Переставьте его ниже. Та же ошибка (с точкой в конце) возникает при вызове admin.site.get_model_admin() для незарегистрированной модели.
ImproperlyConfigured: абстрактная модель
Абстрактную модель (abstract = True в Meta) зарегистрировать нельзя — у неё нет таблицы:
django.core.exceptions.ImproperlyConfigured: The model TimeStamped is abstract, so it cannot be registered with admin.
Регистрируйте конкретных наследников. Модели с составным первичным ключом (CompositePrimaryKey, появился в Django 5.2) админка тоже пока не поддерживает: register() для них выбрасывает ImproperlyConfigured с текстом has a composite primary key, so it cannot be registered with admin.
admin.E039: связанная модель не зарегистрирована
autocomplete_fields работает через поиск по связанной модели, поэтому она обязана быть зарегистрирована и иметь search_fields. Если регистрации нет, проверка проекта остановит запуск:
<class 'library.admin.BookAdmin'>: (admin.E039) An admin for model "Author" has to be registered to be referenced by BookAdmin.autocomplete_fields.
Модель не видна в админке: чек-лист
Пройдите пункты по порядку — каждый отсекает отдельную причину.
- Приложение в
INSTALLED_APPS. Без негоadmin.pyне загрузится. Если модели этого приложения импортируются откуда-то ещё, Django сообщит прямо:RuntimeError: Model class library.models.Author doesn't declare an explicit app_label and isn't in an application in INSTALLED_APPS. - Регистрация в правильном файле и сайте. Файл называется
admin.py, лежит в папке приложения, вызовregister()не закомментирован и не спрятан под условием. Если модель зарегистрирована в своёмAdminSite, искать её нужно по адресу этого сайта, а не в/admin/. Быстрая проверка —admin.site.is_registered(Model)вshell. - Сервер перезапущен.
runserverперезагружается сам при сохранении файла, а Gunicorn, uWSGI и контейнеры — нет: после деплоя их нужно перезапустить. - Миграции применены. Без таблицы модель всё равно появится в меню, но список упадёт с
OperationalError: no such table: library_book(текст для SQLite). Выполнитеpython manage.py makemigrationsиpython manage.py migrate— подробнее в статье о миграциях Django. - У пользователя
is_staff=True. Без флага админка не пускает дальше формы входа: «Пожалуйста, введите корректные имя пользователя и пароль учётной записи…» Флаг ставится в карточке пользователя или вshell; первого администратора создают командой createsuperuser. - Есть право хотя бы на просмотр. Сотрудник без прав видит главную страницу с сообщением «У вас недостаточно полномочий для просмотра или изменения чего либо.» Модель появляется в меню, когда у пользователя или его группы есть одно из прав
view_,add_,change_илиdelete_на неё. Как выдавать права через группы, разобрано в статье о правах доступа в Django. ModelAdminне прячет модель. Переопределённыеhas_module_permission()илиget_model_perms(), которые возвращаютFalseили пустой словарь, убирают модель из меню даже у суперпользователя.
Названия в меню: verbose_name и имя приложения
Админка не берёт имена из кода класса. Название модели в меню — это verbose_name_plural из Meta с заглавной буквы, заголовок блока — verbose_name конфигурации приложения:
# library/models.py
class Book(models.Model):
title = models.CharField("Название", max_length=300)
class Meta:
verbose_name = "книга"
verbose_name_plural = "книги"
# library/apps.py
from django.apps import AppConfig
class LibraryConfig(AppConfig):
default_auto_field = "django.db.models.BigAutoField"
name = "library"
verbose_name = "Библиотека"
Без этих настроек блок называется по метке приложения (Library), модель — по имени класса (Books). Если указать только verbose_name = "книга", Django допишет к нему латинскую s и в меню появится «Книгаs», поэтому для русских названий всегда задавайте обе формы. Поля Meta подробно описаны в статье о моделях Django.
Порядок моделей и приложений в меню
Порядок вызовов register() на меню не влияет. Django сортирует приложения по verbose_name, а модели внутри приложения — по verbose_name_plural, в обоих случаях по алфавиту. Проект с примерами выше выглядит так:
Библиотека
Авторы
Жанры
Издательства
Книги
Пользователи и группы
Группы
Пользователи
Сортировку выполняет метод AdminSite.get_app_list(). Чтобы задать свой порядок, переопределите его в подклассе AdminSite:
# config/admin.py
from django.contrib import admin
# Метка приложения -> имена классов моделей в нужном порядке
MODEL_ORDER = {
"library": ["Book", "Author", "Genre", "Publisher"],
}
class OrderedAdminSite(admin.AdminSite):
def get_app_list(self, request, app_label=None):
app_list = super().get_app_list(request, app_label)
for app in app_list:
order = MODEL_ORDER.get(app["app_label"])
if order:
app["models"].sort(
key=lambda m: order.index(m["object_name"])
if m["object_name"] in order
else len(order)
)
return app_list
И сделайте этот класс сайтом по умолчанию — тогда admin.site во всех admin.py станет экземпляром OrderedAdminSite, и менять регистрации не придётся:
# config/apps.py
from django.contrib.admin.apps import AdminConfig
class OrderedAdminConfig(AdminConfig):
default_site = "config.admin.OrderedAdminSite"
# settings.py
INSTALLED_APPS = [
"config.apps.OrderedAdminConfig", # вместо "django.contrib.admin"
"django.contrib.auth",
# ...
]
После этого «Книги» стоят первыми и на главной, и на странице приложения, и в боковом меню. Модели, которых нет в MODEL_ORDER, уходят в конец. Порядок самих приложений меняется так же — сортировкой списка app_list.
Встречается и обходной путь: цифры в начале verbose_name_plural («1. Книги»). Он работает без кода, но цифры видны пользователям и попадают во все сообщения админки.
Частые вопросы
Можно ли зарегистрировать одну модель дважды с разными настройками?
В одном сайте — нет, это AlreadyRegistered. Создайте прокси-модель (proxy = True в Meta) и зарегистрируйте её отдельно: у неё своя строка в меню, свой ModelAdmin и, при необходимости, своя выборка в get_queryset(). Прокси-модель требует миграции, но таблицу не создаёт.
class AvailableBook(Book):
class Meta:
proxy = True
verbose_name = "книга в наличии"
verbose_name_plural = "книги в наличии"
Как скрыть модель из меню, но оставить её для autocomplete?
Верните пустой словарь из get_model_perms(). Модель исчезнет из меню, но останется зарегистрированной: autocomplete_fields в других ModelAdmin и прямые ссылки продолжат работать, права пользователей не изменятся.
@admin.register(Author)
class AuthorAdmin(admin.ModelAdmin):
search_fields = ["name"]
def get_model_perms(self, request):
return {}
Как разбить большой admin.py на несколько файлов?
Превратите модуль в пакет: папка admin/ с файлами books.py, authors.py и __init__.py, который их импортирует (from . import authors, books). Autodiscover импортирует library.admin, а регистрация из подмодулей выполнится при импорте пакета.
Можно ли регистрировать модели в models.py?
Технически вызов сработает, но так смешиваются слой данных и интерфейс, а импорт admin в models.py легко приводит к циклическим импортам. Держите регистрацию в admin.py — там её ищут и другие разработчики, и инструменты вроде autodiscover.
Как сделать так, чтобы связанные объекты редактировались на странице модели?
Регистрировать связанную модель для этого не обязательно: её добавляют в inlines родительского ModelAdmin. Варианты TabularInline и StackedInline разобраны в статье об инлайнах в Django Admin.
Итог
Модель регистрируют в admin.py приложения: admin.site.register(Model) для стандартного интерфейса, @admin.register(Model) над своим ModelAdmin — для настроенного. Встроенные User и Group перед заменой снимают через unregister() из приложения, стоящего в INSTALLED_APPS ниже django.contrib.auth. Если модель не видна, проверьте по чек-листу INSTALLED_APPS, регистрацию, миграции, is_staff и права view. Названия в меню задаются через verbose_name, а порядок — переопределением get_app_list() в своём AdminSite. Остальные статьи кластера собраны в разделе Django Admin.
- #Django Admin
- #ModelAdmin
- #AdminSite
- #Админка Django
- #Django