Spec-Zone.ru › Django 4.1

Виджеты

Виджет — это представление 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-списка <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, когда варианты выбора присущи модели, а не просто представлению.

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

При рендеринге 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)
>>> 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>

На реальной веб-странице вы, вероятно, не захотите, чтобы все виджеты выглядели одинаково. Возможно, вы захотите, чтобы поле комментария было больше, и, возможно, виджет «имя» должен иметь особый 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) и более глубоко настраивать их внешний вид и поведение.

Вкратце, вам нужно будет унаследовать виджет и либо определить внутренний класс «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
Добавлено в Django 4.1.

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

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, но отображается как список радиокнопок внутри тегов <div>:

<div>
  <div><input type="radio" name="..."></div>
  ...
</div>
Изменено в Django 4.0:

Для более лаконичного объявления с помощью экранных читателей радиокнопки были переделаны на отображение в тегах <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 для вывода ID элемента.

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 в противном случае.

Изменено в Django 4.0:

Для более лаконичного объявления с помощью экранных читателей чекбоксы были переделаны на отображение в тегах <div>.

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

При переборе чекбоксов теги 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 из 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/4.1/ref/forms/widgets/

Spec-Zone.ru

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