Thursday, October 19, 2017

Setting choices by foreign keys related model's field

Hello all,


I want to set the choices according to a foreign keys parent model's field's value. I.e. "QuestionAnswer" models foreign key "question" is set to model "Question" and that model contains a field "question_type". If the "question_type" value is 1 then set the choices as a, b, c, d, e or if the value is 2, set the choices as f, g, h, i, j. Forms are built as formset but that shouldn't affect how it is done?


First of all do I set the choices as a function and where do I set it? Forms.py, models.py or views.py?

If in the forms.py do I do it with the __init__ method?

How do I get the correct question and the correct choices together?


If you need more info, please ask.


Django version is 1.11.5 and python version is 3.6.0



forms.py

class AnswerForm(forms.ModelForm):

    class Meta: 

        model = QuestionAnswer

        fields = ['question', 'answer_text', 'questionnaire_key']

        exclude = []

        widgets = {

            'question': HiddenInput,

            'answer_text': RadioSelect(choices=CHOICES,

                                                 attrs={'required': 'True'}),

            'questionnaire_key': HiddenInput

            }



models.py

class Question(models.Model):

    questionnaire = models.ForeignKey(Questionnaire)

    question_text = models.CharField(max_length=200)

    question_type = models.CharField(max_length=2)

    def __str__(self):

        return self.question_text


class QuestionAnswer(models.Model):

    questionnaire_key = models.ForeignKey(Questionnaire, null=False, blank=False)

    question = models.ForeignKey(Question, null=False, blank=False)

    answer_text = models.CharField(max_length=1, null=False, default=None)

    def __str__(self):

        return self.answer_text


In the views I set the initial question data for the formset. And I zip the questions and the formset to be able to render them in table, with question's text on the left, and the answer choices on the right.

views.py

def answerpage(request, questionnaire_pk):

    AnswerFormSet = formset_factory(AnswerForm, extra=0)

    questions = Question.objects.filter(questionnaire=questionnaire_pk)

    qname = Questionnaire.objects.get(id=questionnaire_pk)

 

    if request.method == 'POST':

        answer_formset = AnswerFormSet(request.POST)

        if answer_formset.is_valid():

            for answer_form in answer_formset:

                if answer_form.is_valid():

                    instance = answer_form.save(commit=False)

                    instance.answer_text = answer_form.cleaned_data.get('answer_text')

                    instance.question = answer_form.cleaned_data.get('question')

                    instance.questionnaire = answer_form.cleaned_data.get('questionnaire_key')

                    instance.save()

            return redirect('main:calcs')

        else:

            return redirect('main:home')

    else:

        quest_id = request.session.get('questionnaire_key', 0)

        question_data = [{'question': question,

                          'questionnaire_key': quest_id} for question in questions]

 

        answer_formset = AnswerFormSet(initial=question_data)

 

    combined = zip(questions, answer_formset)

    context = {

        'combined': combined,

        'questions': questions,

        'answer_formset': answer_formset,

        'qname': qname,

    }

    return render(request, 'main/questionnaire_details2.html', context)

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscribe@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/5cdb2391-28d0-4df4-96d9-3bd3b4b7c3f2%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

No comments:

Post a Comment