Виджеты

Виджет - это представление Django элемента ввода HTML. Виджет обрабатывает рендеринг HTML и извлечение данных из GET/POST словаря, соответствующего виджету.

HTML, создаваемый встроенными виджетами, использует синтаксис HTML5, ориентированный на <!DOCTYPE html>. Например, он использует булевы атрибуты, такие как checked, а не стиль XHTML checked='checked'.

Совет

Виджеты не следует путать с form fields. Поля формы имеют дело с логикой валидации ввода и используются непосредственно в шаблонах. Виджеты имеют дело с визуализацией элементов ввода HTML-формы на веб-странице и извлечением необработанных отправленных данных. Тем не менее, виджеты должны быть assigned к полям форм.

Указание виджетов

Всякий раз, когда вы указываете поле в форме, Django будет использовать виджет по умолчанию, соответствующий типу отображаемых данных. Чтобы узнать, какой виджет используется для того или иного поля, смотрите документацию о Встроенные классы Field.

Однако, если вы хотите использовать другой виджет для поля, вы можете использовать аргумент widget в определении поля. Например:

from django import forms

class CommentForm(forms.Form):
    name = forms.CharField()
    url = forms.URLField()
    comment = forms.CharField(widget=forms.Textarea)

Это укажет форму с комментарием, которая использует больший виджет Textarea, а не виджет по умолчанию TextInput.

Установка аргументов для виджетов

Многие виджеты имеют необязательные дополнительные аргументы; их можно установить при определении виджета на поле. В следующем примере атрибут years установлен для SelectDateWidget:

from django import forms

BIRTH_YEAR_CHOICES = ['1980', '1981', '1982']
FAVORITE_COLORS_CHOICES = [
    ('blue', 'Blue'),
    ('green', 'Green'),
    ('black', 'Black'),
]

class SimpleForm(forms.Form):
    birth_year = forms.DateField(widget=forms.SelectDateWidget(years=BIRTH_YEAR_CHOICES))
    favorite_colors = forms.MultipleChoiceField(
        required=False,
        widget=forms.CheckboxSelectMultiple,
        choices=FAVORITE_COLORS_CHOICES,
    )

Смотрите Встроенные виджеты для получения дополнительной информации о том, какие виджеты доступны и какие аргументы они принимают.

Виджеты, наследующие от виджета Select

Виджеты, наследующие виджет Select, имеют дело с выбором. Они представляют пользователю список опций, из которых можно выбирать. Различные виджеты представляют этот выбор по-разному; сам виджет Select использует представление списка <select> HTML, а RadioSelect использует радиокнопки.

Виджеты Select используются по умолчанию в полях ChoiceField. Выбор, отображаемый на виджете, наследуется от ChoiceField, и изменение ChoiceField.choices приведет к обновлению Select.choices. Например:

>>> from django import forms
>>> CHOICES = [('1', 'First'), ('2', 'Second')]
>>> choice_field = forms.ChoiceField(widget=forms.RadioSelect, choices=CHOICES)
>>> choice_field.choices
[('1', 'First'), ('2', 'Second')]
>>> choice_field.widget.choices
[('1', 'First'), ('2', 'Second')]
>>> choice_field.widget.choices = []
>>> choice_field.choices = [('1', 'First and only')]
>>> choice_field.widget.choices
[('1', 'First and only')]

Виджеты, предлагающие атрибут choices, могут использоваться с полями, не основанными на выборе - например, CharField - но рекомендуется использовать поле, основанное на ChoiceField, когда выбор присущ модели, а не только представляющему виджету.

Настройка экземпляров виджетов

Когда Django отображает виджет как HTML, он отображает только очень минимальную разметку - Django не добавляет имена классов или любые другие специфические для виджета атрибуты. Это означает, что, например, все виджеты TextInput будут выглядеть одинаково на ваших веб-страницах.

Существует два способа настройки виджетов: per widget instance и per widget class.

Стилизация экземпляров виджетов

Если вы хотите, чтобы один экземпляр виджета отличался от другого, вам нужно будет указать дополнительные атрибуты в момент инстанцирования объекта виджета и назначения его полю формы (и, возможно, добавить некоторые правила в ваши CSS-файлы).

