Выберите правильный вариант. 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',)
Этот фрагмент перед отправкой формы (Пожалуйста, игнорируйте поле "Текст ответа")
Этот снимок сделан после подачи документов
Решил это, В основном, когда я отправлял свою форму, создавался пост-запрос, поэтому я думал, что если пользователь правильно заполнил все необходимые данные в форме, то он сразу перейдет к методу 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_ЗДЕСЬ
Я думаю, что это не самый эффективный способ, но он сработал для меня, и если есть другой хороший способ, не стесняйтесь комментировать :)