Работа с формами Django в Python
Django admin достаточно хорош для того, чтобы администратор мог управлять содержимым на основе моделей. Однако, когда вы хотите, чтобы пользователи веб-сайта управляли своим содержимым, вам нужно создать для них отдельные формы.
В данном руководстве рассмотрим, как создать форму Django для создания, обновления и удаления моделей записей приложения блога в Python.
Знакомство с формами Django
Обработка форм подразумевает очень сложную логику:
- Подготовьте HTML-форму.
- Проверяйте поля в браузере с помощью JavaScript или встроенной проверки HTML5.
- Получите значения на сервере.
- Проверьте поля на сервере.
- Обработка значений формы, например сохранение их в базе данных, если форма действительна.
- Необходимо перерисовать форму со старыми значениями и сообщением об ошибке, если форма недействительна.
Формы Django упрощают и автоматизируют почти все вышеперечисленные шаги.
Обратите внимание, что вы можете написать код для выполнения всех вышеперечисленных шагов вручную, если вам нужна дополнительная настройка форм.
Все формы в Django наследуются от класса django.forms.Form. Класс ModelForm позволяет создать форму, которая ассоциируется с моделью.
Определение формы
- Сначала создайте новый файл forms.py в каталоге приложения блога.
- Затем определите новую форму с именем PostForm, которая наследует класс ModelForm:
from django.forms import ModelForm from .models import Post class PostForm(ModelForm): class Meta: model = Post fields = ['title','content', 'author', 'author']
Как это работает.
- Импортируйте ModelForm из django.forms.
- Импортируйте Post из модуля models.py.
- Определите класс PostForm, который наследует класс ModelForm. В классе PostForm определите класс Meta и укажите атрибуты модели и полей.
- В-третьих, определите маршрут, который отображает PostForm:
from django.urls import path from . import views urlpatterns = [ path('', views.home, name='posts'), path('post/create', views.create_post, name='post-create'), path('about/', views.about, name='about'), ]
- В-четвертых, определите функцию create_post(), которая отображает форму:
from django.shortcuts import render from .models import Post from .forms import PostForm def create_post(request): if request.method == 'GET': context = {'form': PostForm()} return render(request, 'blog/post_form.html', context) def home(request): posts = Post.objects.all() context = {'posts': posts} return render(request, 'blog/home.html', context) def about(request): return render(request, 'blog/about.html')
В create_post(), если HTTP-запрос — GET, создайте новый экземпляр класса PostForm и передайте его функции render().
- В-пятых, создайте шаблон post_form.html:
{% extends 'base.html' %} {% block content %} <h2>New Post</h2> <form method="post" novalidate> {% csrf_token %} {{ form.as_p }} <input type="submit" value="Save" /> </form> {% endblock content %}
В post_form.html добавьте тег csrf_token и визуализируйте форму с помощью свойства form.as_p. Выведется следующее:
<p> <label for="id_title">Title:</label> <input type="text" name="title" maxlength="120" required id="id_title"> </p> <p> <label for="id_content">Content:</label> <textarea name="content" cols="40" rows="10" required id="id_content"></textarea> </p>
Если вы откроете URL-адрес http://127.0.0.1:8000/post/create, вы увидите следующую форму:
Если вы нажмете кнопку «Save», вы увидите сообщение об ошибке:
Поскольку поля заголовка, содержимого и автора модели Post являются обязательными по умолчанию, PostForm, использующая модель Post, также отображает HTML-форму, требующую заполнения этих полей.
Чтобы протестировать проверку сервера, вы можете отключить проверку клиента, добавив свойство novalidate в форму следующим образом:
{% extends 'base.html' %} {% block content %} <h2>New Post</h2> <form method="post" novalidate> {% csrf_token %} {{ form.as_p }} <input type="submit" value="Save" /> </form> {% endblock content %}
Для обработки метода HTTP POST необходимо изменить функцию create_post в файле views.py приложения блога:
from django.shortcuts import render, redirect from .models import Post from .forms import PostForm def create_post(request): if request.method == 'GET': context = {'form': PostForm()} return render(request, 'blog/post_form.html', context) elif request.method == 'POST': form = PostForm(request.POST) if form.is_valid(): form.save() return redirect('posts') else: return render(request, 'blog/post_form.html', {'form': form}) # ...
Если HTTP-запрос — POST(request.method==’POST’):
- Создайте новый экземпляр класса PostForm с данными из POST.
- Проверьте правильность формы.
- Если форма действительна, сохраните значения формы в базе данных и перенаправьте веб-браузер по пути «posts».
- В противном случае перерисуйте форму со старыми значениями и ошибками.
Если вы отправите форму, не введя никаких значений, вы получите следующие сообщения об ошибках:
Однако при указании значений для некоторых обязательных полей Django отображает форму со старыми значениями и отображает сообщения об ошибках только для недопустимых полей.
Например, следующая форма отображает сообщение об ошибке для поля заголовка, сохраняя старые значения для полей содержимого и автора:
Если вы введете допустимые значения для всех полей, Django сохранит значения в базе данных.
…и перенаправит на список постов: