Способ передать варианты выбора choices в forms.ChoiceField из views.py
Недавно сам столкнулся с проблемой передачи вариантов выбора для поля формы с типом виджета Radio и типом формы forms.ChoiceField из views.py. Зачем, почему и какая проблема, объясню далее.
Все интернет-статьи и умные советы были о том, что заведи в forms.py или прямо в models.py список, который будет состоять из кортежей:
CHOICES = [
(1, Вариант 1),
(2, Вариант 2)
]
class TestForm(forms.Form):
otv1 = forms.ChoiceField(widget=forms.RadioSelect(), choices=CHOICES)
Однако, это всё бесполезно, так как до обработки некоторых строк во views.py я не знаю какие варианты выбора должны быть. В конце концов, один из советчиков предложил создать форму прямо в контроллер-функции, но предупредив о том, что это будет грязный и кривой метод. И да, если так сделать, будут проблемы с POST запросами, но не в этом суть. Недолго подумав, я понял как можно передать варианты выбора choices из функции контроллера в форму, и сделать это можно всего одной строкой, ну ладно, двумя:
choice_field = forms.ChoiceField(label=course.Test1, widget=forms.RadioSelect(),
choices=CHOICES)
form.fields["otv1"] = choice_field
Для того, чтобы вам было проще понять, покажу models.py
class Course(models.Model):
...
Test1 = models.TextField(blank=True, verbose_name='Тест 1')
Test1_1 = models.TextField(blank=True, verbose_name='Тест 1 - Ответ 1')
Test1_2 = models.TextField(blank=True, verbose_name='Тест 1 - Ответ 2')
Test1_3 = models.TextField(blank=True, verbose_name='Тест 1 - Ответ 3')
Test1_4 = models.TextField(blank=True, verbose_name='Тест 1 - Ответ 4')
Test1_5 = models.TextField(blank=True, verbose_name='Тест 1 - Правильный ответ')
Также покажу forms.py:
from django import forms
from .models import Course
class TestForm(forms.Form):
otv1 = forms.CharField(label='Вопрос:')
Ну и фрагмент views.py:
initial = {}
CHOICES = [
(course.Test1_1, course.Test1_1),
(course.Test1_2, course.Test1_2),
(course.Test1_3, course.Test1_3),
(course.Test1_4, course.Test1_4)
]
choice_field = forms.ChoiceField(label=course.Test1, widget=forms.RadioSelect(),
choices=CHOICES)
form_class = TestForm
form = form_class(initial=initial)
form.fields["otv1"] = choice_field
if request.method == 'POST':
c_form = form_class(request.POST)
if c_form.is_valid():
TestVop = c_form.cleaned_data.get("otv1")
# print(TestVop)
if TestVop == course.Test1_5:
messages.add_message(request, messages.WARNING, 'Правильно!')
else:
messages.add_message(request, messages.WARNING, 'Не правильно!')
else:
form = c_form
messages.add_message(request, messages.WARNING, 'Не правильно!')