Сегодня мы займемся практическим созданием формы, которая будет взаимодействовать с моделью: мы создадим форму для модели, настроим её поля и валидацию, а затем реализуем сохранение данных в базу.
Что мы будем делать?
- Создадим простую модель (например, "Контакт").
- Напишем форму на основе этой модели.
- Реализуем представление и шаблон для отображения формы.
- Обработаем данные формы: сохраним их в базу и отобразим подтверждение.
Создаём модель
Первым делом, если у нас есть форма, которая должна работать с базой данных, то нам нужна соответствующая модель. Например, предположим, что у нас есть контактная форма. Она должна собирать следующие данные:
- Имя пользователя.
- Электронную почту.
- Сообщение.
Вот так может выглядеть наша модель 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}'
Что здесь происходит?
- Поле
nameхранит имя пользователя. Мы ограничили длину строки на уровне базы данных до 100 символов. - Поле
email— это типEmailField, который автоматически проверяет корректность e-mail при сохранении. - Поле
messageпредназначено для хранения большого текста. - Поле
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, так как это поле заполняется автоматически).
Отображение формы в представлении
Теперь нужно воспользоваться этой формой в одном из представлений. Давайте создадим функциональное представление для отображения и обработки формы:
# 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})
Что здесь происходит:
- Если запрос
POST, мы пытаемся обработать форму, переданную из шаблона. - Если форма валидна (прошла все проверки), мы сохраняем данные в базе с помощью метода
form.save(). - Если запрос не
POST, мы просто отображаем пустую форму. - В случае успешной обработки пользователь попадает на страницу
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>Your message has been sent successfully.</p>
<a href="/" class="btn btn-secondary">Back to Home</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().
Теперь вы готовы к созданию динамичных и безопасных форм, которые умеют взаимодействовать с базой данных. Ваши будущие проекты будут только благодарны за этот навык!
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