Spec-Zone.ru › Django 5.0

Виджеты

Виджет — это представление Django HTML-элемента ввода. Виджет обрабатывает рендеринг 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, в то время как 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 будут выглядеть одинаково на ваших веб-страницах.

Существует два способа настройки виджетов: для каждого экземпляра виджета и для каждого класса виджета.

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

Если вы хотите, чтобы один экземпляр виджета выглядел по-другому, вам нужно указать дополнительные атрибуты при создании объекта виджета и привязке его к полю формы (и, возможно, добавить некоторые правила в свои файлы 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)
>>> 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. Также можно указать атрибут «тип», чтобы воспользоваться новыми типами ввода 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)
>>> 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. В этом случае этот метод должен вернуть значение 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 и имя этого виджета, возвращает, есть ли данные или файлы для виджета.

Результат метода влияет на то, будет ли поле в форме модели возвращаться к своему значению по умолчанию.

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

Переопределите этот метод в пользовательских виджетах, которые несовместимы с валидацией браузера. Например, виджет WYSIWYG-редактора текста, поддерживаемый скрытым элементом 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" ...>

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'
  • Renders as: <input type="text" ...>

Takes same arguments as TextInput, with one more optional argument:

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'
  • Renders as: <input type="text" ...>

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

format

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

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

Обработка микросекунд аналогична DateTimeInput.

Textarea

class Textarea
  • template_name: 'django/forms/widgets/textarea.html'
  • Renders as: <textarea>...</textarea>

Selector and checkbox widgets

Эти виджеты используют 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'
  • Renders as: <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'
  • Renders as: <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, чекбоксы не будут включать атрибут required HTML, если поле является обязательным, потому что валидация браузера потребует проверки всех чекбоксов, а не хотя бы одного.

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

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

FileInput

class FileInput
  • template_name: 'django/forms/widgets/file.html'
  • Renders as: <input type="file" ...>

ClearableFileInput

class ClearableFileInput
  • template_name: 'django/forms/widgets/clearable_file_input.html'
  • Renders as: <input type="file" ...> с дополнительным чекбоксом для очистки значения поля, если поле не обязательно и имеет начальные данные.

Композитные виджеты

MultipleHiddenInput

class MultipleHiddenInput
  • template_name: 'django/forms/widgets/multiple_hidden.html'
  • Renders as: несколько тегов <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/5.0/ref/forms/widgets/

Spec-Zone.ru

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