Django分页依赖于排序
我简化了以下模型:Django分页依赖于排序,django,pagination,Django,Pagination,我简化了以下模型: class Post(models.Model): title = models.CharField(max_length=20) date_created = models.DateTimeField(auto_now=True) class Meta: ordering = ('-date_created',) # note the "reverse" ordering here ,然后是基于generic.DetailView
class Post(models.Model):
title = models.CharField(max_length=20)
date_created = models.DateTimeField(auto_now=True)
class Meta:
ordering = ('-date_created',) # note the "reverse" ordering here
,然后是基于generic.DetailView的自定义详细视图:
最后是以下模板:
{% with object.get_previous_by_date_created as prev %}
{% if prev %}
<a class="nav-link-prev"
href="{% url "blog:post_detail" pk=prev.id %}">Previous</a>
{% endif %}
{% endwith %}
{% with object.get_next_by_date_created as next %}
{% if next %}
<a class="nav-link-next"
href="{% url "blog:post_detail" pk=next.id %}">Next</a>
{% endif %}
{% endwith %}
我的分页是以这种方式实现的,但是由于反向排序,即-date_created字段,它的上一个/下一个标签放错了位置。换句话说,我的模板在下一个应该在哪里输出上一个,反之亦然。如果我删除一个-sign-in-ordering='-date_created',它可以正常工作,但这不是我希望在我的网站上进行的排序
有没有一种简单而惯用的方法来纠正这种错误行为?我缺少什么?添加
ordering = ['-date_created']
或
要发布列表视图我认为您必须使用DetailView和mixin MultipleObjectMixin,如下所示
from django.views.generic.detail import DetailView
from django.views.generic.list import MultipleObjectMixin
from django.core import paginator
class PostDetailView(DetailView, MultipleObjectMixin):
model = Post
paginate_by = 5
def get_context_data(self, **kwargs):
object_list = Post.objects.all().order_by('-date_created')
context = super(PostDetailView, self).get_context_data(object_list=object_list, **kwargs)
post_paginator = paginator.Paginator(object_list, self.paginate_by)
# Catch invalid page numbers
try:
post_page_obj = post_paginator.page(purchases_page)
except (paginator.PageNotAnInteger, paginator.EmptyPage):
post_page_obj = post_paginator.page(1)
context["post_page_obj"] = post_page_obj
return context
现在,您应该能够使用带有post_page_obj变量的分页方法我走了这条路线,并且能够解决这个问题:
class PostDetailView(generic.DetailView):
model = Post
def get_context_data(self, **kwargs):
context = super(PostDetailView, self).get_context_data(**kwargs)
next = Post.objects.filter(pk__lt=self.object.pk).order_by('-pk')[:1]
prev = Post.objects.filter(pk__gt=self.object.pk).order_by('pk')[:1]
if prev:
context['prev'] = prev[0]
if next:
context['next'] = next[0]
return context
现在在template.html中:
{% if prev %}
<a class="nav-link-prev"
href="{% url "post_detail" pk=prev.id %}">Previous
</a>
{% endif %}
{% if next %}
<a class="nav-link-next"
href="{% url "post_detail" pk=next.id %}">Next
</a>
{% endif %}
您对这种方法有何看法?因此,下一步只更改标签|上一步,否则效果很好?@Horatiujefleal all link HTMLs。您可以在查询集中添加order_by,比如queryset=Post.objects.all.order_by'-date_created',并检查您的输出。@MKPatel尝试了您的方法。我没有看到任何变化。作为一个黑客,我可能会使用{%with object.get_next_by_date_创建为prev%}和{%with object.get_PREVICE_by_date_创建为next%}但这很难看。我的问题与generic.DetailView有关,而不是generic.ListView,我更新了它。抱歉搞混了。谢谢,它成功了。顺便说一下,它也可以在代码片段中不使用paginate_By=5的情况下工作。你能解释一下原因吗?是的,因为如果不编写paginate_,它将采用默认分页。我仍然不确定它是否与我在问题中发布的默认模板代码兼容。但编辑之前的模板代码易于理解和使用。Django doc中paginate_by的参考是,从逻辑上讲,您正在编写,但如果Django is提供了使用prev/next的内置功能,那么为什么我们应该编写逻辑以应用相同的功能:不,逻辑上它们不一样。遗憾的是,我还没有看到内置的功能。
class PostDetailView(generic.DetailView):
model = Post
def get_context_data(self, **kwargs):
context = super(PostDetailView, self).get_context_data(**kwargs)
next = Post.objects.filter(pk__lt=self.object.pk).order_by('-pk')[:1]
prev = Post.objects.filter(pk__gt=self.object.pk).order_by('pk')[:1]
if prev:
context['prev'] = prev[0]
if next:
context['next'] = next[0]
return context
{% if prev %}
<a class="nav-link-prev"
href="{% url "post_detail" pk=prev.id %}">Previous
</a>
{% endif %}
{% if next %}
<a class="nav-link-next"
href="{% url "post_detail" pk=next.id %}">Next
</a>
{% endif %}