Например, возьмем следующую форму:

from django import forms

class CommentForm(forms.Form):
    name = forms.CharField()
    url = forms.URLField()
    comment = forms.CharField()

Эта форма будет включать три виджета по умолчанию TextInput, с рендерингом по умолчанию - без CSS класса, без дополнительных атрибутов. Это означает, что поля ввода, предусмотренные для каждого виджета, будут отображаться одинаково:

>>> f = CommentForm(auto_id=False)
>>> f.as_table()
<tr><th>Name:</th><td><input type="text" name="name" required></td></tr>
<tr><th>Url:</th><td><input type="url" name="url" required></td></tr>
<tr><th>Comment:</th><td><input type="text" name="comment" required></td></tr>

На реальной веб-странице вы, вероятно, не захотите, чтобы все виджеты выглядели одинаково. Возможно, вам понадобится более крупный элемент ввода для комментария, а виджету „name“ нужно придать особый CSS-класс. Также можно указать атрибут „type“, чтобы воспользоваться преимуществами новых типов ввода HTML5. Для этого при создании виджета вы используете аргумент Widget.attrs:

class CommentForm(forms.Form):
    name = forms.CharField(widget=forms.TextInput(attrs={'class': 'special'}))
    url = forms.URLField()
    comment = forms.CharField(widget=forms.TextInput(attrs={'size': '40'}))

Вы также можете изменить виджет в определении формы:

class CommentForm(forms.Form):
    name = forms.CharField()
    url = forms.URLField()
    comment = forms.CharField()

    name.widget.attrs.update({'class': 'special'})
    comment.widget.attrs.update(size='40')

Или если поле не объявлено непосредственно на форме (например, поля формы модели), вы можете использовать атрибут Form.fields:

class CommentForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['name'].widget.attrs.update({'class': 'special'})
        self.fields['comment'].widget.attrs.update(size='40')

Затем Django включит дополнительные атрибуты в отображаемый вывод:

>>> f = CommentForm(auto_id=False)
>>> f.as_table()
<tr><th>Name:</th><td><input type="text" name="name" class="special" required></td></tr>
<tr><th>Url:</th><td><input type="url" name="url" required></td></tr>
<tr><th>Comment:</th><td><input type="text" name="comment" size="40" required></td></tr>

Вы также можете установить HTML id, используя attrs. См. пример BoundField.id_for_label.

Стилизация классов виджетов

С помощью виджетов можно добавлять активы (css и javascript) и более глубоко настраивать их внешний вид и поведение.

В двух словах, вам нужно будет создать подкласс виджета и либо define a «Media» inner class, либо create a «media» property.

Эти методы предполагают несколько продвинутое программирование на Python и подробно описаны в руководстве по теме Form Assets.

Базовые классы виджетов

Базовые классы виджетов Widget и MultiWidget являются подклассами всех built-in widgets и могут служить основой для пользовательских виджетов.

Widget

class Widget(attrs=None)[исходный код]

Этот абстрактный класс не может быть отображен, но предоставляет базовый атрибут attrs. Вы также можете реализовать или переопределить метод render() в пользовательских виджетах.

attrs

Словарь, содержащий атрибуты HTML, которые должны быть установлены на отображаемом виджете.

>>> from django import forms
>>> name = forms.TextInput(attrs={'size': 10, 'title': 'Your name'})
>>> name.render('name', 'A name')
'<input title="Your name" type="text" name="name" value="A name" size="10">'

Если присвоить атрибуту значение True или False, он будет отображаться как булев атрибут HTML5:

>>> name = forms.TextInput(attrs={'required': True})
>>> name.render('name', 'A name')
'<input name="name" type="text" value="A name" required>'
>>>
>>> name = forms.TextInput(attrs={'required': False})
>>> name.render('name', 'A name')
'<input name="name" type="text" value="A name">'
supports_microseconds

Атрибут, который по умолчанию имеет значение True. Если установлено значение False, то микросекундная часть значений datetime и time будет установлена в 0.

