Search code examples
djangodjango-templatesmany-to-manyeager-loading

Django rendering issue eager loaded data


Those are many models

class FacultyMember(models.Model):
    # some attributes

    @staticmethod
    def get_profile_information(id, first_name, last_name):
        return get_object_or_404(FacultyMember.objects.filter(
            pk=id,
            first_name=first_name,
            last_name=last_name
        ).prefetch_related('project_set').prefetch_related('publication_set'))


class Publication(models.Model):
    # some attributes
    author = models.ManyToManyField(FacultyMember, blank=True)

class Project(models.Model):
    # some attributes
    researchers = models.ManyToManyField(FacultyMember, blank=True)

And this is my view

def profile(request, id, first_name, last_name):
    return render(request, 'profile.html', {
        'faculty': FacultyMember.get_profile_information(
            id, first_name, last_name
         )
    })

I try render those data in template as following code

{% for i in faculty.project_set %}
    <li>
        {{ i.title }}
    </li>
{% endfor %}

Than I get following error message

'ManyRelatedManager' object is not iterable

-> {% for i in faculty.project_set %}

How to render eager loaded data in django template


Solution

  • You are getting the error because faculty.project_set is a manager, not a queryset.

    Just as you have to do Faculty.objects.all() or Faculty.objects.filter(...) instead of simply Faculty.objects, you need to call a method on the project set, like faculty.objects.all()

    In the Django template language, you don't use parentheses to call the method, so you would do:

    {% for project in faculty.project_set.all %}
    

    This is unrelated to whether you use prefetch_related or not.