0

我有 3 个主要模型。问卷模型或问题集包含一组问题。所有用户响应都存储在 answer 中。

现在我必须生成一个表单集,它将存储问卷集中所有问题的答案。我怎么能在 django 中做到这一点。到目前为止,我已经设法通过一次显示给定问卷中的单个问题并存储响应来做到这一点。我的问题是基于 questiontype 使用两种不同的模型形式(MultipleChoiceAnswerForm、DescriptiveChoiceAnswerForm)并根据表单类型验证它们。如何在表单集中使用它。

我是 django 的初学者,感谢任何帮助。

我的代码:

#Models.py

class Question(models.Model):
    statement = models.CharField(max_length=255)
    question_type = models.CharField(max_length=20, choices=get_qtypes())
    remarks = models.CharField(max_length=200, null=True, blank=True)

    def __unicode__(self):
        return '%s'%(self.statement)

class Questionnaire(models.Model):
    title = models.CharField(max_length=255)
    questionaire_type = models.CharField(max_length=20,choices=QUESTIONNAIRETYPE)
    context = models.ForeignKey(QuestionContext)
    questions = models.ManyToManyField(Question)

    timestamp = models.DateTimeField(auto_now=True)
    tathya_user = models.ForeignKey(User)

    def __unicode__(self):
        return '%s'%(self.title)

class Answer(models.Model):
    question = models.ForeignKey(Question)
    person = models.ForeignKey(Person)
    course = models.ForeignKey(Course)
    teacher=models.ForeignKey(Person, null=True, blank=True, default = None)
    questionaire = models.ForeignKey(Questionnaire)
    statement = models.CharField(max_length=255)


    def get_label(self):
        return '%s'%(self.question.statement)
    def get_choices(self):
        return get_questionchoices(self.question.question_type)

class DescriptiveAnswerForm(ModelForm):
    def __init__(self, *args, **kwargs):
        super(DescriptiveAnswerForm, self).__init__(*args, **kwargs)
        if kwargs.has_key('instance'):
            self.fields['statement'].label = kwargs['instance'].get_label()

    statement = forms.CharField(widget=forms.Textarea())
    class Meta:
        model = Answer
        exclude=('question','person','course','teacher','questionaire')

class MultipleChoiceAnswerForm(ModelForm):
    statement = forms.ChoiceField(widget=forms.RadioSelect(choices=EMPTY,attrs={'class': 'allradio',}))

    def __init__(self, *args, **kwargs):
        super(MultipleChoiceAnswerForm, self).__init__(*args, **kwargs)
        if kwargs.has_key('instance'):
            self.fields['statement'].label = kwargs['instance'].get_label()
            self.fields['statement'].choices = kwargs['instance'].get_choices()

    class Meta:
        model = Answer
        exclude=('question','person','course','teacher','questionaire')

###################################################################
#view.py
@login_required
def content_feedback_view_old(request,course_code):
    #do validation and other jobs
    questionnaire = get_questionnaire(some_params_like_coursecode)
    if request.method == 'POST':
        r_answer = Answer()
        r_answer.question = Question.objects.get(id=request.session['question'])
        r_answer.person = student
        r_answer.course = course
        r_answer.questionaire = questionnaire
        r_answer.tathya_user = User.objects.get(id=request.user.pk)
        rformtype = request.POST['formtype']
        if rformtype == 'MCQ':
            rform = MultipleChoiceAnswerForm(request.POST, instance=r_answer)
        else:
            rform = DescriptiveAnswerForm(request.POST, instance=r_answer)
        if rform.is_valid():
            rform.save()
        else:
           #return HttpResponse(printerror("Some problem occurred!"))
           errortext = "You need to provide an input!"

    questions = questionnaire.questions.all()
    allquestions = questions.count()
    tot_q = 0
    formtype = ""
    answered = 0
    for question in questions:
        try:
            answer=Answer.objects.get(question=question,person=student,course=course,questionaire=questionnaire)
            answered += 1
        except:
            answer = Answer()
            answer.question = question
            answer.person = student
            answer.course = course
            answer.questionaire = questionnaire
            answer.tathya_user = User.objects.get(id=request.user.pk)
            request.session['question']=question.id
            tot_q = tot_q + 1;
            if get_questiontype(question.question_type)=='MCQ':
                formtype="MCQ"
                form=MultipleChoiceAnswerForm(instance=answer)
            else:
                formtype="DESC"
                form=DescriptiveAnswerForm(instance=answer)
            break
    if tot_q>0:
        data_dict['FeedbackFormType']=formtype
        data_dict['FeedbackForm']=form
        data_dict['pagetitle']=context.description
        data_dict['coursecode']=course.course_code
        data_dict['feedbacktitle']="Content Feedback for "+course.fullname
        data_dict['Completeness'] = (answered/allquestions)*100
        data_dict['error']=errortext
    else:
        return HttpResponse(printerror("Thanks! You've answered all the questions!<br><a href=\"/feedback/teachers/"+course.course_code+"\">Continue with the teaching feedback.</a>"))
    req_context = RequestContext(request)
    return render_to_response('view.html', data_dict, req_context)
4

1 回答 1

1

简单的答案:仅在单个 AnswerForm 上使用并让它管理它应该使用哪种字段和小部件,即:

class AnswerForm(ModelForm):
    def __init__(self, *args, **kwargs):
        super(AnswerForm, self).__init__(*args, **kwargs)
        instance = self.instance
        if instance.question.question_type == 'MCQ':
             self.fields["statement"] = forms.ChoiceField(
                 choices=instance.get_choices(),
                 widget=forms.RadioSelect(attrs={'class': 'allradio',})
                 )
        else:
             self.fields["statement"] = forms.CharField(
                widget=forms.Textarea()
                )
        self.fields['statement'].label = instance.get_label()

    class Meta:
        model = Answer
        exclude=('question','person','course','teacher','questionaire')

作为旁注,您可以将模型的属性值传递给模型的构造函数:

    answer = Answer(
        question=Question.objects.get(id=request.session['question']),
        person=student,
        course=course,
        questionnaire=questionnaire,
        # User.objects.get(id=request.user.pk) will return request.user
        # so it's just useless - just use request.user
        tathya_user=request.user
        )
于 2013-04-19T11:55:46.657 回答