Reputation: 99
I use a detail view for my posts in my blog and each post has comments so I want to paginate them but I don't konw how to do it because I did a request for the post model. I know how to do it in function view but not in detail view...
##view :
class PostDetailView(DetailView):
model = Post
def get_context_data(self, **kwargs):
context = super(PostDetailView, self).get_context_data(**kwargs)
context['comments'] = Comment.objects.filter(post_id=self.object.id).all()
context['comments_number'] = Comment.objects.filter(post_id=self.object.id).count()
context['form'] = CommentForm()
return context
def post(self, request, pk):
form = CommentForm(request.POST)
if form.is_valid():
comment = form.save(commit=False)
comment.post = Post.objects.get(id=pk)
comment.user = request.user
comment.save()
post = Post.objects.get(pk=pk)
post.comments_nmb+=1
post.save()
return HttpResponseRedirect(request.META.get('HTTP_REFERER'))
##template:
{% extends "blog/base.html" %}
{% block content %}
<article class="media content-section">
<img class="rounded-circle article-img" src="{{ object.author.profile.image.url }}">
<div class="media-body">
<div class="article-metadata">
<a class="mr-2" href="{% url 'user-posts' object.author.username %}">{{ object.author }}</a>
<small class="text-muted">{{ object.date_posted|date:"F d, Y" }}</small>
{% if object.author == user %}
<div>
<a class="btn btn-secondary btn-sm mt-1 mb-1" href="{% url 'post-update' object.id %}">Update</a>
<a class="btn btn-danger btn-sm mt-1 mb-1" href="{% url 'post-delete' object.id %}">Delete</a>
</div>
{% endif %}
</div>
<h2 class="article-title">{{ object.title }}</h2>
<p class="article-content">{{ object.content }}</p>
<p>{{comments_number}} Comments</p>
{% for comment in comments %}
<div class="media">
<a class="float-left">
<img class="rounded-circle account-img" src="{{ comment.user.profile.image.url }}">
</a>
<div class="media-body">
<h4 class="media-heading ">{{ comment.user.username }}</h4>
{{comment.text}}
</div>
<p class="float-right"><small>{{ comment.date}}</small></p>
</div>
{% endfor %}
</div>
</article>
{% endblock content %}
How to make pagination for comments in the for loop ?
Upvotes: 2
Views: 607
Reputation: 477607
Almost exactly the same way:
from django.core.paginator import Paginator
class PostDetailView(DetailView):
model = Post
def get_context_data(self, **kwargs):
context = super(PostDetailView, self).get_context_data(**kwargs)
page = self.request.GET.get('page')
comments = Paginator(self.object.comment_set.all(), 25)
context['comments'] = comments.get_page(page)
context['comments_number'] = self.object.comment_set.count()
context['form'] = CommentForm()
return context
# ...
We thus obtain the page
parameter from the self.request.GET
parameters, and we then make a Paginator
and page it accordingly. You probably should also order the comments according to some field. Right now the comments can appear in any order, and thus the next page can contain comments that appeared on the previous page, etc.
The comments
variable is thus a pagination object, and you can render it like you do in a function-based view.
Note that you can use comment_set
(or if you set another related_name
, that name) to access the set of attributes related to the Post
object.
That being said, perhaps this is more a ListView
over the comments, or a FormView
, since you include a Form
to comment.
Upvotes: 2