format_value(value)[исходный код]

Очищает и возвращает значение для использования в шаблоне виджета. value не гарантируется, что это правильный ввод, поэтому реализации подклассов должны программировать защитно.

get_context(name, value, attrs)[исходный код]

Возвращает словарь значений для использования при рендеринге шаблона виджета. По умолчанию словарь содержит единственный ключ 'widget', который является словарным представлением виджета, содержащим следующие ключи:

  • 'name': Имя поля из аргумента name.
  • 'is_hidden': Булево значение, указывающее, является ли данный виджет скрытым или нет.
  • 'required': Булево значение, указывающее, является ли поле для этого виджета обязательным.
  • 'value': Значение, возвращаемое командой format_value().
  • 'attrs': HTML-атрибуты, которые должны быть установлены на отображаемом виджете. Комбинация атрибута attrs и аргумента attrs.
  • 'template_name': Значение self.template_name.

Widget Подклассы могут предоставлять пользовательские значения контекста, переопределяя этот метод.

id_for_label(id_)[исходный код]

Возвращает HTML ID атрибут этого виджета для использования <label>, учитывая ID поля. Возвращает None, если ID недоступен.

Этот хук необходим, поскольку некоторые виджеты имеют несколько элементов HTML и, следовательно, несколько ID. В этом случае данный метод должен возвращать значение ID, соответствующее первому ID в тегах виджета.

render(name, value, attrs=None, renderer=None)[исходный код]

Рендерит виджет в HTML, используя заданный рендерер. Если renderer равно None, используется рендерер из настройки FORM_RENDERER.

value_from_datadict(data, files, name)[исходный код]

Учитывая словарь данных и имя этого виджета, возвращает значение этого виджета. files может содержать данные, полученные из request.FILES. Возвращает None, если значение не было предоставлено. Обратите внимание, что value_from_datadict может быть вызван более одного раза во время обработки данных формы, поэтому, если вы настраиваете его и добавляете дорогостоящую обработку, вам следует самостоятельно реализовать какой-либо механизм кэширования.

value_omitted_from_data(data, files, name)[исходный код]

Учитывая словари data и files и имя этого виджета, возвращает наличие или отсутствие данных или файлов для виджета.

Результат метода влияет на то, является ли поле в форме модели falls back to its default.

Особыми случаями являются CheckboxInput, CheckboxSelectMultiple и SelectMultiple, которые всегда возвращают False, потому что не установленный флажок и не выбранный <select multiple> не появляются в данных отправки HTML-формы, поэтому неизвестно, отправил пользователь значение или нет.

use_required_attribute(initial)[исходный код]

Учитывая значение initial поля формы, возвращает, может ли виджет быть отображен с атрибутом required HTML. Формы используют этот метод вместе с Field.required и Form.use_required_attribute, чтобы определить, отображать или нет атрибут required для каждого поля.

По умолчанию возвращает False для скрытых виджетов и True в противном случае. Особыми случаями являются FileInput и ClearableFileInput, которые возвращают False, когда установлено initial, и CheckboxSelectMultiple, который всегда возвращает False, поскольку валидация браузера требует, чтобы все флажки были отмечены, а не хотя бы один.

Переопределите этот метод в пользовательских виджетах, которые не совместимы с проверкой браузера. Например, виджет текстового редактора WSYSIWG, поддерживаемый скрытым элементом textarea, может захотеть всегда возвращать False, чтобы избежать проверки браузера на скрытое поле.

Changed in Django 3.1:

В старых версиях True возвращалось для FileInput, когда было установлено initial.

MultiWidget

class MultiWidget(widgets, attrs=None)[исходный код]

Виджет, состоящий из нескольких виджетов. MultiWidget работает рука об руку с MultiValueField.

MultiWidget имеет один обязательный аргумент:

widgets

Итерабельность, содержащая необходимые виджеты. Например:

>>> from django.forms import MultiWidget, TextInput
>>> widget = MultiWidget(widgets=[TextInput, TextInput])
>>> widget.render('name', ['john', 'paul'])
'<input type="text" name="name_0" value="john"><input type="text" name="name_1" value="paul">'

