Следующие предыдущие ссылки из набора запросов/общих представлений
У меня довольно простой набор запросов и связанные общие представления:
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, ),
)
Просто шаблон для создания подробной страницы фотографии: так что нет представления.
Есть ли простой способ иметь ссылку на предыдущий | следующий элемент в шаблоне
без ручного кодирования вида?
Somthing like a:
{% if foto.next_item %}
<a href="/path/foto/{{ foto.next_item.id_field }}/">Next</a>
{% endif}
Ответы
Ответ 1
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, вы могли бы заставить методы вернуть разметку для ссылки на следующую/предыдущую, если она есть, иначе ничего не вернет. то вы просто делаете foto.get_next
и т.д., также помните, что запросы являются ленивыми, поэтому на самом деле вы не получаете тонны предметов в следующем/предыдущем.
Ответ 2
В приведенной выше версии 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
Ответ 3
Если вы примете Model.objects.all() в качестве набора запросов, и вам будет удобно захватывать следующие/предыдущие элементы по полю даты (обычно это поле "created" с auto_now_add = True будет иметь тот же порядок, что и object id), вы можете использовать get_next_by_foo() и get_previous_by_foo(), где 'foo' - это поле даты.
Для следующих/предыдущих ссылок из более сложного QuerySet, используя Paginator с порогом, установленным в один из них, кажется, что это лучший вариант.