One to many join using django-tables2

64 Views Asked by At

I'm trying to join two tables together (Question and Choice) and visualize the output with django-tables2. Between Question and Choice exists a one-to-many relationship. My goal is to get this join working while specifying the Questions table as starting point / as a model in the views.py

There are 2 quizzes, each quiz has 2 questions and each question has 2 answers.

models.py

class Quiz(models.Model):
    quiz_identifier = models.IntegerField(primary_key=True)
    quiz_name = models.CharField(max_length=200)


class Question(models.Model):
    question_identifier = models.IntegerField(primary_key=True)
    quiz_identifier = models.ForeignKey(Quiz, db_column='quiz_identifier', on_delete=models.CASCADE)
    question_text = models.CharField(max_length=200)


class Choice(models.Model):
    choice_identifier = models.IntegerField(primary_key=True)
    question_identifier = models.ForeignKey(Question, db_column='question_identifier', on_delete=models.CASCADE)
    choice_text = models.CharField(max_length=200)

tables.py

class QuestionTable(tables.Table):
    quiz_name = tables.Column(accessor='quiz_identifier__quiz_name', verbose_name='Quiz Name')
    choice_text = tables.Column(accessor='choice__choice_text', verbose_name='Choice Text')

    class Meta:
        model = Question
        fields = ("question_identifier", "choice_text", 'quiz_name',)

views.py

class QuestionListView(SingleTableView):
    model = Question
    table_class = QuestionTable
    template_name = 'polls/question.html'

Versions: django==4.2.3 django-tables2==2.5.3

Running this code yields a table output where the choice_text column is always none. The values in the quiz_name are all there. I tried to specify a render function for choice_text, but it was never called.

def render_choice_text(self, value, record):
    LOG.info(f"render function called")
    return "something"

Moreover I expected to get 8 rows (4 questions * 2 choices), but I only got 4.

Manually specifying a queryset with the same accessors as above works perfectly fine and yields 8 rows with all the information from the Choice and Quiz table.

queryset = Question.objects.all().values("question_identifier", "choice__choice_text", "quiz_identifier__quiz_name")
0

There are 0 best solutions below