Вы можете предоставить словарь, чтобы указать пользовательские суффиксы для атрибута name на каждом субвиджете. В этом случае, для каждой пары (key, widget) ключ будет добавлен к name виджета, чтобы сгенерировать значение атрибута. Вы можете указать пустую строку ('') для одного ключа, чтобы исключить суффикс для одного виджета. Например:

>>> widget = MultiWidget(widgets={'': TextInput, 'last': TextInput})
>>> widget.render('name', ['john', 'paul'])
'<input type="text" name="name" value="john"><input type="text" name="name_last" value="paul">'

И один необходимый метод:

decompress(value)[исходный код]

Этот метод принимает одно «сжатое» значение из поля и возвращает список «распакованных» значений. Входное значение может считаться действительным, но не обязательно непустым.

Этот метод должен быть реализован подклассом, и поскольку значение может быть пустым, реализация должна быть защитной.

Смысл «распаковки» заключается в том, что необходимо «разделить» объединенное значение поля формы на значения для каждого виджета.

Примером может служить то, как SplitDateTimeWidget превращает значение datetime в список, в котором дата и время разделены на два отдельных значения:

from django.forms import MultiWidget

class SplitDateTimeWidget(MultiWidget):

    # ...

    def decompress(self, value):
        if value:
            return [value.date(), value.time()]
        return [None, None]

Совет

Обратите внимание, что MultiValueField имеет дополнительный метод compress() с противоположной обязанностью - объединить очищенные значения всех полей-членов в одно.

Это обеспечивает некоторый пользовательский контекст:

get_context(name, value, attrs)[исходный код]

В дополнение к клавише 'widget', описанной в Widget.get_context(), MultiWidget добавляет клавишу widget['subwidgets'].

Их можно зациклить в шаблоне виджета:

{% for subwidget in widget.subwidgets %}
    {% include subwidget.template_name with widget=subwidget %}
{% endfor %}

Вот пример виджета, который подклассифицирует MultiWidget для отображения даты с днем, месяцем и годом в разных окнах выбора. Этот виджет предназначен для использования с DateField, а не с MultiValueField, поэтому мы реализовали value_from_datadict():

from datetime import date
from django import forms

class DateSelectorWidget(forms.MultiWidget):
    def __init__(self, attrs=None):
        days = [(day, day) for day in range(1, 32)]
        months = [(month, month) for month in range(1, 13)]
        years = [(year, year) for year in [2018, 2019, 2020]]
        widgets = [
            forms.Select(attrs=attrs, choices=days),
            forms.Select(attrs=attrs, choices=months),
            forms.Select(attrs=attrs, choices=years),
        ]
        super().__init__(widgets, attrs)

    def decompress(self, value):
        if isinstance(value, date):
            return [value.day, value.month, value.year]
        elif isinstance(value, str):
            year, month, day = value.split('-')
            return [day, month, year]
        return [None, None, None]

    def value_from_datadict(self, data, files, name):
        day, month, year = super().value_from_datadict(data, files, name)
        # DateField expects a single string that it can parse into a date.
        return '{}-{}-{}'.format(year, month, day)

Конструктор создает несколько Select виджетов в списке. Метод super() использует этот список для настройки виджета.

Необходимый метод decompress() разбивает значение datetime.date на значения дня, месяца и года, соответствующие каждому виджету. Если была выбрана недопустимая дата, например, несуществующее 30 февраля, DateField передает этому методу строку, поэтому ее нужно разобрать. Заключительный return обрабатывает, когда value является None, то есть у нас нет никаких значений по умолчанию для наших подвиджетов.

Реализация по умолчанию value_from_datadict() возвращает список значений, соответствующих каждому Widget. Это уместно при использовании MultiWidget с MultiValueField. Но поскольку мы хотим использовать этот виджет с DateField, который принимает одно значение, мы переопределили этот метод. Реализация здесь объединяет данные из субвиджетов в строку в формате, который ожидает DateField.

Встроенные виджеты

Django предоставляет представление всех основных виджетов HTML, плюс некоторые часто используемые группы виджетов в модуле django.forms.widgets, включая the input of text, various checkboxes and selectors, uploading files и handling of multi-valued input.

