Виджет NullBooleanSelect
Виджет NullBooleanSelect применяется к полю формы NullBooleanField и представляет собой выпадающий список (select) с тремя опциями: "Unknown" (значение None), "Yes" (значение True) и "No" (значение False). Этот виджет используется, когда необходимо предоставить пользователю возможность выбора между тремя состояниями: утвердительным, отрицательным и неопределенным. По умолчанию NullBooleanSelect используется для поля NullBooleanField в формах Django.
Синтаксис
from django import forms
class MyForm(forms.Form):
field_name = forms.NullBooleanField(
widget=forms.NullBooleanSelect(attrs={'class': 'my-class'})
)
Виджет принимает необязательный параметр attrs для передачи HTML-атрибутов элемента select.
Пример
Давайте создадим форму с полем для выбора статуса согласия пользователя:
from django import forms
class ConsentForm(forms.Form):
agree = forms.NullBooleanField(
label="Are you agree?",
widget=forms.NullBooleanSelect(attrs={'class': 'form-select'})
)
def clean_agree(self):
agree = self.cleaned_data.get('agree')
if agree is None:
raise forms.ValidationError("Please make a choice.")
return agree
Теперь создадим экземпляр формы и отобразим поле в шаблоне:
from django.shortcuts import render
from .forms import ConsentForm
def consent_view(request):
form = ConsentForm()
return render(request, 'consent.html', {'form': form})
В шаблоне вы можете отобразить поле следующим образом:
<form method="post">
{% csrf_token %}
{{ form.agree }}
<button type="submit">Submit</button>
</form>
Результат в HTML будет выглядеть так:
<select name="agree" class="form-select">
<option value="1">Unknown</option>
<option value="2">Yes</option>
<option value="3">No</option>
</select>
Пример
Давайте обработаем отправленные данные формы с использованием NullBooleanSelect:
from django import forms
from django.shortcuts import render
from django.http import HttpResponse
class SubscriptionForm(forms.Form):
subscribe = forms.NullBooleanField(
label="Subscribe to newsletter?",
widget=forms.NullBooleanSelect
)
def subscription_view(request):
if request.method == 'POST':
form = SubscriptionForm(request.POST)
if form.is_valid():
subscribe = form.cleaned_data['subscribe']
if subscribe is True:
return HttpResponse("Subscription confirmed.")
elif subscribe is False:
return HttpResponse("Subscription declined.")
else:
return HttpResponse("No decision made.")
else:
form = SubscriptionForm()
return render(request, 'subscription.html', {'form': form})
Результат выполнения для разных вариантов выбора:
# Если выбрано "Yes" (значение 2):
"Subscription confirmed."
# Если выбрано "No" (значение 3):
"Subscription declined."
# Если выбрано "Unknown" (значение 1):
"No decision made."
Пример
Давайте используем виджет с моделью через ModelForm для поля, допускающего значение None:
from django.db import models
from django import forms
class UserProfile(models.Model):
user = models.OneToOneField('auth.User', on_delete=models.CASCADE)
receive_emails = models.BooleanField(null=True, blank=True)
class ProfileForm(forms.ModelForm):
class Meta:
model = UserProfile
fields = ['receive_emails']
widgets = {
'receive_emails': forms.NullBooleanSelect(
attrs={'class': 'form-control'}
),
}
# Создаем форму с существующим экземпляром
profile = UserProfile.objects.get(id=1)
form = ProfileForm(instance=profile)
# Выводим HTML виджета
print(form['receive_emails'].as_widget())
Результат выполнения кода:
<select name="receive_emails" class="form-control">
<option value="1">Unknown</option>
<option value="2" selected>Yes</option>
<option value="3">No</option>
</select>
Смотрите также
-
виджет
CheckboxInput,
который используется для полей с двумя состояниями -
виджет
Select,
который создает стандартный выпадающий список -
виджет
RadioSelect,
который отображает выбор в виде радиокнопок -
поле
BooleanField,
которое предназначено для булевых значений