【问题标题】:Select a valid choice. 6da87c51321849bdb7da80990fdab19b is not one of the available choices选择一个有效的选项。 6da87c51321849bdb7da80990fdab19b 不是可用的选择之一
【发布时间】:2021-11-07 23:20:45
【问题描述】:

我在表单中使用 answers 字段仅用于测试目的,以查看它是否在提交表单时返回 post 请求中值的选定 id,而且我正在使用 get_form_kwargs() 将选择动态传递给 from 视图,在前端它向我显示了正确的选择,但是当一个选择并提交时,它向我显示了这个问题的主题中提到的错误

另外仅供参考,我没有在模型中包含“answerss”字段,因为我只是想测试它是否在 POST 请求中返回正确的 id。

这是我从 views.py 到 forms.py 的动态传递列表,以填充在 init 中创建的“answerss”字段的选择。每次提交后,此列表都会不断变化

另外仅供参考,这是一个测验应用程序,因此每次提交后我将其重定向到呈现下一个问题并在选择字段中呈现不同选项的同一页面

[('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)

这是我的观点.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)

我的表单.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',)

此片段是在提交表单之前(请忽略文本答案字段)

这个片段是在提交之后

【问题讨论】:

    标签: python django django-models django-forms django-class-based-views


    【解决方案1】:

    解决了,所以基本上每当我提交表单时,都会重新创建一个发布请求,所以我基本上认为如果用户在表单中正确填写了所有必需的详细信息,那么它将直接转到 form_valid() 方法但是在转到表单有效方法之前我错了,它会在视图中初始化我的 Start_Game 类的__init__ 方法,然后它会初始化我的get_form_kwargs() 所以在这个get_form_kwargs() 中我编写了代码来生成下一个问题和选项在forms.py中将它发送到我的表单,这样这将直接更新我在表单中的多选选项和下一个问题选项,并且在更新多选选项之后,它会将我之前选择的选项值与新更新的值进行比较,所以显然这会产生上述错误由于所选选项在更新的选项中不可用,所以基本上我在下面的代码中写下了一个 if 条件来检查请求是发布还是获取

    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_HERE

    我认为这不是一种有效的方法,但它对我有用,如果有其他好的方法,请随时发表评论:)

    【讨论】:

      猜你喜欢
      • 2019-01-14
      • 2021-01-25
      • 1970-01-01
      • 2018-06-11
      • 2021-04-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-30
      相关资源
      最近更新 更多