Виджет RadioSelect
Виджет RadioSelect предназначен для отображения выбора одного
варианта из нескольких в виде списка радио-кнопок. Он используется
с полями выбора, такими как ChoiceField,
ModelChoiceField или TypedChoiceField. По умолчанию
Django отображает выбор с помощью виджета Select, но
RadioSelect дает более наглядный интерфейс, особенно когда
вариантов немного и нужно сразу видеть все доступные опции.
Виджет поддерживает настройку отображения с помощью атрибутов
attrs, а также позволяет кастомизировать HTML-разметку
каждой радио-кнопки и её подписи через параметр choice_label
или шаблоны. По умолчанию радио-кнопки выводятся вертикально,
но это поведение можно изменить с помощью CSS или переопределением
шаблона виджета.
Синтаксис
from django import forms
class MyForm(forms.Form):
field_name = forms.ChoiceField(
choices=CHOICES,
widget=forms.RadioSelect
)
Пример . С ChoiceField
Создадим форму с выбором статуса заказа с помощью радио-кнопок:
from django import forms
class OrderForm(forms.Form):
STATUS_CHOICES = [
('pending', 'Pending'),
('processing', 'Processing'),
('completed', 'Completed'),
('cancelled', 'Cancelled'),
]
status = forms.ChoiceField(
choices=STATUS_CHOICES,
widget=forms.RadioSelect,
initial='pending'
)
Результат вывода формы в шаблоне:
<ul id="id_status">
<li>
<label for="id_status_0">
<input type="radio" name="status" value="pending" id="id_status_0" checked>
Pending
</label>
</li>
<li>
<label for="id_status_1">
<input type="radio" name="status" value="processing" id="id_status_1">
Processing
</label>
</li>
<li>
<label for="id_status_2">
<input type="radio" name="status" value="completed" id="id_status_2">
Completed
</label>
</li>
<li>
<label for="id_status_3">
<input type="radio" name="status" value="cancelled" id="id_status_3">
Cancelled
</label>
</li>
</ul>
Пример . С ModelChoiceField
Используем RadioSelect для выбора категории из модели
в форме редактирования статьи:
from django import forms
from myapp.models import Category, Article
class ArticleForm(forms.ModelForm):
category = forms.ModelChoiceField(
queryset=Category.objects.all(),
widget=forms.RadioSelect,
empty_label=None
)
class Meta:
model = Article
fields = ['title', 'content', 'category']
В контроллере создаем форму и передаем в шаблон:
from django.shortcuts import render
from myapp.forms import ArticleForm
def create_article(request):
form = ArticleForm()
return render(request, 'article_form.html', {'form': form})
В шаблоне выводим форму:
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Save</button>
</form>
Настройка атрибутов
Добавим CSS-классы и атрибуты к радио-кнопкам через параметр
attrs:
from django import forms
class SurveyForm(forms.Form):
RATING_CHOICES = [
(1, 'Very Bad'),
(2, 'Bad'),
(3, 'Normal'),
(4, 'Good'),
(5, 'Very Good'),
]
rating = forms.ChoiceField(
choices=RATING_CHOICES,
widget=forms.RadioSelect(
attrs={
'class': 'rating-radio',
'data-type': 'survey'
}
),
initial=3
)
В результате каждая радио-кнопка получит атрибуты:
<input type="radio" name="rating" value="3" id="id_rating_2"
class="rating-radio" data-type="survey" checked>
Кастомизация отображения
Для более гибкой настройки вы можете переопределить шаблон
виджета. Создадим форму с выбором дня недели и кастомизируем
разметку через параметр choice_label:
from django import forms
class ScheduleForm(forms.Form):
DAY_CHOICES = [
('mon', 'Monday'),
('tue', 'Tuesday'),
('wed', 'Wednesday'),
('thu', 'Thursday'),
('fri', 'Friday'),
]
day = forms.ChoiceField(
choices=DAY_CHOICES,
widget=forms.RadioSelect,
initial='mon'
)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['day'].widget.choice_label = lambda choice: f"<span class='day-label'>{choice[1]}</span>"
В контроллере проверим работу формы:
from django.shortcuts import render
from myapp.forms import ScheduleForm
def schedule_view(request):
if request.method == 'POST':
form = ScheduleForm(request.POST)
if form.is_valid():
print("Selected day:", form.cleaned_data['day'])
else:
form = ScheduleForm()
return render(request, 'schedule.html', {'form': form})
Результат вывода в консоль при отправке формы:
"Selected day: wed"
Вертикальное и горизонтальное отображение
По умолчанию RadioSelect выводит варианты вертикально.
Чтобы сделать горизонтальное расположение, используйте CSS:
<style>
ul.radio-group {
list-style: none;
padding: 0;
display: flex;
gap: 20px;
}
ul.radio-group li {
display: inline-block;
}
</style>
{{ form.field_name }}
Либо задайте класс непосредственно в атрибутах виджета:
from django import forms
class ColorForm(forms.Form):
COLOR_CHOICES = [
('red', 'Red'),
('green', 'Green'),
('blue', 'Blue'),
]
color = forms.ChoiceField(
choices=COLOR_CHOICES,
widget=forms.RadioSelect(
attrs={'class': 'horizontal-radio'}
)
)
Смотрите также
-
виджет
Select,
который выводит выбор в виде выпадающего списка -
виджет
CheckboxSelectMultiple,
который выводит множественный выбор в виде чекбоксов -
виджет
NullBooleanSelect,
который выводит выбор для булевого поля с тремя состояниями -
виджет
SelectMultiple,
который выводит множественный выбор в виде списка