Home > OS >  How do I iterate inside a queryset in django template
How do I iterate inside a queryset in django template

Time:03-17

My django view returns a dictionary people with values for all keys in list format. The code for the view is:

class ProjectDetail(View):
    def get(self, request, pk, *args, **kwargs):
        project = Project.objects.get(pk=pk)
        roles = Role.objects.filter(project=pk)
        people = {}
        for role in roles:
            try:
                people[role]  = Person.objects.filter(role=role.pk)
            except KeyError:
                people[role] = [Person.objects.filter(role=role.pk)]

        context = {
            'project': project,
            'people': people
        }

        return render(request, 'project_management/project_detail.html', context)

My Models

class Project(models.Model):
    title = models.CharField(max_length=2000)
    introduction = models.TextField(blank=True)

class Role(models.Model):
    role_name =  models.CharField(max_length=30)
    project = models.ForeignKey(Status, on_delete=models.CASCADE)

class Person(models.Model):
    name = models.CharField(max_length=30, blank=True, null=True)
    role = models.ForeignKey(Role, on_delete=models.CASCADE)

In order to iterate through the dictionary I used:

{% for designation, persons in people.items %}
<h5> {{ designation.role_name }} </h5>
<ul>
    {% for person in persons %} <!-- My Problem lies here, this loop is not iterating, it's running only once-->
        <li> {{person}} </li>
    {% endfor %}
</ul>
{% endfor %}

The result I got is:

enter image description here

I want the items inside queryset listed out separately, instead of being shown inside square brackets. How can I make that happen?

CodePudding user response:

You don't need to do all this work. You can pass only the project. For example with:

from django.shortcuts import get_object_or_404

class ProjectDetail(View):
    def get(self, request, pk, *args, **kwargs):
        project = get_object_or_404(Project, pk=pk)
        return render(request, 'project_management/project_detail.html', {'project': project})

or even simpler with a DetailView [Django-doc]:

class ProjectDetail(DetailView):
    queryset = Status.objects.prefetch_related(
        'role_set', 'role_set__person_set'
    )
    template_name = 'project_management/project_detail.html'
    context_object_name = 'project'

Then in the template you can render this with:

{% for role in project.role_set.all %}
<h5> {{ role.role_name }} </h5>
<ul>
    {% for person in role.person_set.all %}
        <li> {{ person.name }} </li>
    {% endfor %}
</ul>
{% endfor %}
  • Related