Виджеты, обрабатывающие ввод текста

Эти виджеты используют элементы HTML input и textarea.

TextInput

class TextInput[исходный код]
  • input_type: 'text'
  • template_name: 'django/forms/widgets/text.html'
  • Изображается как: <input type="text" ...>

NumberInput

class NumberInput[исходный код]
  • input_type: 'number'
  • template_name: 'django/forms/widgets/number.html'
  • Изображается как: <input type="number" ...>

Имейте в виду, что не все браузеры поддерживают ввод локализованных чисел в типах ввода number. Сам Django избегает их использования для полей, у которых свойство localize установлено в True.

EmailInput

class EmailInput[исходный код]
  • input_type: 'email'
  • template_name: 'django/forms/widgets/email.html'
  • Изображается как: <input type="email" ...>

URLInput

class URLInput[исходный код]
  • input_type: 'url'
  • template_name: 'django/forms/widgets/url.html'
  • Изображается как: <input type="url" ...>

PasswordInput

class PasswordInput[исходный код]
  • input_type: 'password'
  • template_name: 'django/forms/widgets/password.html'
  • Изображается как: <input type="password" ...>

Принимает один необязательный аргумент:

render_value

Определяет, будет ли у виджета заполнено значение при повторном отображении формы после ошибки валидации (по умолчанию False).

HiddenInput

class HiddenInput[исходный код]
  • input_type: 'hidden'
  • template_name: 'django/forms/widgets/hidden.html'
  • Изображается как: <input type="hidden" ...>

Обратите внимание, что существует также виджет MultipleHiddenInput, который заключает в себе набор скрытых элементов ввода.

DateInput

class DateInput[исходный код]
  • input_type: 'text'
  • template_name: 'django/forms/widgets/date.html'
  • Изображается как: <input type="text" ...>

Принимает те же аргументы, что и TextInput, с еще одним необязательным аргументом:

format

Формат, в котором будет отображаться начальное значение этого поля.

Если аргумент format не указан, форматом по умолчанию будет первый формат, найденный в DATE_INPUT_FORMATS и соответствующий Локализация формата.

DateTimeInput

class DateTimeInput[исходный код]
  • input_type: 'text'
  • template_name: 'django/forms/widgets/datetime.html'
  • Изображается как: <input type="text" ...>

Принимает те же аргументы, что и TextInput, с еще одним необязательным аргументом:

format

Формат, в котором будет отображаться начальное значение этого поля.

Если аргумент format не указан, форматом по умолчанию будет первый формат, найденный в DATETIME_INPUT_FORMATS и соответствующий Локализация формата.

По умолчанию микросекундная часть значения времени всегда установлена в 0. Если требуются микросекунды, используйте подкласс с атрибутом supports_microseconds, установленным в True.

TimeInput

class TimeInput[исходный код]
  • input_type: 'text'
  • template_name: 'django/forms/widgets/time.html'
  • Изображается как: <input type="text" ...>

Принимает те же аргументы, что и TextInput, с еще одним необязательным аргументом:

format

Формат, в котором будет отображаться начальное значение этого поля.

Если аргумент format не указан, форматом по умолчанию будет первый формат, найденный в TIME_INPUT_FORMATS и соответствующий Локализация формата.

Об обращении с микросекундами см. в разделе DateTimeInput.

Textarea

class Textarea[исходный код]
  • template_name: 'django/forms/widgets/textarea.html'
  • Изображается как: <textarea>...</textarea>

Виджеты селектора и флажка

Эти виджеты используют элементы HTML <select>, <input type="checkbox"> и <input type="radio">.

Виджеты, отображающие несколько вариантов выбора, имеют атрибут option_template_name, который определяет шаблон, используемый для отображения каждого варианта. Например, для виджета Select, select_option.html рендерит <option> для <select>.

CheckboxInput

class CheckboxInput[исходный код]
  • input_type: 'checkbox'
  • template_name: 'django/forms/widgets/checkbox.html'
  • Изображается как: <input type="checkbox" ...>

