How to get all children (ForeignKey based) from parent objects in a django template (e.g all comments for a blog post) ?

Published: May 02, 2022

Updated: December 09, 2022

Tags: Django; Python;

DMCA.com Protection Status

Example of how to get all children from parent objects in a django template:

Models.py file

Let's consider the following case: a blog website in which a post can be created and commented as well:

class Blog_Post(models.Model):
        content = models.TextField()
        date_created = models.DateTimeField(default=datetime.now)

class Blog_Post_Comment(models.Model):
        blog_post = models.ForeignKey(Blog_Post, null=True, blank=True, default = None,on_delete=models.DO_NOTHING)
        content = models.TextField()
        date_created = models.DateTimeField(default=datetime.now)

So a single post can have multiple comments.

To display all posts in a django template (called for example blog.html), we can create a simple Django view:

def blog_view(request):
        blog_post_obj_list = Blog_Post.objects.all()
        context = {'blog_post_obj_list':blog_post_obj_list}
        return render(request, "myapp/blog.html", context )

Get all children in a django template

To iterate over all posts and show its content in the django template blog.html, a solution is to do

{% for blog_post_obj in blog_post_obj_list %}

    {{ blog_post_obj.content }}

{% endfor %}

Now to also get all comments for a single post, a solution is to do here (see Many-to-one relationships:

blog_post_obj.blog_post_comment_set.all

(just add the suffix _set.all to the child name: parent_obj.child_name_set.all )

{% for blog_post_obj in blog_post_obj_list %}

    {{ blog_post_obj.content }}

    {% for blog_post_comment_obj in blog_post_obj.blog_post_comment_set.all %}
        {{ blog_post_obj.content }}
    {% endfor %}

{% endfor %}

Get the number of comments:

Note 1: it is possible to get the number of comments:

{{ blog_post_obj.blog_post_comment_set.count }}

Sort comments by

Note 2: Comments can also be sorted by a given column, for example date_created (see dictsort)

{% for blog_post_comment_obj in blog_post_obj.blog_post_comment_set.all|dictsort:"date_created" %}