0

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.

Smurphy
  • 70
  • 6
  • 1
    I'm confused, if they have a relationship shouldn't you be able to do {% for answer in question.answer_set.all %}? Or define a related_name in the Answer model so you can do just question.answers.all – Jonas Grumann Nov 17 '22 at 09:38
  • Mabe this will help? [HERE](https://stackoverflow.com/questions/57821896/access-dictionary-within-dictionary-jinja) – JDODER Nov 17 '22 at 09:42
  • @JonasGrumann. The question.answer_set.all worked, I didn't know this was possible, thanks. – Smurphy Nov 17 '22 at 10:04
  • Glad it worked, I added it as a proper answer with a little more explanation on the related_name, I'd be glad if you could accept it ;) – Jonas Grumann Nov 17 '22 at 10:19

1 Answers1

1

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.

Jonas Grumann
  • 10,438
  • 2
  • 22
  • 40