Home > Software design >  Using jinja variable as dictionary key
Using jinja variable as dictionary key

Time:11-17

I'm making a django app to do with tests/exams. Two of the models in this app are the "Question" and "Answer" model which have a one-to-many relationship. On the page, each question will be listed with all of its possible answers below it which the user can choose from.

In my views.py file, after getting the list of question objects, the best way I thought of for storing the answers was in a dictionary like so:

answers = {}
for question in questions:
    answers[question.id] = Answer.objects.filter(question=question.id)

Then, for the template, I thought I would be able to do something like:

{% for question in questions %}
<h2>{{ question.title }}</h2>
<ul>
    {% for answer in answers.{{ question.id }} %}
    <li>{{ answer.title }}</li>
    {% endfor %}
</ul>
{% endfor %}

The error arises in this line - {% for answer in answers.{{ question.id }} %}.

I've tried rewriting this line as per this post which suggested things like:

{% for answer in answers[question.id] %}

and

{% for answer in answers.get(question.id) %}

but none of these worked.

Please let me know if there is a syntax in Jinja that allows this or else if there is a better way of me passing the answers variable in my views.py file altogether.

CodePudding user response:

Jonas Grumann gave me the answer.

I was able to generate a list of each question's answers with the _set.all() function which I just learned was a thing.

Cheers Jonas!

CodePudding user response:

You can use the _set.all() convention to get all the related items:

{% for answer in question.answer_set.all %}
    {{ answer.id }}
{% endfor %}

This works, but if you want to have a more readable version you can define a related_name in your model:

class Question(models.Model):
    prompt = (models.CharField)

class Answer(models.Model):
    question = models.ForeignKey(Question, related_name="answers")
    correct = models.BooleanField()
    prompt = models.CharField()

And then you can use that related name instead of the _set:

{% for answer in question.answers.all %}
    {{ answer.id }}
{% endfor %}

which makes it a bit more readable.

  • Related