(ab)使用Django表单向导进行我的出价 - 这甚至可能吗?

时间:2012-05-18 14:36:18

标签: django django-forms django-formwizard

我几天以来一直先对砖墙冲锋,现在是时候问一些比我更聪明,经验更丰富的人了。

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

a)我必须动态地构建测验问题表单(radioselect widget)。由于答案选项和问题文本都是用户生成的(模型'问题'和'答案'),我必须在视图中运行查询,然后将变量传递给我的表单的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。

来自models.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. 如果我使用的是表格向导,如何访问网址参数并将其用于我的查询? (顺便说一下,我讨厌基于类的通用视图)我试着让问题的数量变得动态,但还没弄明白我怎样才能将变量(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. 我是否应该费心去尝试弯曲formwizard来做我需要的事情?我花了很多时间在谷歌研究和源代码上,我发现了一些问题的潜在解决方案,但并非所有问题。特别是不能同时为所有人......

    我可能不得不覆盖至少所有这些:

    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,我建议如何处理测验?使用formwizard对我来说似乎更清晰,而不仅仅是使用每个测验问题的视图。该向导的巨大优势在于,我不需要在某个地方保存表单数据,直到整个测验完成并经过验证,并且向导会跟踪步骤数和当前步骤。我是一个新手,从头开始写这种先进的东西并不是那么好。

  4. 非常感谢您的帮助,我们非常感谢任何建议或帮助!

0 个答案:

没有答案