我有一个非常简单的查询集和相关的通用视图:
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}
答案 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似乎可能是最佳选择。