我几天以来一直先对砖墙冲锋,现在是时候问一些比我更聪明,经验更丰富的人了。
上下文:作为我的网络应用程序的一部分,我正在构建一个测验应用程序,用户可以在其中回答由多项选择问题组成的测验。这些问题都是用户生成的,所以我同时遇到了一些有趣的问题:
a)我必须动态地构建测验问题表单(radioselect widget)。由于答案选项和问题文本都是用户生成的(模型'问题'和'答案'),我必须在视图中运行查询,然后将变量传递给我的表单的init。这样我就可以填充选项并用问题文本覆盖标签:
来自forms.py: 的
b)这意味着测验问题表格是模型形式(我有一个名为'AnsweredQuestions'的模型,可以保存给定答案的实例。还有一个模型'TakenQuiz'用于测验)。当用户开始测验时我创建了TakenQuiz的实例,当她回答测验问题并且表单被保存时,我创建了AnsweredQuestion。 #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()
: c)测验可以包含可变数量的测验问题,我只设置了最大限制。所以几乎所有东西都是动态的:( 所以这是我的具体问题: 如果我使用的是表格向导,如何访问网址参数并将其用于我的查询? (顺便说一下,我讨厌基于类的通用视图)我试着让问题的数量变得动态,但还没弄明白我怎样才能将变量(len(quiz_questions))传递给向导...我的网址看起来如下,不幸的是我需要将它全部传递给模板上下文或表单'init: : 我是否应该费心去尝试弯曲formwizard来做我需要的事情?我花了很多时间在谷歌研究和源代码上,我发现了一些问题的潜在解决方案,但并非所有问题。特别是不能同时为所有人...... 我可能不得不覆盖至少所有这些: 最后:如果我不能使用formwizard,我建议如何处理测验?使用formwizard对我来说似乎更清晰,而不仅仅是使用每个测验问题的视图。该向导的巨大优势在于,我不需要在某个地方保存表单数据,直到整个测验完成并经过验证,并且向导会跟踪步骤数和当前步骤。我是一个新手,从头开始写这种先进的东西并不是那么好。 非常感谢您的帮助,我们非常感谢任何建议或帮助!
来自views.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)
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)
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))]
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)