JavaRush /Курсы /Модуль 3: Django /Настройка страниц редактирования и отображения данных

Настройка страниц редактирования и отображения данных

Модуль 3: Django
11 уровень , 7 лекция
Открыта

Давайте добавим последнюю щепотку магии и разберемся с настройкой страниц редактирования и отображения данных.

Кастомизация страниц редактирования

В базовой настройке 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. Эти знания помогут вам делать интерфейс админ-зоны удобным и понятным для использования.

1
Задача
Модуль 3: Django, 11 уровень, 7 лекция
Недоступна
Группировка полей с использованием fieldsets
Группировка полей с использованием fieldsets
1
Задача
Модуль 3: Django, 11 уровень, 7 лекция
Недоступна
Настройка видимости и редактируемых полей
Настройка видимости и редактируемых полей
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