python - django complex formset issue -


i have 3 primary models. questionnaire model or question set contains set of questions. user response stored in answer.

now have generate formset store answer of questions in questionnaire set. how can in django. far have manged displaying single question @ once given questionnaire , store response. problem based on questiontype use 2 different modelform (multiplechoiceanswerform,descriptivechoiceanswerform) , validate them based on formtype. how can use in formset.

i beginner in django , appreciated.

my code:

#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 , 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 provide input!"      questions = questionnaire.questions.all()     allquestions = questions.count()     tot_q = 0     formtype = ""     answered = 0     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 "+course.fullname         data_dict['completeness'] = (answered/allquestions)*100         data_dict['error']=errortext     else:         return httpresponse(printerror("thanks! you've answered questions!<br><a href=\"/feedback/teachers/"+course.course_code+"\">continue teaching feedback.</a>"))     req_context = requestcontext(request)     return render_to_response('view.html', data_dict, req_context) 

simple answer: use on single answerform , let manage kind of field , widget should use, ie:

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') 

as side note, can pass model's attributes values model's constructor:

    answer = answer(         question=question.objects.get(id=request.session['question']),         person=student,         course=course,         questionnaire=questionnaire,         # user.objects.get(id=request.user.pk) return request.user         # it's useless - use request.user         tathya_user=request.user         ) 

Comments

Popular posts from this blog

node.js - Bad Request - node js ajax post -

Why does Ruby on Rails generate add a blank line to the end of a file? -

keyboard - Smiles and long press feature in Android -