Spec-Zone.ru › Django 6.0

Виджеты

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

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

Совет

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

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

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

Однако, если для поля требуется другой виджет, можно использовать аргумент 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 использует представление в виде списка HTML <select>, а 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, если варианты являются неотъемлемой частью модели, а не просто способом отображения виджета.

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

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

Настроить виджеты можно двумя способами: для каждого экземпляра виджета и для класса виджета.

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

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

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

from django import forms


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

В этой форме для полей имени и комментария будут использоваться виджеты TextInput, а для поля URL — виджет URLInput. Для каждого используется стандартное представление — без класса CSS и дополнительных атрибутов:

>>> f = CommentForm(auto_id=False)
>>> print(f)
<div>Name:<input type="text" name="name" required></div>
<div>Url:<input type="url" name="url" required></div>
<div>Comment:<input type="text" name="comment" required></div>

На настоящей веб-странице, вероятно, потребуется настроить виджеты. Например, для комментария может потребоваться более крупный элемент ввода, а для виджета «имя» — особый класс 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")

Если поле не объявлено непосредственно в форме (например, если это поле ModelForm), можно использовать атрибут 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)
>>> print(f)
<div>Name:<input type="text" name="name" class="special" required></div>
<div>Url:<input type="url" name="url" required></div>
<div>Comment:<input type="text" name="comment" size="40" required></div>

Также можно задать HTML-атрибут id с помощью attrs. Пример см. в описании BoundField.id_for_label.

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

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

Вкратце, потребуется создать подкласс виджета и либо определить вложенный класс «Media», либо создать свойство «media».

Эти способы требуют несколько продвинутых навыков программирования на Python и подробно описаны в тематическом руководстве Ресурсы форм.

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

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

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 поля. Если ID недоступен, возвращается пустая строка.

Этот метод необходим, поскольку некоторые виджеты содержат несколько HTML-элементов и, следовательно, несколько идентификаторов. В таком случае этот метод должен возвращать значение 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 и имя этого виджета, возвращает признак наличия данных или файлов для виджета.

Результат этого метода влияет на то, будет ли поле ModelForm использовать значение по умолчанию.

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

use_fieldset

Атрибут, определяющий, следует ли при отображении группировать виджет в <fieldset> с <legend>. По умолчанию имеет значение False, но принимает значение True, если виджет содержит несколько тегов <input>, например CheckboxSelectMultiple, RadioSelect, MultiWidget, SplitDateTimeWidget и SelectDateWidget.

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

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

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

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

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, включая ввод текста, различные флажки и списки выбора, загрузку файлов и обработку многозначного ввода.

Виджеты для ввода текста

Эти виджеты используют элементы 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" ...>

ColorInput

Добавлено в Django 5.2.
class ColorInput [исходный код]
  • input_type: 'color'
  • template_name:'django/forms/widgets/color.html'
  • Отображается как: <input type="color" ...>

SearchInput

Добавлено в Django 5.2.
class SearchInput [исходный код]
  • input_type: 'search'
  • template_name: 'django/forms/widgets/search.html'
  • Отображается как: <input type="search" ...>

TelInput

Добавлено в Django 5.2.
class TelInput [исходный код]
  • input_type: 'tel'
  • template_name: 'django/forms/widgets/tel.html'
  • Отображается как: <input type="tel" ...>

По умолчанию браузеры не выполняют проверку данных на стороне клиента, поскольку форматы телефонных номеров сильно различаются по всему миру. Вы можете добавить такую проверку, задав pattern, minlength или maxlength в аргументе Widget.attrs.

Кроме того, вы можете добавить проверку на стороне сервера для поля формы с помощью валидатора, например RegexValidator, или стороннего пакета, например django-phonenumber-field.

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 с учетом локализации форматов. Этот виджет не поддерживает форматы %U, %W и %j.

DateTimeInput

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

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

format

Формат отображения начального значения этого поля.

Если аргумент format не указан, по умолчанию используется первый формат из DATETIME_INPUT_FORMATS с учетом локализации форматов. Этот виджет не поддерживает форматы %U, %W и %j.

По умолчанию микросекундная часть значения времени всегда устанавливается в 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, но отображается в виде списка переключателей внутри тегов <div>:

<div>
  <div><input type="radio" name="..."></div>
  ...
</div>

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

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

В результате будет сгенерирован следующий HTML:

<fieldset>
    <legend>Radio buttons</legend>
    <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>
</fieldset>

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

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

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

<fieldset>
    <legend>Radio buttons</legend>
    <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>
</fieldset>

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

Внешний контейнер <div> получает атрибут 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, но отображается в виде списка флажков:

<div>
  <div><input type="checkbox" name="..." ></div>
  ...
</div>

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

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

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

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

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 из 3 строковых элементов, у каждого списка выбора будет собственная метка. Метки должны быть расположены в следующем порядке: ('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"),
    ),
)

© Django Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/6.0/ref/forms/widgets/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API