Когда вы впервые открываете административную панель Django, создаётся ощущение, будто вы заглянули внутрь скрытой части своего проекта. Здесь можно управлять данными, моделями, пользователями — и именно в этот момент часто возникает желание сделать админку максимально удобной. Ведь если ваш проект растёт, работать с «сырым» списком записей становится всё сложнее.
В этом уроке мы научимся настраивать отображение списков моделей на примере проекта cinemahub, где у нас уже есть модель фильмов, категорий и другие сущности. Мы будем работать с моделью Movie, но при желании студент сможет повторить те же шаги для любой другой модели.
Основная задача урока — сделать список фильмов в админ-панели удобным, информативным и понятным. Это важный навык, который пригодится в каждом реальном Django-проекте.
Предположим, у нас есть следующая модель фильма:
class Movie(models.Model):
title = models.CharField(max_length=255, verbose_name="Название")
description = models.TextField(blank=True, verbose_name="Описание")
release_year = models.PositiveIntegerField(verbose_name="Год выпуска")
is_published = models.BooleanField(default=True, verbose_name="Опубликовано")
category = models.ForeignKey(
'Category',
on_delete=models.PROTECT,
related_name='movies',
verbose_name="Категория"
)
created_at = models.DateTimeField(auto_now_add=True, verbose_name="Добавлено")
class Meta:
verbose_name = "Фильм"
verbose_name_plural = "Фильмы"
ordering = ['-created_at']Теперь наша задача — сделать так, чтобы фильм в списке админки отображался красиво и удобно.
Открываем файл cinemahub/admin.py и начинаем настройку.
- ID
- название
- год выхода
- статус публикации
- дата добавления
Создаём класс администратора:
from django.contrib import admin
from .models import Movie
@admin.register(Movie)
class MovieAdmin(admin.ModelAdmin):
list_display = ('id', 'title', 'release_year', 'is_published', 'created_at')
list_display_links = ('id', 'title')- list_display — набор полей, которые будут отображаться в таблице.
- list_display_links — по каким полям можно кликнуть для перехода на страницу редактирования.
После сохранения файла:
- Переходим в браузере → http://127.0.0.1:8000/admin/
- Открываем раздел Фильмы.
- Видим обновлённый список.
Если вы не видите никаких изменений — перезапустите сервер. Иногда Django «залипает» на кэше.
По умолчанию Django сортирует записи по первичному ключу. Это не всегда удобно.
Допустим, мы хотим сортировать фильмы:
- сначала по году выхода,
- затем по названию.
Добавляем:
ordering = ['-release_year', 'title']Теперь последние фильмы отображаются первыми.
Обновляем страницу списка фильмов — порядок изменился.
Хотим, чтобы вместо «is published» отображалось «Опубликовано»?
Это уже сделано через verbose_name, но иногда поля в списке могут выводиться в сыром виде, если мы выводим методы или вычисляемые значения.
Django автоматически подставляет verbose_name внутри админки, поэтому нам важно указывать их в модели. Студент должен привыкнуть: чем аккуратнее оформлены verbose-names — тем чище будет админка.
Часто вместе со списком фильмов в админке нужны также категории:
from django.contrib import admin
from .models import Category
@admin.register(Category)
class CategoryAdmin(admin.ModelAdmin):
list_display = ('id', 'name')
list_display_links = ('id', 'name')Обновляем страницу — видим категорию в панели управления.
Одно из сильнейших преимуществ Django admin — возможность редактировать поля без перехода в карточку записи.
Вы, например, хотите управлять статусом публикации фильма прямо в списке.
Добавляем:
# movies/admin.py
list_editable = ('is_published',)Теперь:
- поле «Опубликовано» становится редактируемым,
- можно менять статус по нескольким фильмам сразу,
- изменения отправляются кнопкой Сохранить.
Поля из list_editable не могут быть в list_display_links.
То есть is_published не должно быть ссылкой.
Если нарушить правило — появится ошибка:
The value of 'list_editable' cannot be in list_display_links.
Это частая ошибка новичков, обязательно объясните её студентам.
Мы уже добавили поле category в модель.
Теперь можно отобразить категорию фильма прямо в списке:
list_display = ('id', 'title', 'release_year', 'category', 'is_published', 'created_at')
list_editable = ('category', 'is_published')В админке теперь появится удобное выпадающее меню с категориями — можно менять их прямо в общем списке.
Если фильмов много, имеет смысл ограничить вывод:
list_per_page = 10Теперь Django показывает только 10 записей на странице и подгружает постраничную навигацию.
Что должен увидеть студент?
- Обновлённый список фильмов.
- Новые колонки.
- Сортировка по году.
- Выпадающие списки категорий.
- Возможность редактировать публикацию.
- Пагинацию.
Это важный навык — настроить админку так, чтобы ей было приятно пользоваться.
The value of 'list_editable' cannot be in list_display_links
Причина: Поле одновременно редактируемое и кликабельное.
Решение:
Убираем его из list_display_links.
Причина:
В модели указано ordering в Meta, а в админке — другое.
Решение: Уточнить порядок либо в модели, либо в классе администратора.
Причина:
Поле не добавлено в list_display.
Частая ошибка — неправильный импорт:
from models import Movie # ❌ неправильноПравильно:
from .models import MovieВ классе-модели забыли переопределить метод str. Для решения нужно добавить метод str, который возвращает имя категории.
def __str__(self):
return self.nameДобавьте в список фильмов поле release_year, если его ещё нет.
Сделайте так, чтобы оно отображалось между названием и статусом публикации.
Сделайте поле category редактируемым прямо в списке — чтобы можно было менять категорию фильмов без перехода на страницу редактирования.
Добавьте в админку сортировку фильмов:
- сначала по категории,
- внутри категорий — по году выхода (по убыванию).
Ограничьте количество элементов на странице списком из 7 записей.
Добавьте вторую модель (например, Director) и выведите её в админку с:
- list_display
- list_display_links
- собственным
verbose_name
Проверьте отображение в панели администратора.
- За что отвечает параметр
list_display? - Можно ли сделать одно и то же поле одновременно ссылкой и редактируемым? Почему?
- Как включить сортировку записей в админке?
- Чем
orderingв модели отличается отorderingв админ-классе? - Для чего используется
list_per_page? - Что делает декоратор
@admin.register? - Почему важно указывать
verbose_nameиverbose_name_plural? - Можно ли редактировать ForeignKey-поле прямо в списке?
- Что произойдёт, если в
list_displayуказать поле, которого нет в модели? - Что нужно сделать, чтобы изменения стали заметны в админке?