Принимает один необязательный аргумент:

check_test

Вызываемый элемент, который принимает значение CheckboxInput и возвращает True, если флажок должен быть установлен для этого значения.

Select

class Select[исходный код]
  • template_name: 'django/forms/widgets/select.html'
  • option_template_name: 'django/forms/widgets/select_option.html'
  • Изображается как: <select><option ...>...</select>
choices

Этот атрибут необязателен, если поле формы не имеет атрибута choices. Если он есть, то при обновлении атрибута на Field он будет переопределять все, что вы задали здесь.

NullBooleanSelect

class NullBooleanSelect[исходный код]
  • template_name: 'django/forms/widgets/select.html'
  • option_template_name: 'django/forms/widgets/select_option.html'

Выберите виджет с опциями „Неизвестно“, „Да“ и „Нет“

SelectMultiple

class SelectMultiple[исходный код]
  • template_name: 'django/forms/widgets/select.html'
  • option_template_name: 'django/forms/widgets/select_option.html'

Аналогично Select, но допускает множественный выбор: <select multiple>...</select>

RadioSelect

class RadioSelect[исходный код]
  • template_name: 'django/forms/widgets/radio.html'
  • option_template_name: 'django/forms/widgets/radio_option.html'

Аналогично Select, но отображается как список радиокнопок в тегах <li>:

<ul>
  <li><input type="radio" name="..."></li>
  ...
</ul>

Для более детального контроля над генерируемой разметкой вы можете перебирать радиокнопки в шаблоне. Предположим форму myform с полем beatles, которое использует RadioSelect в качестве виджета:

{% for radio in myform.beatles %}
<div class="myradio">
    {{ radio }}
</div>
{% endfor %}

Это приведет к созданию следующего HTML:

<div class="myradio">
    <label for="id_beatles_0"><input id="id_beatles_0" name="beatles" type="radio" value="john" required> John</label>
</div>
<div class="myradio">
    <label for="id_beatles_1"><input id="id_beatles_1" name="beatles" type="radio" value="paul" required> Paul</label>
</div>
<div class="myradio">
    <label for="id_beatles_2"><input id="id_beatles_2" name="beatles" type="radio" value="george" required> George</label>
</div>
<div class="myradio">
    <label for="id_beatles_3"><input id="id_beatles_3" name="beatles" type="radio" value="ringo" required> Ringo</label>
</div>

Это включает в себя теги <label>. Для более детальной настройки можно использовать атрибуты tag, choice_label и id_for_label каждой радиокнопки. Например, этот шаблон…

{% for radio in myform.beatles %}
    <label for="{{ radio.id_for_label }}">
        {{ radio.choice_label }}
        <span class="radio">{{ radio.tag }}</span>
    </label>
{% endfor %}

…приведет к следующему HTML:

<label for="id_beatles_0">
    John
    <span class="radio"><input id="id_beatles_0" name="beatles" type="radio" value="john" required></span>
</label>

<label for="id_beatles_1">
    Paul
    <span class="radio"><input id="id_beatles_1" name="beatles" type="radio" value="paul" required></span>
</label>

<label for="id_beatles_2">
    George
    <span class="radio"><input id="id_beatles_2" name="beatles" type="radio" value="george" required></span>
</label>

<label for="id_beatles_3">
    Ringo
    <span class="radio"><input id="id_beatles_3" name="beatles" type="radio" value="ringo" required></span>
</label>

Если вы решите не зацикливать радиокнопки - например, если ваш шаблон включает {{ myform.beatles }} - они будут выведены в тегах <ul> с <li>, как указано выше.

Внешний контейнер <ul> получает атрибут id виджета, если он определен, или BoundField.auto_id в противном случае.

При переходе по радиокнопкам теги label и input включают атрибуты for и id соответственно. Каждая радиокнопка имеет атрибут id_for_label для вывода идентификатора элемента.

CheckboxSelectMultiple

class CheckboxSelectMultiple[исходный код]
  • template_name: 'django/forms/widgets/checkbox_select.html'
  • option_template_name: 'django/forms/widgets/checkbox_option.html'

