JavaRush /Курси /Модуль 3: Django /Практичне створення форми для моделі

Практичне створення форми для моделі

Модуль 3: Django
Рівень 12 , Лекція 8
Відкрита

Сьогодні ми займемося практичним створенням форми, яка буде взаємодіяти з моделлю: ми створимо форму для моделі, налаштуємо її поля та валідацію, а потім реалізуємо збереження даних у базу.

Що ми будемо робити?

  1. Створимо просту модель (наприклад, "Контакт").
  2. Напишемо форму на основі цієї моделі.
  3. Реалізуємо представлення та шаблон для відображення форми.
  4. Обробимо дані форми: збережемо їх у базу та відобразимо підтвердження.

Створюємо модель

Перше, що потрібно зробити, якщо у нас є форма, яка має працювати з базою даних, то нам потрібна відповідна модель. Наприклад, припустимо, що у нас є контактна форма. Вона повинна збирати наступні дані:

  • Ім'я користувача.
  • Електронну пошту.
  • Повідомлення.

Ось так може виглядати наша модель Contact:

# models.py
from django.db import models

class Contact(models.Model):
    name = models.CharField(max_length=100)  # Ім'я
    email = models.EmailField()  # Електронна пошта
    message = models.TextField()  # Повідомлення
    created_at = models.DateTimeField(auto_now_add=True)  # Дата створення запису

    def __str__(self):
        return f'{self.name} - {self.email}'

Що тут відбувається?

  1. Поле name зберігає ім'я користувача. Ми обмежили довжину рядка на рівні бази даних до 100 символів.
  2. Поле email — це тип EmailField, який автоматично перевіряє коректність e-mail при збереженні.
  3. Поле message призначене для зберігання великого тексту.
  4. Поле created_at автоматично фіксує дату та час створення запису.

Не забудьте виконати міграції:

python manage.py makemigrations
python manage.py migrate

Створюємо форму на основі моделі

Тепер, коли у нас є модель, ми можемо використовувати класи Django Forms для автоматичного створення форми на основі цієї моделі. Ласкаво просимо у світ ModelForm — магічного інструменту, який економить купу часу.

# forms.py
from django import forms
from .models import Contact

class ContactForm(forms.ModelForm):
    class Meta:
        model = Contact  # Вказуємо модель
        fields = ['name', 'email', 'message']  # Поля, які будуть у формі

Тут:

  • Ми створюємо клас ContactForm, який наслідується від forms.ModelForm.
  • Всередині класу Meta ми зв'язуємо форму з моделлю Contact.
  • Вказуємо, які поля з моделі мають використовуватися у формі (у цьому випадку — всі, крім created_at, оскільки це поле заповнюється автоматично).

Відображення форми у view

Тепер потрібно скористатися цією формою в одному з view. Давайте створимо функціональне view для відображення та обробки форми:

# views.py
from django.shortcuts import render, redirect
from .forms import ContactForm

def contact_view(request):
    if request.method == 'POST':
        form = ContactForm(request.POST)
        if form.is_valid():
            form.save()  # Зберігаємо дані в базі
            return render(request, 'contact_success.html')  # Відображаємо сторінку успіху
    else:
        form = ContactForm()

    return render(request, 'contact.html', {'form': form})

Що тут відбувається:

  1. Якщо запит POST, ми намагаємося обробити форму, передану з шаблону.
  2. Якщо форма валідна (пройшла всі перевірки), ми зберігаємо дані в базі за допомогою методу form.save().
  3. Якщо запит не POST, ми просто відображаємо порожню форму.
  4. У разі успішної обробки користувач потрапляє на сторінку contact_success.html.

Шаблон для форми

Тепер створимо шаблон contact.html для відображення форми:

<!-- templates/contact.html -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Contact Us</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
    <div class="container mt-5">
        <h1>Contact Us</h1>
        <form method="post" novalidate>
            {% csrf_token %}
            {{ form.as_p }}
            <button type="submit" class="btn btn-primary">Submit</button>
        </form>
    </div>
</body>
</html>

Зверни увагу на:

  • {% csrf_token %} — це захист від CSRF-атак, обов'язковий при відправці даних через POST.
  • {{ form.as_p }} — рендеринг форми в тегу p. Це досить простий спосіб, але форми також можна стилізувати з використанням Bootstrap або інших CSS-бібліотек.

Також створимо шаблон для сторінки успіху contact_success.html:

<!-- templates/contact_success.html -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Message Sent</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
    <div class="container mt-5">
        <h1>Thank You!</h1>
        <p>Ваше повідомлення успішно відправлено.</p>
        <a href="/" class="btn btn-secondary">Повернутися на головну</a>
    </div>
</body>
</html>

Налаштування маршрутів

Не забудьте налаштувати маршрути для нашого представлення:

# urls.py
from django.urls import path
from .views import contact_view

urlpatterns = [
    path('contact/', contact_view, name='contact'),
]

Тепер доступ до форми буде здійснюватися через URL /contact/.

Практичне завдання

Перед тим як ти почнеш радіти своїм успіхам, спробуй вирішити задачу самостійно. Наприклад:

  • Розширити функціональність форми, додавши поле "Тема повідомлення".
  • Реалізувати перевірку, щоб поле "Повідомлення" не залишалося порожнім.
  • Налаштувати відображення помилок у формі при введенні некоректних даних.

Бонус: Типова помилка при роботі з формами. Одна з поширених помилок — забути додати {% csrf_token %} у шаблон. Так, Django піклується про безпеку, тому, якщо ти забудеш цей токен, твоя форма просто не відправиться. Ще одна помилка — спроба зберегти дані при невалідній формі. Завжди перевіряй form.is_valid() перед викликом form.save().

Тепер ти готовий до створення динамічних і безпечних форм, які вміють взаємодіяти з базою даних. Твої майбутні проєкти будуть тільки вдячні за цю навичку!

Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