Настав час поглибити наші знання та навчитися кастомізувати поля ModelForm. Адже іноді стандартна функціональність форми не відповідає всім вимогам проєкту. Наприклад, потрібно змінити мітки полів, додати плейсхолдери, віджети або навіть задати нові початкові значення. Сьогодні ми навчимося освоювати ці та інші магічні трюки.
Налаштування полів у ModelForm
За замовчуванням, ModelForm створює поля на основі моделі "як є". Наприклад, якщо в моделі є поле CharField, воно автоматично перетворюється в текстове поле у формі forms.TextInput. Але що, якщо ми хочемо зробити це поле обов'язковим, змінити мітку (label) або додати плейсхолдер, щоб підказати користувачу, що потрібно вводити? Для таких задач і існує кастомізація полів.
Зміна властивостей полів
Django дозволяє напряму втрутитись у процес генерації полів ModelForm та змінити їх властивості. Розглянемо найпопулярніші властивості, які можна кастомізувати:
label: задає текст мітки для поля.widget: визначає віджет, який використовується для відображення поля.initial: задає початкове значення для поля.required: робить поле обов'язковим або необов'язковим.help_text: додає пояснювальний текст під полем.error_messages: дозволяє налаштувати користувацькі повідомлення про помилки.
Тепер перейдемо до практики.
Приклад 1: налаштування мітки (label) та початкового значення (initial)
Припустимо, у нас є наступна модель:
from django.db import models
class Profile(models.Model):
username = models.CharField(max_length=100)
email = models.EmailField()
age = models.IntegerField(default=18)
Створимо ModelForm та змінимо мітку для поля username, а також задамо початкове значення для поля age:
from django import forms
from .models import Profile
class ProfileForm(forms.ModelForm):
class Meta:
model = Profile
fields = ['username', 'email', 'age']
# Перевизначення властивостей полів
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['username'].label = "Ім'я користувача"
self.fields['age'].initial = 25
Тепер, якщо ви відобразите цю форму, мітка для поля username зміниться на "Ім'я користувача", а у поля age з'явиться початкове значення 25.
Приклад 2: зміна віджета (widget)
Віджети визначають, як поле форми буде представлено в HTML. Наприклад, текстові поля можуть бути представлені як <input type="text">, багаторядкові — як <textarea> і так далі.
Припустимо, ми хочемо, щоб поле email використовувало віджет із плейсхолдером. Ось як це робиться:
class ProfileForm(forms.ModelForm):
class Meta:
model = Profile
fields = ['username', 'email', 'age']
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['email'].widget = forms.TextInput(
attrs={'placeholder': 'Введіть ваш email'}
)
Завдяки цьому в HTML-коді буде створено поле <input> з атрибутом placeholder.
Приклад 3: додавання helptext та errormessages
Властивість help_text додає текст, що пояснює, що потрібно вводити в поле. А error_messages дозволяє налаштувати повідомлення про помилки.
Припустимо, ми хочемо додати пояснення до поля username, а також змінити повідомлення про помилку для поля age:
class ProfileForm(forms.ModelForm):
class Meta:
model = Profile
fields = ['username', 'email', 'age']
help_texts = {
'username': 'Введіть унікальне ім\'я користувача.',
}
error_messages = {
'age': {
'invalid': 'Вік має бути числом!',
},
}
Тепер користувачі побачать додаткові підказки у формі, а якщо введуть некоректний вік, Django видасть більш дружнє повідомлення про помилку.
Практичне завдання: налаштування форми
Давай разом створимо форму для керування профілями користувачів і налаштуємо деякі поля.
Крок 1: Модель UserProfile
Почнемо з моделі. Нехай у нас є наступна модель профілю:
class UserProfile(models.Model):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
bio = models.TextField(null=True, blank=True)
birth_date = models.DateField()
Крок 2: створення ModelForm
Тепер створимо ModelForm з кастомізованими полями:
class UserProfileForm(forms.ModelForm):
class Meta:
model = UserProfile
fields = ['first_name', 'last_name', 'bio', 'birth_date']
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['first_name'].widget = forms.TextInput(
attrs={'placeholder': 'Ваше імʼя'}
)
self.fields['last_name'].widget = forms.TextInput(
attrs={'placeholder': 'Ваше прізвище'}
)
self.fields['bio'].widget = forms.Textarea(
attrs={'rows': 4, 'placeholder': 'Про себе'}
)
self.fields['birth_date'].label = "Дата народження"
self.fields['birth_date'].help_text = "Введіть дату у форматі РРРР-ММ-ДД"
Тепер при відображенні цієї форми в шаблоні користувачі побачать красиву кастомізовану форму.
Виправляємо помилки
- Проблема з неправильними віджетами
Іноді розробники намагаються задавати несумісні віджети для полів. Наприклад, для поля birth_date може бути заданий віджет forms.TextInput, який не підтримує форматування дати. Найкраще у таких випадках використовувати спеціалізовані віджети, такі як forms.DateInput.
- Проблема з локалізацією міток
Поле label може стати проблемою, якщо проєкт підтримує декілька мов. У таких випадках краще використовувати функції для перекладу gettext_lazy.
Приклад:
from django.utils.translation import gettext_lazy as _
class UserProfileForm(forms.ModelForm):
class Meta:
model = UserProfile
fields = ['birth_date']
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['birth_date'].label = _("Дата народження")
Корисні трюки
- Поля "тільки для читання"
Якщо ти хочеш зробити поле доступним тільки для читання, можна відключити його за допомогою атрибуту disabled:
self.fields['first_name'].widget.attrs['disabled'] = True
- Динамічне додавання полів
Іноді потрібно додавати поля у форму в залежності від контексту. Це можна зробити у конструкторі:
if some_condition:
self.fields['new_field'] = forms.CharField(label="Нове поле")
- Приховані поля
Для приховування полів використовується віджет HiddenInput:
self.fields['some_field'].widget = forms.HiddenInput()
Тепер ти знаєш, як кастомізувати поля у ModelForm. Ця потужна можливість дозволить тобі створювати зручні та красиві форми, які ідеально відповідають вимогам будь-якого проєкту. Не забувай експериментувати та практикуватися — тільки так можна стати майстром кастомізації!
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