2013-04-18 84 views
0

我有3個主要模型。問卷模型或問題集包含一組問題。所有的用戶響應都存儲在答案中。django複雜的formset問題

現在我必須生成一個formset,它將所有問題的答案存儲在問卷集中。我怎麼能在Django中做到這一點。到目前爲止,我已經通過從給定問卷中一次性顯示單個問題並存儲迴應來做到這一點。我的問題是基於questiontype使用兩種不同的模型(MultipleChoiceAnswerForm,DescriptiveChoiceAnswerForm)並基於formtype驗證它們。我如何在formset中使用它。

我是初學者在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) 

回答

1

答案很簡單:只在單AnswerForm使用,讓它管理何種領域和Widget它應該使用,即:

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 
     ) 
+0

謝謝,我的問題幾乎解決了。陷入一個不同的點,但更好地堅持DIY方法。 – biztiger