📝 Html Css

Django: Формы в шаблонах

P
Автор
Pyland
📅
Опубликовано
30.06.2026
⏱️
Время чтения
2 мин
👁️
Просмотров
73
🌳
Уровень
Продвинутый
🐦 💼 ✈️

Django-форма — это Python-класс. В шаблоне она превращается в HTML. Разберём способы рендера: от автоматического до полностью ручного.

Передача формы в шаблон

# forms.py
from django import forms

class CommentForm(forms.Form):
    name = forms.CharField(max_length=100, label="Имя")
    email = forms.EmailField(label="Email")
    text = forms.CharField(widget=forms.Textarea, label="Комментарий")
# views.py
from django.shortcuts import render, redirect
from .forms import CommentForm

def add_comment(request, post_pk):
    if request.method == 'POST':
        form = CommentForm(request.POST)
        if form.is_valid():
            # сохранить данные
            return redirect('post-detail', pk=post_pk)
    else:
        form = CommentForm()

    return render(request, 'blog/comment_form.html', {'form': form})

Автоматический рендер

Быстрый способ — позволить Django самому отрисовать поля:

<form method="post">
  {% csrf_token %}
  {{ form.as_p }}
  <button type="submit" class="btn btn-primary">Отправить</button>
</form>
Метод HTML-обёртка
{{ form.as_p }} Каждое поле в <p>
{{ form.as_div }} Каждое поле в <div> (Bootstrap-совместимо)
{{ form.as_table }} Таблица <tr>/<td>
{{ form.as_ul }} Список <li>

Ограничение: автоматический рендер не добавляет классы Bootstrap — стиль придётся задавать через CSS или виджеты.

Ручной рендер: полный контроль

Ручной рендер даёт полный контроль над HTML каждого поля:

<form method="post" novalidate>
  {% csrf_token %}

  <div class="mb-3">
    {{ form.name.label_tag }}
    {{ form.name }}
    {% if form.name.errors %}
      <div class="invalid-feedback d-block">
        {{ form.name.errors }}
      </div>
    {% endif %}
  </div>

  <div class="mb-3">
    {{ form.email.label_tag }}
    {{ form.email }}
    {% if form.email.errors %}
      <div class="invalid-feedback d-block">
        {{ form.email.errors }}
      </div>
    {% endif %}
  </div>

  <div class="mb-3">
    {{ form.text.label_tag }}
    {{ form.text }}
    {% if form.text.errors %}
      <div class="invalid-feedback d-block">
        {{ form.text.errors }}
      </div>
    {% endif %}
  </div>

  <button type="submit" class="btn btn-primary">Отправить</button>
</form>

{{ form.name }} рендерит <input>, {{ form.name.label_tag }}<label>, {{ form.name.errors }} — список ошибок валидации.

Bootstrap-классы через виджеты

Чтобы не писать стили в шаблоне, добавьте классы в форму:

# forms.py
class CommentForm(forms.Form):
    name = forms.CharField(
        max_length=100,
        label="Имя",
        widget=forms.TextInput(attrs={
            'class': 'form-control',
            'placeholder': 'Ваше имя',
        })
    )
    email = forms.EmailField(
        label="Email",
        widget=forms.EmailInput(attrs={'class': 'form-control'})
    )
    text = forms.CharField(
        label="Комментарий",
        widget=forms.Textarea(attrs={
            'class': 'form-control',
            'rows': 4,
        })
    )

Теперь {{ form.as_p }} уже выдаст поля с классом form-control.

Цикл по полям формы

Если полей много, можно пройтись по ним в цикле:

<form method="post">
  {% csrf_token %}

  {% for field in form %}
    <div class="mb-3">
      {{ field.label_tag }}
      {{ field }}
      {% if field.help_text %}
        <small class="form-text text-muted">{{ field.help_text }}</small>
      {% endif %}
      {% for error in field.errors %}
        <div class="invalid-feedback d-block">{{ error }}</div>
      {% endfor %}
    </div>
  {% endfor %}

  {{ form.non_field_errors }}

  <button type="submit" class="btn btn-primary">Отправить</button>
</form>

form.non_field_errors — ошибки, не привязанные к конкретному полю (например, из form.clean()).

Пример: форма входа на DevBlog

{% extends 'base.html' %}

{% block title %}Войти — DevBlog{% endblock %}

{% block content %}
<div class="row justify-content-center">
  <div class="col-md-5">
    <h1 class="mb-4">Вход</h1>

    <form method="post">
      {% csrf_token %}

      <div class="mb-3">
        <label for="{{ form.username.id_for_label }}" class="form-label">
          Имя пользователя
        </label>
        {{ form.username }}
        {{ form.username.errors }}
      </div>

      <div class="mb-3">
        <label for="{{ form.password.id_for_label }}" class="form-label">
          Пароль
        </label>
        {{ form.password }}
        {{ form.password.errors }}
      </div>

      {% if form.non_field_errors %}
        <div class="alert alert-danger">{{ form.non_field_errors }}</div>
      {% endif %}

      <button type="submit" class="btn btn-primary w-100">Войти</button>
    </form>
  </div>
</div>
{% endblock %}

Ваша реакция на статью

💬 Комментарии (0)

🔐 Войдите в систему, чтобы оставить комментарий
🚪 Войти
💭

Комментариев пока нет

Станьте первым, кто поделится мнением об этой статье!

🔗 Похожие

Похожие статьи

Продолжите изучение с этими материалами

📝

pytest-django: тестирование Django

Охватываемые темы: Установка, @pytest.mark.djangodb, Фикстуры, Тестирование views.

📅 30.06.2026 👁️ 131
📝

Что такое ORM

ORM (Object-Relational Mapping) — технология, позволяющая работать с базой данных через объекты Python вместо SQL.

📅 30.06.2026 👁️ 124
📝

SQLite в Python: персистентная память для агентов

SQLite — встроенная в Python реляционная база данных. Хранит данные в одном файле, не требует...

📅 30.06.2026 👁️ 78

Понравилась статья?

Подпишитесь на наши обновления и получайте новые статьи первыми. Развивайтесь вместе с PyLand!