Home > Net >  How to iterate over 2 variables in Django template
How to iterate over 2 variables in Django template

Time:01-11

I have an app for some quiz with questions and choices. So I'm trying to render all this stuff to Django templates. In my views.py it looks like this

def choice(request):
    question_list = get_list_or_404(Question)
    page = get_object_or_404(Page, name='about')
    letters = ["A", "B", "C", "D", "E"]
    return render(request,
                  'qview/choice.html',
                  {
                    'question_list': question_list,
                    'page': page,
                    'letters': letters,
                   }
                  )

I have a list of questions and list with letters. All of that I'm sending as context to my template.

  {% if question_list %}
    <ul>
    {% for question in question_list %}
      <li><a href="#">{{question.question}}</a></li>
        <ul>
          {% for choice in question.choice_set.all %}
          <li>{{ choice.text }}</li>
          {% endfor %}
        </ul>
    {% endfor %}
    </ul>
  {% else %}
    <p>No questions available</p>
  {% endif %} 

So here I'm going through all of questions and all of choices connected to this question. But I can't get how I can also go through letters list? I was thinking about zip it all. But in view I have only questions not choices, so I can't zip to it.

So what else is possible here?

CodePudding user response:

So it'll be like A choice01, B choice 02 and so on

This can be solved by HTML. Use an ordered list.

        <ol type="A">
          {% for choice in question.choice_set.all %}
          <li>{{ choice.text }}</li>
          {% endfor %}
        </ol>

CodePudding user response:

Django templates make some pretty handy loop builtins available. The one you want to use in this case is forloop.counter0. Specifically, use it as an index for your letters list.

{% if question_list %}
<ul>
  {% for question in question_list %}
    <li><a href="#">{{question.question}}</a></li>
      <ul>
        {% for choice in question.choice_set.all %}
        <li>{{ letters[forloop.counter0] }}: {{ choice.text }}</li>
        {% endfor %}
      </ul>
  {% endfor %}
</ul>
{% else %}
  <p>No questions available</p>
{% endif %} 

Suggestion, it might be a better idea to "zip" them together and pass the zipped output to the template (you were already thinking about this -- good!) Templates should know as little as possible about your business logic and make as few assumptions as possible about your data structures.

CodePudding user response:

cycle tag is perfect for such manner. It goes in for loop and takes first argument for first iteration, second for second and so on... If they are not enough, then it starts from the begininng.

    {% for choice in question.choice_set.all %}
        <li>{% cycle 'A' 'B' 'C' 'D' 'E' 'F' %}: {{ choice.text }}</li>
    {% endfor %}
  • Related