【问题标题】:Initial data as queryset for formset foreign key field初始数据作为表单集外键字段的查询集
【发布时间】:2016-05-02 17:19:44
【问题描述】:

我正在处理英语语言测试申请。每个问题都有问题和 4 个可能的答案。只有一个答案是正确的。 以下是模型:

class EnglishTestQuestion(AbstractDatetimeModel):
    text = models.CharField(max_length=255, verbose_name=u"Question text")

class EnglishTestAnswerVariants(models.Model):
    question = models.ForeignKey(EnglishTestQuestion, verbose_name=_(u"question"), related_name='Variants')
    text = models.CharField(max_length=255, verbose_name=u"Text")
    is_correct = models.BooleanField(_(u"Is correct"), default=False)

class EnglishTestAnswer(AbstractDatetimeModel):
    user = models.ForeignKey(User, blank=True, null=True, verbose_name=u"user")
    question = models.ForeignKey(EnglishTestQuestion, blank=False, verbose_name=u"question")
    answer = models.ForeignKey(EnglishTestAnswerVariants, verbose_name=u"answer")

这是视图。我为每个问题创建一个表格并传递初始数据。问题字段获取初始数据,但答案字段忽略它并显示所有答案,:

def english_test(request):
    questions = EnglishTestQuestion.objects.all()
    QuestionFormSet = formset_factory(form=EnglishTestForm, max_num=questions.count())
    formset = QuestionFormSet(initial=[{
                                           'question': x,
                                           'answer': EnglishTestAnswerVariants.objects.filter(question=x)
                                       } for x in questions])

    return render(request, 'testing/english_test.html', {"questions": questions, "question_formset": formset})

但它应该只为每个问题显示通过外键连接的答案。

这是表格:

class EnglishTestForm(forms.ModelForm):

    class Meta:
        model = EnglishTestAnswer
        fields = '__all__'
        widgets = {
            'answer': forms.RadioSelect()
        }

如何仅将那些与 FK 问题相关的答案传递到答案字段中?

【问题讨论】:

    标签: django django-forms formset


    【解决方案1】:

    initial 参数传递字段的初始值,而不是这些字段的可用选项。在您的情况下,您可以动态调整 EnglishTestForm.answer 字段的查询集:

    class EnglishTestForm(forms.ModelForm):
        class Meta:
            model = EnglishTestAnswer
            fields = '__all__'
            widgets = {
                'answer': forms.RadioSelect()
            }
    
        def __init__(self, *args, **kwargs):
            super(EnglishTestForm, self).__init__(*args, **kwargs)
            question = self.initial.get('question')
            if question:
                self.fields['answer'].queryset = question.Variants.all()
    

    P.S.:实际上您有一个安全问题:恶意用户可能会伪造您的表单集值,例如,制作具有相同问题 ID 和所有可能答案 ID 的四个表单。当您盲目地保存这些表格时,根据您的计算方法,可能会导致测试的假阳性结果。只是为了警告你。

    【讨论】:

    • 谢谢!有用。关于安全问题,您有什么建议?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-07
    • 2013-11-20
    • 2011-07-13
    • 1970-01-01
    • 2012-07-14
    • 2011-05-08
    相关资源
    最近更新 更多