Search code examples
djangopaginationdjango-pagination

Django pagination on model with foreign key


Post and comment models

class Post(models.Model):
    title = models.CharField(max_length=120)
    content = models.TextField()

class Comment(models.Model):
    post = models.ForeignKey(Post, on_delete=models.CASCADE)
    content = models.TextField()

Class view of post detail

class PostDetailView(DetailView):
    model = Post
    context_object_name = 'post'
    template_name = 'posts/detail.html'

    def get_queryset(self, *args, **kwargs):
        request = self.request
        pk = self.kwargs.get('pk')
        queryset = Post.objects.filter(pk=pk)
        return queryset

In the template I do something like this

{% for comment in post.comment_set.all %}
{% comment.content %}
{% endfor %}

In this approach, all the comments are shown in the post detail page. However, I want to paginate the comments of a post so that I can do pagination on comments and not show the whole list of comments.

How can I do this?


Solution

  • Paginators are provided in django be default. You can paginate comments by overriding your get_context_data method like this.

    def get_context_data(self, **kwargs):
        context = super(PostDetailView, self).get_context_data(**kwargs)
        comments = context['post'].comment_set.all()
        paginator = Paginator(comments, per_page=50)
        page_number = 1  # get it from query sting or whatever the way you want
        page = paginator.page(page_number)
        context['comments'] = page
        return context
    

    you can render commnets in template by looping over them like this.

    {% for comment in comments %}
        {# render comment here. #}
    {% endfor %} 
    

    for more information about rendering pagination controls, please consult official docs about paginators here.