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
Post a Comment