Виджет HiddenInput

Виджет HiddenInput применяется для создания скрытого HTML-поля ввода, которое не отображается на странице, но передает свое значение при отправке формы. Это полезно, когда необходимо сохранить данные, которые не должны быть видны или изменены пользователем, например, идентификатор записи, токен безопасности или состояние формы. При использовании данного виджета поле всегда рендерится как   <+html+> <-html-> , независимо от переданного значения.

Синтаксис

pythonfrom django import forms

class MyForm(forms.Form):
  field_name = forms.CharField(widget=forms.HiddenInput())
  # или для других типов полей:
  field_name = forms.IntegerField(widget=forms.HiddenInput())

Пример

Давайте создадим форму со скрытым полем для хранения идентификатора пользователя:

pythonfrom django import forms

class UserProfileForm(forms.Form):
  user_id = forms.IntegerField(widget=forms.HiddenInput(), required=False)
  name = forms.CharField(max_length=50)
  email = forms.EmailField()

При рендеринге формы в HTML:

html<form method="post">
  <input type="hidden" name="user_id" value="123">
  <label>Имя: <input type="text" name="name"></label>
  <label>Email: <input type="email" name="email"></label>
  <button type="submit">Сохранить</button>
</form>

Пример

Давайте передадим начальное значение скрытому полю с помощью параметра initial:

pythonfrom django import forms

class ArticleForm(forms.Form):
  article_id = forms.IntegerField(widget=forms.HiddenInput())
  title = forms.CharField(max_length=100)
  content = forms.CharField(widget=forms.Textarea)
  
# Передача начального значения
form = ArticleForm(initial={'article_id': 456})
print(form.as_p())

Результат выполнения кода:

html<p><label for="id_article_id">Article id:</label>
  <input type="hidden" name="article_id" value="456" id="id_article_id"></p>
<p><label for="id_title">Title:</label>
  <input type="text" name="title" maxlength="100" id="id_title"></p>
<p><label for="id_content">Content:</label>
  <textarea name="content" id="id_content"></textarea></p>

Пример

При обработке отправленной формы скрытое поле будет присутствовать в cleaned_data:

pythonfrom django import forms

class ProductForm(forms.Form):
  product_id = forms.IntegerField(widget=forms.HiddenInput())
  name = forms.CharField(max_length=50)
  price = forms.DecimalField(max_digits=10, decimal_places=2)
  
  def clean_product_id(self):
    product_id = self.cleaned_data['product_id']
    if product_id <= 0:
      raise forms.ValidationError("ID must be positive")
    return product_id
    
# При обработке POST-запроса
form = ProductForm(request.POST)
if form.is_valid():
  product_id = form.cleaned_data['product_id']
  name = form.cleaned_data['name']
  price = form.cleaned_data['price']
  print(f"Product ID: {product_id}, Name: {name}, Price: {price}")

Результат выполнения кода при успешной валидации:

python"Product ID: 789, Name: Laptop, Price: 999.99"

Пример

Использование HiddenInput в модели с формой ModelForm:

pythonfrom django.db import models
from django import forms

class Order(models.Model):
  order_number = models.CharField(max_length=20)
  user_id = models.IntegerField()
  amount = models.DecimalField(max_digits=10, decimal_places=2)
  
class OrderForm(forms.ModelForm):
  class Meta:
    model = Order
    fields = '__all__'
    widgets = {
      'user_id': forms.HiddenInput(),
      'order_number': forms.TextInput(attrs={'readonly': 'readonly'}),
    }

Теперь поле 'user_id' не отображается в форме, но передает свое значение:

html<form method="post">
  <input type="hidden" name="user_id" value="5">
  <label>Номер заказа: <input type="text" name="order_number" readonly="readonly" value="ORD-001"></label>
  <label>Сумма: <input type="text" name="amount" value="1500.00"></label>
  <button type="submit">Обновить</button>
</form>

Пример

Скрытые поля можно комбинировать с обычными полями для передачи дополнительных данных:

pythonfrom django import forms

class SearchForm(forms.Form):
  query = forms.CharField(label='Search query')
  page = forms.IntegerField(widget=forms.HiddenInput())
  sort_by = forms.CharField(widget=forms.HiddenInput())
  
# В контроллере
form = SearchForm(initial={
  'page': 2,
  'sort_by': 'created_at'
})
res = form.as_div()
print(res)

Результат выполнения кода:

html<div><label for="id_query">Search query:</label>
  <input type="text" name="query" id="id_query"></div>
<div><input type="hidden" name="page" value="2" id="id_page"></div>
<div><input type="hidden" name="sort_by" value="created_at" id="id_sort_by"></div>

Смотрите также

  • виджет MultipleHiddenInput,
    который используется для множественных скрытых полей
  • виджет TextInput,
    который создает стандартное текстовое поле ввода
  • метод initial,
    который задает начальные значения для полей формы
  • метод clean,
    который выполняет валидацию данных формы