Majed Saaeddin
Majed Saaeddin

Reputation: 81

Django: How can I show up the name of the choices instead of the integers?

I have had several problems while making this website and this is the newest one. I have created these choices fields, however, only the numbers are showing up in the first one, where in the second one and because the question_type is linked to the Question table, the questions that I add into the database are showing up instead of the quesiton type, where there are only two questions' types that are supposed to show up. And depending on the choice made by the user, a new page that is only for reading will show up with the questions that belong to this specific topic with the specific type of questions.

This is the models.py

    from django.db import models
    from home.choices import *

    # Create your models here.

    class Topic(models.Model):
        topic_name = models.IntegerField(
                        choices = question_topic_name_choices, default = 1)
        def __str__(self):
            return '%s' % self.topic_name

    class Image (models.Model):
        image_file = models.ImageField()

        def __str__(self):
            return '%s' % self.image_file

    class Question(models.Model):
        questions_type = models. IntegerField(
                        choices = questions_type_choices, default = 1)
        question_topic = models.ForeignKey(    'Topic',
                                        on_delete=models.CASCADE,
                                        blank=True,
                                        null=True)
        question_description = models.TextField()
        question_answer = models.ForeignKey(    'Answer',
                                        on_delete=models.CASCADE,
                                        blank=True,
                                        null=True)
        question_image = models.ForeignKey(    'Image',
                                        on_delete=models.CASCADE,
                                        blank=True,
                                        null=True)

        def __str__(self):
            return '%s' % self.question_type

    class Answer(models.Model):
        answer_description = models.TextField()
        answer_image = models.ForeignKey(    'Image',
                                        on_delete=models.CASCADE,
                                        blank=True,
                                        null=True)

        def __str__(self):
            return '%s' % self.answer_description

This is the forms.py

    from django import forms
    from betterforms.multiform import MultiModelForm
    from .models import Topic, Image, Question, Answer
    from .choices import questions_type_choices, question_topic_name_choices

    class TopicForm(forms.ModelForm):
        topic_name      =   forms.ModelChoiceField(
                        queryset = Topic.objects.all(),
                        widget = forms.Select(
                        attrs = {'class': 'home-select-one'}
                        ))

        class Meta:
            model = Topic
            fields = ['topic_name',]
            def __str__(self):
                return self.fields


    class QuestionForm(forms.ModelForm):
        questions_type =   forms.ModelChoiceField(
                        queryset = Question.objects.all(),
                        widget = forms.Select(
                        attrs = {'class': 'home-select-two'},
                        ))

        class Meta:
            model = Question
            fields = ['questions_type',]
            def __str__(self):
                return self.fields


    class QuizMultiForm(MultiModelForm):
        form_classes    =   {
                    'topics':TopicForm,
                    'questions':QuestionForm
        }
        def save(self, commit=True):
            objects = super(QuizMultiForm, self).save(commit=False)

            if commit:
                topic_name = objects['topic_name']
                topic_name.save()
                questions_type = objects['question_type']
                questions_type.topic_name = topic_name
                questions_type.save()
            return objects

This is the choices.py

    question_topic_name_choices = (
        (1, ("Topic #1: Measurements and Uncertainties")),
        (2, ("Topic #2: Mechanics")),
        (3, ("Topic #3: Thermal Physics")),
        (4, ("Topic #4: Waves")),
        (5, ("Topic #5: Electricity and Magnetism")),
        (6, ("Topic #6: Circular Motion and Gravitation")),
        (7, ("Topic #7: Atomic, Nuclear and Particle Physics")),
        (8, ("Topic #8: Energy Production")),
        (9, ("Topic #9: Wave Phenomena (HL Only)")),
        (10, ("Topic #10: Fields (HL Only)")),
        (11, ("Topic #11: Electromagnetic Induction (HL Only)")),
        (12, ("Topic #12: Quantum and Nuclear Physics (HL Only)")),
        (13, ("Option A: Relativity")),
        (14, ("Option B: Engineering Physics")),
        (15, ("Option C: Imaging")),
        (16, ("Option D: Astrophysics"))
            )

    questions_type_choices = (
        (1, "Multiple Choice Questions"),
        (2, "Problem Solving Questions"))

This is the views.py

    from django.shortcuts import render, render_to_response
    from django.views.generic import CreateView
    from home.models import Topic, Image, Question, Answer
    from home.forms import QuizMultiForm



    def QuizView(request):
        if request.method == "POST":
            form = QuizMultiForm(request.POST)
            if form.is_valid():
                pass
        else:
            form = QuizMultiForm()
        return render(request, "index.html", {'form': form})

Thank you!

Upvotes: 1

Views: 1432

Answers (1)

Shakil
Shakil

Reputation: 4630

Problem is you are passing queryset as formChoiceField which is fine but will populate as a DB level field value. In your case those are integer values. One option is You can pass your tuple choices as formChoices, django will handle everying by itself. In your form.py

 class TopicForm(forms.ModelForm):
        topic_name      =   forms.ChoiceField(choices=question_topic_name_choices)
        class Meta:
            model = Topic
            fields = ['topic_name',]



    class QuestionForm(forms.ModelForm):
        questions_type =  forms.ChoiceField(choices= questions_type_choices)

        class Meta:
            model = Question
            fields = ['questions_type',]

Or you can change your DB choice fields to char from Integer field and store human readable choices name.

Upvotes: 1

Related Questions