Выберите правильный вариант. 6da87c51321849bdb7da80990fdab19b не является одним из доступных вариантов выбора

Я использую поле answers в форме только для тестирования, чтобы проверить, возвращает ли оно выбранный id значения в пост-запросе, когда форма отправлена, также я передаю варианты динамически в представления from с помощью get_form_kwargs(), На фронтенде он показывает мне правильные варианты, но когда один выбран и отправлен, он показывает мне ошибку, указанную в теме этого вопроса

Также, к вашему сведению, я не включил поле "answerss" в модели, потому что я просто хотел проверить, возвращает ли оно правильный id при POST запросе.

Это мой динамически передаваемый список из views.py в forms.py для заполнения вариантов поля "answerss", созданного в init. Этот список продолжает меняться после каждой отправки

Также FYI это приложение викторины, поэтому после каждой отправки я перенаправляю его на ту же страницу, где следующий вопрос отображается и различные варианты отображаются в поле выбора

[('d5730fbb3b1742d183d0968802859c7d', 'Africa'), ('6da87c51321849bdb7da80990fdab19b', 'Asia'), ('e0d084ff6e7544478523149186835132', 'North America')]

Это мой model.py

class userAnswer(models.Model):
answer_id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
user_id= models.ForeignKey(CustomUser,on_delete=models.CASCADE)
question_id = models.ForeignKey(question,on_delete=models.CASCADE)
text_ans = models.CharField(max_length=100)
remaining_time = models.TimeField(default='23:00:00')
correct_Answer_id = models.ForeignKey(correctAnswer,on_delete=models.CASCADE)

Это мой views.py

class Start_Game(FormView):
model = userAnswer
template_name = 'test_template.html'
form_class = Useranswer
success_url = 'game'
context_object_name = 'questions'
question_collection = []
question_id_collection = []
count = 0

def __init__(self) :
    
    if len(Start_Game.question_id_collection)!=0:
            Start_Game.question_id_collection = []
            Start_Game.question_collection = []
    find = quizz.objects.get(category=formality.question_subject)
    ids = question.objects.all().filter(quiz_id = find.quiz_id)
    for i in ids:
            Start_Game.question_id_collection.append(i.question_id)
            Start_Game.question_collection.append(i)     

def get_context_data(self,*args,**kwargs) :
    context = super().get_context_data(*args,**kwargs)
    context['data4'] = correctAnswer.objects.all().filter(question_id = 
    Start_Game.question_id_collection[Start_Game.count])
    context['data5'] = question.objects.filter(question = 
    Start_Game.question_collection[Start_Game.count]).values('question_id')
    context['data6'] = correctAnswer.objects.filter( check_answer_bool = 1, question_id = 
    Start_Game.question_collection[Start_Game.count] ).values('correct_Answer_id')
    
    context['data2'] = Start_Game.count
    context['data3'] = Start_Game.question_collection[Start_Game.count]
    # context['data4']  = Start_Game.question_id_collection[Start_Game.count]
    Start_Game.count+=1
    if Start_Game.count>len(Start_Game.question_collection)-1:
        Start_Game.count=0  
        return context
    return context

def get_form_kwargs(self, *args,**kwargs) :
    message = super(Start_Game,self).get_form_kwargs(*args,**kwargs)
    option_choice = []
    #q = correctAnswer.objects.only('answer').values_list('correct_Answer_id','answer')
    q = correctAnswer.objects.all().filter(question_id = Start_Game.question_id_collection[Start_Game.count]).values_list('correct_Answer_id','answer')
    for i in range(len(q)):
        option_choice.append(((q[i][0]).hex,q[i][1]))
        
   
    message['options'] =    option_choice      
   
    return  message

def form_valid(self, form) :
    print('selected id is ',self.request.POST.get('answers')) #checking if id is returned properly when form is submitted after selecting from MultichoiceField
    obj = form.save(commit= False)
    obj.user_id = self.request.user
    obj.question_id_id = question.objects.filter(question = Start_Game.question_collection[Start_Game.count-1]).values('question_id')
    obj.correct_Answer_id_id = correctAnswer.objects.filter( check_answer_bool = 1, question_id = Start_Game.question_id_collection[Start_Game.count-1] ).values('correct_Answer_id')
    obj.save()
    return super().form_valid(form)

Мой forms.py

  class Useranswer(forms.ModelForm):
     def __init__(self,*args, **kwargs) :
    
        options_availble = kwargs.pop('options',None)
        super(Useranswer,self).__init__(*args, **kwargs)
    
        self.fields["answerss"] = forms.MultipleChoiceField(choices=options_availble)
    
    class Meta :
        model = userAnswer
        fields = ('text_ans',)

Этот фрагмент перед отправкой формы (Пожалуйста, игнорируйте поле "Текст ответа") enter image description here

Этот снимок сделан после подачи документов

enter image description here

Решил это, В основном, когда я отправлял свою форму, создавался пост-запрос, поэтому я думал, что если пользователь правильно заполнил все необходимые данные в форме, то он сразу перейдет к методу form_valid(), но я ошибался, прежде чем перейти к методу подтверждения формы, он инициализирует мой метод __init__ класса Start_Game в представлении, после чего он инициализирует мой get_form_kwargs(), поэтому в этом get_form_kwargs() я написал код для генерации следующего вопроса и его вариантов, чтобы отправить его в мою форму в forms. py, так что это непосредственно обновит мою опцию multichoice в forms с опцией следующих вопросов и после обновления опции multichoice она затем сравнит мои ранее выбранные значения опций с недавно обновленными значениями, так что, очевидно, это создало вышеуказанную ошибку, так как выбранная опция не была доступна в обновленных опциях, так что в основном я записал условие if в следующем коде, чтобы проверить, был ли запрос post или get

def get_form(self,*args, **kwargs):
    if self.request.method == 'GET':
        self.question_and_type.clear()
        self.unanswered_question = UserAnswer.get_unanswered_question(self.request.user.UserId,
                                                                      Quiz.objects.get(category = self.slug).quizId)
        
        self.question = self.unanswered_question.first()
        self.type = self.question.type
        self.question_and_type.extend([self.question, self.type])
        return self.form_class(**self.get_form_kwargs())
    else :
        form = AnswerForm(question = self.question_and_type[0],
                          type = self.question_and_type[1], 
                          data = self.request.POST)
        return form

def get_form_kwargs(self):
    if self.request.method == 'GET' :
        kwargs =  super().get_form_kwargs()
        return dict(kwargs,question=self.question,type=self.type)

Итак, теперь я буду получать новые вопросы только если запрос был "GET", если же запрос был "POST", то я просто отправлю данные текущего вопроса в форму

   form =  AnswerForm(question = self.question_and_type[0],
                                  type = self.question_and_type[1], 
                                  data = self.request.POST)

чтобы он мог успешно проверить, присутствовал ли выбранный вариант в доступных вариантах. К вашему сведению, я храню предыдущие вопросы в self.question_and_type. пока выполняется запрос 'GET'. Вы можете проверить мой github для получения более подробной информации GITHUB_ЗДЕСЬ

Я думаю, что это не самый эффективный способ, но он сработал для меня, и если есть другой хороший способ, не стесняйтесь комментировать :)

Вернуться на верх