来自查询集/通用视图的下一个上一个链接

时间:2010-02-06 21:40:45

标签: django views pagination generics

我有一个非常简单的查询集和相关的通用视图:

f_detail = {
         'queryset': Foto.objects.all(),
         'template_name': 'foto_dettaglio.html',
         "template_object_name" : "foto",
       }

urlpatterns = patterns('',
# This very include
(r'^foto/(?P<object_id>\d+)/$', list_detail.object_detail, f_detail, ),
)

只是用于生成照片详细信息页面的模板:所以没有视图。


是否有一种简单的方法可以链接到上一个|模板中的下一个元素 没有manualy编码视图?

像是一样:

{% if foto.next_item %} 
  <a href="/path/foto/{{ foto.next_item.id_field }}/">Next</a> 
{% endif}

3 个答案:

答案 0 :(得分:24)

class Foto(model):
  ...
  def get_next(self):
    next = Foto.objects.filter(id__gt=self.id)
    if next:
      return next.first()
    return False

  def get_prev(self):
    prev = Foto.objects.filter(id__lt=self.id).order_by('-id')
    if prev:
      return prev.first()
    return False

你可以根据自己的喜好调整这些。我只是再次查看你的问题...为了使它比使用if语句更容易,你可以让方法返回链接的标记,如果有的话,链接到下一个/ prev,否则什么都不返回。那么你只需foto.get_next等等。还记得查询集是懒惰的,所以你实际上并没有在下一个/上一个中获得大量的项目。

答案 1 :(得分:7)

上面的Foto版本有几个缺点:

  • 执行像if next:这样的布尔评估可能会很慢,因为它基本上会加载整个QuerySet结果。使用next.exists()或我的版本中的try / except。
  • get_prev()结果错误,因为在这种情况下您需要撤消排序。

所以这里的FWIW是我的版本,用于通用主键:

def get_next(self):
    """
    Get the next object by primary key order
    """
    next = self.__class__.objects.filter(pk__gt=self.pk)
    try:
        return next[0]
    except IndexError:
        return False

def get_prev(self):
    """
    Get the previous object by primary key order
    """
    prev = self.__class__.objects.filter(pk__lt=self.pk).order_by('-pk')
    try:
        return prev[0]
    except IndexError:
        return False

答案 2 :(得分:1)

如果您接受Model.objects.all()作为您的查询集,并且您可以通过日期字段抓取下一个/上一个项目(通常使用auto_now_add = True的'created'字段将提供与对象ID),您可以使用get_next_by_foo() and get_previous_by_foo(),其中'foo'是日期字段。

对于来自更复杂的QuerySet的下一个/上一个链接,使用Paginator with threshold set to one似乎可能是最佳选择。