Давайте добавим последнюю щепотку магии и разберемся с настройкой страниц редактирования и отображения данных.
Кастомизация страниц редактирования
В базовой настройке Django Admin автоматически генерирует форму редактирования для объекта на основе полей модели. Однако в реальных проектах стандартное поведение может быть недостаточным. Например, вы можете захотеть изменить порядок отображения полей или спрятать лишние поля. К счастью, Django предоставляет для этих целей множество инструментов.
Изменение порядка полей с помощью fields
Атрибут fields позволяет указать, какие поля и в каком порядке должны отображаться на странице редактирования.
Пример:
# admin.py
from django.contrib import admin
from .models import Product
class ProductAdmin(admin.ModelAdmin):
fields = ['name', 'price', 'description'] # Указываем нужные поля и их порядок
admin.site.register(Product, ProductAdmin)
Если вы зайдёте на страницу редактирования объекта Product, поля будут отображаться в порядке, указанном в списке fields. Поля, не указанные в этом списке, просто не будут показаны.
Попытка указать поле, которого нет в модели, вызовет ошибку FieldDoesNotExist. Убедитесь, что все перечисленные поля реально существуют в вашей модели.
Группировка полей с помощью fieldsets
Если у вас много полей и они не помещаются в одну колонку, можно использовать fieldsets, чтобы сгруппировать поля в логические блоки с заголовками.
Пример:
# admin.py
class ProductAdmin(admin.ModelAdmin):
fieldsets = [
('Основная информация', {'fields': ['name', 'price']}),
('Дополнительно', {'fields': ['description', 'created_at']}),
]
admin.site.register(Product, ProductAdmin)
На странице редактирования вы увидите два раздела: "Основная информация" и "Дополнительно". Это помогает организовать информацию и сделать интерфейс более понятным.
Установка только для чтения с помощью readonly_fields
Иногда нужно сделать так, чтобы поля на странице редактирования были доступными только для чтения. Например, вы хотите предотвратить изменение значений важных полей, таких как created_at.
Пример:
# admin.py
class ProductAdmin(admin.ModelAdmin):
readonly_fields = ['created_at']
admin.site.register(Product, ProductAdmin)
Теперь поле created_at будет отображаться в форме, но его нельзя будет изменить.
🤔 А можно ли сделать поле редактируемым только для администраторов? Да, чуть позже мы увидим, как это сделать с помощью переопределения методов.
Кастомизированные отображения
Настройка интерфейса редактирования – это не только про порядок полей. Вы также можете кастомизировать, как именно отображаются данные, делая их более читаемыми и удобными для работы.
Динамическое изменение полей на основе объекта
Иногда набор полей, доступных для редактирования, может зависеть от самого объекта. Например, вы хотите, чтобы поле discount отображалось только для товаров, цена которых выше 100.
Пример:
# admin.py
class ProductAdmin(admin.ModelAdmin):
def get_fields(self, request, obj=None):
if obj and obj.price > 100:
return ['name', 'price', 'description', 'discount']
return ['name', 'price', 'description']
admin.site.register(Product, ProductAdmin)
В методе get_fields вы можете реализовать любую логику, определяющую, какие поля показывать в зависимости от атрибутов объекта.
Переопределение формы редактирования
Если встроенных возможностей Django Admin недостаточно, вы можете полностью переопределить форму редактирования, используя собственный класс формы.
Пример:
# forms.py
from django import forms
from .models import Product
class ProductForm(forms.ModelForm):
class Meta:
model = Product
fields = ['name', 'price', 'description']
def clean_price(self):
price = self.cleaned_data['price']
if price <= 0:
raise forms.ValidationError('Цена должна быть больше нуля!')
return price
# admin.py
from django.contrib import admin
from .forms import ProductForm
from .models import Product
class ProductAdmin(admin.ModelAdmin):
form = ProductForm
admin.site.register(Product, ProductAdmin)
Теперь при сохранении администратор получит ошибку, если укажет отрицательную цену.
Добавление пользовательских методов для полей
Иногда вы хотите показать, например, рассчитанное значение или ссылку на внешний ресурс. В таких случаях вы можете определить метод в ModelAdmin и использовать его вместо стандартного поля.
Пример:
# admin.py
class ProductAdmin(admin.ModelAdmin):
fields = ['name', 'price', 'discount', 'final_price']
def final_price(self, obj):
return obj.price - (obj.price * obj.discount / 100)
final_price.short_description = 'Итоговая цена' # Настройка названия колонки
admin.site.register(Product, ProductAdmin)
На странице редактирования появится поле с рассчитанной итоговой ценой.
Пользовательские поля нельзя редактировать прямо в админке. Если вам нужно редактировать подобные данные, придется добавить дополнительную логику.
Реальный пример: кастомизация интерфейса для блога
Возьмем пример приложения для ведения блога. У нас есть модель Article с полями: title, content, author, status, published_at.
Код модели:
# models.py
from django.db import models
from django.contrib.auth.models import User
class Article(models.Model):
DRAFT = 'draft'
PUBLISHED = 'published'
STATUS_CHOICES = [
(DRAFT, 'Черновик'),
(PUBLISHED, 'Опубликовано'),
]
title = models.CharField(max_length=255)
content = models.TextField()
author = models.ForeignKey(User, on_delete=models.CASCADE)
status = models.CharField(max_length=10, choices=STATUS_CHOICES, default=DRAFT)
published_at = models.DateTimeField(null=True, blank=True)
Теперь настроим админ-зону:
# admin.py
from django.contrib import admin
from .models import Article
class ArticleAdmin(admin.ModelAdmin):
fieldsets = [
('Основная информация', {'fields': ['title', 'content', 'author']}),
('Состояние', {'fields': ['status', 'published_at']}),
]
readonly_fields = ['published_at']
def save_model(self, request, obj, form, change):
if obj.status == Article.PUBLISHED and not obj.published_at:
obj.published_at = timezone.now() # Автоматически выставляем время публикации
super().save_model(request, obj, form, change)
admin.site.register(Article, ArticleAdmin)
Теперь админка выглядит аккуратно, а при публикации статьи автоматически заполняется поле published_at.
На этом этапе вы узнали, как настраивать страницы редактирования и отображения объектов в Django Admin. Эти знания помогут вам делать интерфейс админ-зоны удобным и понятным для использования.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