Блог Алексея Черемных

Способ передать варианты выбора choices в forms.ChoiceField из views.py

Категория: Разработка Теги: Веб-разработка Опубликовано: 21 июня 2021 г. 18:00
Код
Код

Недавно сам столкнулся с проблемой передачи вариантов выбора для поля формы с типом виджета 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, 'Не правильно!')

Похожие материалы:


Код функции-контроллера с декоратором
Разрешить только определенные HTTP запросы при помощи require_http_methods в Django
Автор: Алексей Черемных3 января 2021

В Django существует довольно простой способ разрешить только определенные типы HTTP запросов при помощи декоратора представлений require_http_methods.

Для этого необходимо во …

Форма заявки (пример)
Django автоматическое заполнение поля в модели при её создании
Автор: Алексей Черемных10 января 2021

Появилась необходимость заполнить поле с номером заявки до формирования формы, связанной с моделью, но как это сделать? В интернете много способов, …

Код функции
Простой способ в Django блокировать конкретные IP на всем сайте
Автор: Алексей Черемных3 января 2021

На любом сайте приходится блокировать определенные IP адреса. Если таковых нет, это значит только одно - что этим сайтом никто не …

VisualSEOStudio
Бесплатная программа для создания карты сайта
Автор: Алексей Черемных30 ноября 2020

Сегодня не так много бесплатных программ для создания карты сайта. Пара штук, и те работают как не очень. О переводе …

Прогон по каталогам
Есть ли эффект от прогонов по каталогам?
Автор: Алексей Черемных28 ноября 2020

Уже давно разного рода сео специалисты спорят о пользе от прогона по каталогам. Под прогоном имеется в виду рассылка объявлений, …

CleanTalk
Лучшая система для фильтрации спама на сайте
Автор: Алексей Черемных30 ноября 2020

Сегодня Вам прорекламирую безусловно лучшую в рунете систему фильтрации спама для сайтов CleanTalk!

С данным сервисов работаю с 2018 года, …

Все теги:

Подписка на рассылку свежих статей