Виджет MultipleHiddenInput

Виджет MultipleHiddenInput применяется к полям формы с множественным выбором и отображает выбранные значения в виде нескольких скрытых полей input type="hidden". Каждое выбранное значение представляет собой отдельное скрытое поле с одинаковым именем, что позволяет передавать несколько значений через форму. Виджет полезен, когда нужно сохранить состояние множественного выбора, но не показывать его пользователю визуально.

Синтаксис

pythonfrom django import forms

class MyForm(forms.Form):
  field_name = forms.MultipleChoiceField(
    choices=CHOICES_LIST,
    widget=forms.MultipleHiddenInput()
  )

Параметры

Виджет MultipleHiddenInput принимает следующие параметры:

Пример . С простой формой

Рассмотрим пример формы, в которой пользователь выбирает несколько городов, а виджет скрывает этот выбор:

pythonfrom django import forms

CITY_CHOICES = [
  ('msc', 'Москва'),
  ('spb', 'Санкт-Петербург'),
  ('nsk', 'Новосибирск'),
  ('ekb', 'Екатеринбург'),
]

class CityForm(forms.Form):
  cities = forms.MultipleChoiceField(
    choices=CITY_CHOICES,
    widget=forms.MultipleHiddenInput(),
    required=False
  )

form = CityForm(initial={'cities': ['msc', 'spb']})
print(form.as_div())

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

python<div>
  <input type="hidden" name="cities" value="msc" id="id_cities_0">
  <input type="hidden" name="cities" value="spb" id="id_cities_1">
</div>

Как видно из примера, виджет создает два скрытых поля, соответствующих выбранным городам.

Пример . С динамическим выбором

Рассмотрим более сложный пример, где значения для виджета передаются через POST-запрос:

pythonfrom django import forms
from django.http import HttpRequest

class BookForm(forms.Form):
  genres = forms.MultipleChoiceField(
    choices=[
      ('fiction', 'Художественная'),
      ('science', 'Научная'),
      ('history', 'Историческая'),
      ('poetry', 'Поэзия'),
    ],
    widget=forms.MultipleHiddenInput()
  )

# Создание формы с POST-данными
post_data = HttpRequest()
post_data.method = 'POST'
post_data.POST = {
  'genres': ['fiction', 'science']
}

form = BookForm(post_data.POST)
if form.is_valid():
  selected_genres = form.cleaned_data['genres']
  print(selected_genres)

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

python['fiction', 'science']

Виджет автоматически обрабатывает несколько значений с одинаковым именем и передает их как список в cleaned_data.

Пример . С пользовательскими атрибутами

Покажем, как добавить CSS-классы и другие атрибуты к скрытым полям:

pythonfrom django import forms

class UserForm(forms.Form):
  interests = forms.MultipleChoiceField(
    choices=[
      ('sport', 'Спорт'),
      ('music', 'Музыка'),
      ('art', 'Искусство'),
      ('tech', 'Технологии'),
    ],
    widget=forms.MultipleHiddenInput(
      attrs={
        'class': 'hidden-field',
        'data-type': 'interest'
      }
    )
  )

form = UserForm(initial={'interests': ['sport', 'tech']})
print(form.as_table())

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

python<tr>
  <th></th>
  <td>
    <input type="hidden" name="interests" value="sport"
         class="hidden-field" data-type="interest" id="id_interests_0">
    <input type="hidden" name="interests" value="tech"
         class="hidden-field" data-type="interest" id="id_interests_1">
  </td>
</tr>

Все атрибуты, переданные в attrs, применяются к каждому скрытому полю.

Пример . С ModelMultipleChoiceField

Покажем использование виджета с полем, основанным на модели:

pythonfrom django import forms
from myapp.models import Category

class ArticleForm(forms.Form):
  categories = forms.ModelMultipleChoiceField(
    queryset=Category.objects.all(),
    widget=forms.MultipleHiddenInput()
  )

# Создание формы с начальными значениями
categories = Category.objects.filter(name__in=['news', 'blog'])
form = ArticleForm(initial={'categories': categories})
print(form.as_ul())

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

python<li>
  <input type="hidden" name="categories" value="1" id="id_categories_0">
  <input type="hidden" name="categories" value="2" id="id_categories_1">
</li>

Виджет работает одинаково как с обычным, так и с модельным множественным выбором.

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

  • виджет HiddenInput,
    который используется для одного скрытого поля
  • виджет SelectMultiple,
    который отображает множественный выбор в виде списка
  • виджет CheckboxSelectMultiple,
    который отображает множественный выбор в виде чекбоксов
  • поле MultipleChoiceField,
    которое используется для множественного выбора