2

几天来,我一直一头扎进砖墙上,是时候向比我更聪明、更有经验的人寻求建议了。

背景:作为我的网络应用程序的一部分,我正在构建一个测验应用程序,用户可以在其中回答由多项选择题组成的测验。这些问题都是用户生成的,所以我同时遇到了几个有趣的问题:

a)我必须动态构建测验问题表单(radioselect 小部件)。由于答案选项和问题文本都是用户生成的(模型“问题”和“答案”),我必须在视图中运行查询,然后将变量传递给表单的 init。这样我就可以填充选项并用问题文本覆盖标签:

来自forms.py:

#it's not very clean, there's a lot of legacy code in there...
class AnsweredQuestionForm(forms.ModelForm):
    class Meta:
        model = AnsweredQuestion
        widget = {
            'id': forms.TextInput,  # needed for formset that I was using
        }

    question_field = forms.ModelChoiceField(
        empty_label='Gee, this is tough. Can you show me some hints?',
        widget=forms.RadioSelect,
        queryset=Question.objects.all(),
        required=True,
        help_text='',
        error_messages={'required': 'Please pick an answer'},
    )

    def __init__(self, *args, **kwargs):  # I'm using django crispy-forms
        self.helper = FormHelper()
        self.helper.form_method = 'POST'
        self.helper.form_id = ''
        self.helper.form_class = ''
        self.helper.form_action = ''
        self.helper.form_tag = False
        self.helper.help_text_inline = True
        self.helper.render_unmentioned_fields = False
        self.helper.form_error_title = 'Form Errors'
        self.helper.layout = Layout(
            Field('question_field'),
            Field('id', css_class='hidden'),
        )
        self.question = kwargs.pop('question', None)
        super(AnsweredQuestionForm, self).__init__(*args, **kwargs)
        self.fields['question_field'].label = self.question.question_text
        self.fields['question_field'].queryset = self.question.answers.all()

b)这意味着测验问题形式是模型形式(我有一个名为“AnsweredQuestions”的模型,它保存给定答案的实例。还有一个用于测验的模型“TakenQuiz”)。我在用户开始测验时创建了 TakenQuiz 的实例,并在她回答测验问题并保存表单时创建了 AnsweredQuestion 的实例。

来自模型.py

class AnsweredQuestion(models.Model):
    question = models.ForeignKey(Question, null=True, blank=True)
    given_answer = models.ForeignKey(Answer, null=True, blank=True)
    taken_quiz = models.ForeignKey(TakenQuiz, related_name="answered_questions", null=True, blank=True)
    date = models.DateTimeField(editable=False)
    correct = models.BooleanField(default=False)

    class Meta:
        verbose_name = 'answered question'
        verbose_name_plural = 'answered questions'

    def save(self, *args, **kwargs):
        """ On save, update timestamp."""
        if not self.id:
            self.date = datetime.datetime.now()
        super(AnsweredQuestion, self).save(*args, **kwargs)

    def __unicode__(self):
        return unicode(self.given_answer)

从views.py(测试视图):

def take_quiz(request, category_slug, course_slug, module_slug, quiz_number):
    user = request.user
    category = Category.objects.get(slug=category_slug)
    course = Course.objects.get(category=category, slug=course_slug)
    module = Module.objects.get(course=course, slug=module_slug)
    quiz = module.quizzes.get(number=quiz_number)
    quiz_questions = Question.objects.filter(quiz=quiz)
    ...
    else:
        taken_quiz = TakenQuiz()
        aq_form = AnsweredQuestionForm(question=question)

c) 一个测验可以由可变数量的测验问题组成,我只设置了一个最大限制。所以几乎一切都是动态的:(

所以这是我的具体问题:

  1. 如果我使用表单向导,如何访问 URL 参数并将它们用于我的查询?(顺便说一句,我讨厌基于类的通用视图)我试图使问题的数量动态化,但还没有弄清楚如何将变量 (len(quiz_questions) 传递给向导...我的网址如下所示,不幸的是,我需要将所有这些都传递给模板上下文或表单的 init:

    来自 urls.py:

    url(r'^(?P<category_slug>[-\w]+)/(?P<course_slug>[-\w]+)/(?P<module_slug>[-\w]+)/(?P<quiz_number>\d+)/$', quiz_wizard, name='quiz_wizard'),
    quiz_wizard = QuizWizard.as_view(named_quiz_forms)
    named_quiz_forms = [('quiz_question_%d' % i, AnsweredQuestionForm) for i in xrange(0, len(quiz_questions))]
    
  2. 我是否应该费心尝试弯曲表单向导来做我需要的事情?我花了很多时间在谷歌研究和源代码上,我找到了一些问题的潜在解决方案,但不是全部。尤其是不能同时为所有人...

    我可能必须至少覆盖所有这些:

    class QuizWizard(NamedUrlSessionWizardView):
    
        def get_form(self, step=None, data=None, files=None):
            form = super(QuizWizard, self).get_form(step, data, files)
            ...
            return form
    
        def get_form_kwargs(self, step):
            return {}
    
        def get_form_instance(self, step):
            return self.instance_dict.get(step, None)
    
  3. 最后:如果我不能使用表单向导,我应该如何处理测验有什么建议吗?使用 formwizard 对我来说似乎更干净,而不是只为每个测验问题使用视图。该向导的最大优点是在整个测验完成和验证之前,我不必将表单数据保存在某个地方,并且该向导会为我跟踪步骤数和当前步骤。我是一个新手,从头开始编写这种高级的东西并不是很擅长。

非常感谢您的帮助,任何建议或帮助都非常感谢!!

4

0 回答 0