Аналогично SelectMultiple, но отображается как список флажков:

<ul>
  <li><input type="checkbox" name="..." ></li>
  ...
</ul>

Внешний контейнер <ul> получает атрибут id виджета, если он определен, или BoundField.auto_id в противном случае.

Как и RadioSelect, вы можете перебирать отдельные флажки для выбора вариантов виджета. В отличие от RadioSelect, флажки не будут включать HTML-атрибут required, если поле является обязательным, поскольку проверка браузера потребует, чтобы все флажки были отмечены, а не хотя бы один.

При переборе флажков теги label и input включают атрибуты for и id соответственно. Каждый флажок имеет атрибут id_for_label для вывода ID элемента.

Виджеты загрузки файлов

FileInput

class FileInput[исходный код]
  • template_name: 'django/forms/widgets/file.html'
  • Изображается как: <input type="file" ...>

ClearableFileInput

class ClearableFileInput[исходный код]
  • template_name: 'django/forms/widgets/clearable_file_input.html'
  • Отображается как: <input type="file" ...> с дополнительным вводом флажка для очистки значения поля, если поле не является обязательным и имеет исходные данные.

Составные виджеты

MultipleHiddenInput

class MultipleHiddenInput[исходный код]
  • template_name: 'django/forms/widgets/multiple_hidden.html'
  • Отображается как: несколько тегов <input type="hidden" ...>

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

SplitDateTimeWidget

class SplitDateTimeWidget[исходный код]
  • template_name: 'django/forms/widgets/splitdatetime.html'

Обертка (с использованием MultiWidget) вокруг двух виджетов: DateInput для даты и TimeInput для времени. Должна использоваться с SplitDateTimeField, а не с DateTimeField.

SplitDateTimeWidget имеет несколько необязательных аргументов:

date_format

Аналогично DateInput.format

time_format

Аналогично TimeInput.format

date_attrs
time_attrs

Аналогично Widget.attrs. Словарь, содержащий HTML-атрибуты, которые должны быть установлены на отрисованных виджетах DateInput и TimeInput соответственно. Если эти атрибуты не установлены, вместо них используется Widget.attrs.

SplitHiddenDateTimeWidget

class SplitHiddenDateTimeWidget[исходный код]
  • template_name: 'django/forms/widgets/splithiddendatetime.html'

Аналогично SplitDateTimeWidget, но использует HiddenInput как для даты, так и для времени.

SelectDateWidget

class SelectDateWidget[исходный код]
  • template_name: 'django/forms/widgets/select_date.html'

Обертка вокруг трех виджетов Select: по одному для месяца, дня и года.

Принимает несколько необязательных аргументов:

years

Необязательный список/кортеж лет для использования в поле выбора «Год». По умолчанию используется список, содержащий текущий год и следующие 9 лет.

months

Необязательный набор месяцев для использования в поле выбора «Месяцы».

Ключи диктанта соответствуют номеру месяца (с индексацией 1), а значения - отображаемым месяцам:

MONTHS = {
    1:_('jan'), 2:_('feb'), 3:_('mar'), 4:_('apr'),
    5:_('may'), 6:_('jun'), 7:_('jul'), 8:_('aug'),
    9:_('sep'), 10:_('oct'), 11:_('nov'), 12:_('dec')
}
empty_label

Если DateField не требуется, SelectDateWidget будет иметь пустой выбор в верхней части списка (по умолчанию это ---). Текст этой метки можно изменить с помощью атрибута empty_label. empty_label может быть string, list или tuple. Если используется строка, все поля выбора будут иметь пустой выбор с этой меткой. Если empty_label является list или tuple из трех строковых элементов, то поля выбора будут иметь свою собственную пользовательскую метку. Метки должны располагаться в таком порядке ('year_label', 'month_label', 'day_label').

# A custom empty label with string
field1 = forms.DateField(widget=SelectDateWidget(empty_label="Nothing"))

# A custom empty label with tuple
field1 = forms.DateField(
    widget=SelectDateWidget(
        empty_label=("Choose Year", "Choose Month", "Choose Day"),
    ),
)
Вернуться на верх