Search code examples
djangodjango-viewsdjango-templatesdjango-urlsdjango-template-filters

Iterate context variables in Django templates based on user's attributes


Is it possible to iterate over a list of three context variables shown below so that depending on the user's attribute (in this instance grade, Grade 10, Grade 11, Grade 12). If current user's grade attribute is Grade 10 then they only get: context['grade10'] from below.

Current view:

class SumListView(ListView):
    model = Summaries
    template_name = 'exam/summary.html'

def get_context_data(self, **kwargs):
    context = super().get_context_data(**kwargs)
    context['grade10'] = Summary.objects.filter(grade='Grade 10')
    context['grade11'] = Summary.objects.filter(grade='Grade 11')
    context['grade12'] = Summary.objects.filter(grade='Grade 12')
    return context'''

Current html template block:

           {% block content %}
  
               {% for summary in grade10 %}
                   <div class="container>
                      {{ summary.content }}
                   </div>
               {% endfor %}
 
          {% endblock content %}
 

I tried this but it breaks the code since for loops and iterations are mixing:

{% block content %}
     {% if grade10 %}
       {% for summary in grade10 %}
          <div class="container>
             {{ summary.content }}
          </div>
         {% endfor %}
     {% elif grade11 %}
         {% for summary in grade10 %}
          <div class="container>
             {{ summary.content }}
          </div>
          {% endfor %}
     {% else grade12 %}
         {% for summary in grade10 %}
          <div class="container>
             {{ summary.content }}
          </div>
         {% endfor %}
     {% enif %}
{% endblock content %}

What is the best way to go about this?

I know I can write different urls for each context which in turn renders a different template but that does not seem efficient and I hope there is a better way to do that. Any help highly appreciated, including documentation pointers.


Solution

  • You can perform this logic in your view, you can use a single context variable but change it's contents based on your logic

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        user_grade = self.request.user.get_grade() # Replace with how you access the user's grade
        context['grades'] = Summary.objects.filter(grade=user_grade)
        return context
    

    Then loop over grades in your template