JavaRush /Курсы /Модуль 3: Django /Кастомизация форм

Кастомизация форм

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

В этой лекции мы поговорим о том, как стилизовать наши формы, добавлять пользовательские методы для проверки данных и переопределять стандартные методы форм для внедрения специфической логики.

Добавление стилей к формам

Представьте, что вы зашли на сайт, который должен предложить вам крутой функционал, но выглядит он как страница из 2005-го года. Боюсь, вы не задержитесь там надолго. Так что нам нужно не только функционально, но и эстетически улучшить наши формы.

Django Forms автоматически генерируют HTML-код. Но вот беда: этот HTML, как правило, выглядит просто. Просто! А значит, нужно добавить немного магии CSS.

Где стилизовать?

Стили можно добавлять прямо в шаблоне или в самой форме. Мы рассмотрим обе опции.

Пример: добавление CSS и Bootstrap классов

Вот как можно добавить стили полям формы, используя атрибут widgets:

from django import forms

class ContactForm(forms.Form):
    name = forms.CharField(
        max_length=100,
        widget=forms.TextInput(attrs={
            'class': 'form-control',  # Bootstrap класс
            'placeholder': 'Ваше имя',  # Подсказка
        })
    )
    email = forms.EmailField(
        widget=forms.EmailInput(attrs={
            'class': 'form-control',
            'placeholder': 'Ваш Email',
        })
    )
    message = forms.CharField(
        widget=forms.Textarea(attrs={
            'class': 'form-control',
            'placeholder': 'Ваше сообщение',
            'rows': 5,
        })
    )
  • attrs — это магический словарь, где вы задаёте HTML-атрибуты для поля: классы, подсказки, размеры.
  • Мы использовали Bootstrap классы для стилизации полей формы (form-control), а также задали удобные поля placeholder для пользователей.

При этом в вашем шаблоне ничего не нужно менять:

<form method="post">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit" class="btn btn-primary">Отправить</button>
</form>

Результат: красивая форма с минимальными усилиями. Эстетика спасает мир!

Переопределение методов формы

Иногда нужно работать не только с внешним видом, но и с внутренней магией. Например, что, если нужно изменить метки полей (labels) или порядок их отображения? Или передавать в форму динамически изменяемые данные? Давайте разберёмся.

Переопределяем метод __init__

Метод __init__ используется для инициализации формы. Это отличное место для изменений — например, добавления к полям каких-нибудь стартовых данных.

Пример: динамические метки полей

Допустим, у нас есть форма регистрации, и мы хотим, чтобы поле имени могло быть локализованным. Например, "Name" для английского и "Имя" для русского.

class RegistrationForm(forms.Form):
    username = forms.CharField(max_length=50)
    email = forms.EmailField()
    password = forms.CharField(widget=forms.PasswordInput)

    def __init__(self, *args, **kwargs):
        user_language = kwargs.pop('language', 'en')  # Получаем язык из аргументов
        super().__init__(*args, **kwargs)

        if user_language == 'ru':
            self.fields['username'].label = 'Имя пользователя'
            self.fields['email'].label = 'Электронная почта'
            self.fields['password'].label = 'Пароль'
        else:
            self.fields['username'].label = 'Username'
            self.fields['email'].label = 'Email'
            self.fields['password'].label = 'Password'

Теперь можно передать язык формы при её инициализации:

form = RegistrationForm(language='ru')

И вуаля — форма корректно отобразит метки на русском языке.

Изменение порядка полей

Всё ещё метод __init__, но теперь мы поменяем порядок отображения полей в форме.

class CustomOrderForm(forms.Form):
    first = forms.CharField()
    second = forms.CharField()
    third = forms.CharField()

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.order_fields(['third', 'first', 'second'])  # Меняем порядок

Метод order_fields() — встроенный метод Django Forms. У него есть только один недостаток: задний фронт HTML всё равно останется в том же порядке, если ваша форма рендерится через {% for field in form %}. Для красивого подхода лучше явно перестраивать порядок в шаблоне.

Пользовательские методы

Иногда встроенной валидации недостаточно. Например, вы хотите проверить, существует ли введённый email в базе. Для этого можно добавить собственные методы.

Пример: метод проверки уникальности

from django.core.exceptions import ValidationError
from django.contrib.auth.models import User

class RegistrationForm(forms.Form):
    username = forms.CharField(max_length=50)
    email = forms.EmailField()
    password = forms.CharField(widget=forms.PasswordInput)

    def clean_email(self):
        email = self.cleaned_data.get('email')
        if User.objects.filter(email=email).exists():
            raise ValidationError('Такой email уже зарегистрирован.')
        return email

    def clean_username(self):
        username = self.cleaned_data.get('username')
        if User.objects.filter(username=username).exists():
            raise ValidationError('Имя пользователя занято.')
        return username

Что здесь происходит?

  • Мы переопределили метод clean_<fieldname>(). Django автоматически вызывает этот метод, если он существует, для каждого указанного поля.
  • Если проверка не проходит, выбрасывается исключение ValidationError, а форма отмечает это поле как невалидное.

Когда понадобятся кастомные методы?

Вы можете использовать их для всего, где требуется специфическая логика. Например:

  • Проверка уникальности.
  • Проверка формата данных (например, username может содержать только буквы и цифры).
  • Предварительная обработка данных (например, избавление от пробелов).

Best practices и хитрости

  • Старайтесь инкапсулировать логику. Если ваши методы слишком сильно зависят от формы, подумайте, можно ли вынести логику в отдельную функцию или сервис.
  • Будьте осторожны с init. Не забывайте вызывать super().__init__(*args, **kwargs), иначе ваша форма просто не будет работать.
  • Минимум логики в шаблонах. Весь сложный функционал и логику размещайте в Python-коде, а не в HTML.
  • Красота важна. Никто не станет заполнять форму, если она выглядит как форма налоговой декларации 1980-го года.

Поздравляю! Теперь вы знаете, как превращать простенькие формы в мощные, стильные и функциональные инструменты для ваших Django-приложений. На следующем занятии вы научитесь ещё больше: работать с ошибками форм и кастомизировать их отображение.

1
Задача
Модуль 3: Django, 12 уровень, 4 лекция
Недоступна
Базовая кастомизация формы
Базовая кастомизация формы
1
Задача
Модуль 3: Django, 12 уровень, 4 лекция
Недоступна
Переопределение конструктора формы
Переопределение конструктора формы
3
Опрос
Введение в Django Forms, 12 уровень, 4 лекция
Недоступен
Введение в Django Forms
Введение в Django Forms
Комментарии (2)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Александр Уровень 67
24 ноября 2025
В тесте ошибка: Какой виджет Django Forms используется для создания поля ввода пароля? Правильный ответ: forms.PasswordInput системой не принимается.
_den Уровень 65
8 декабря 2025
правильный CharField с указанием widget, поля через froms.*Field создаются.