Следующие предыдущие ссылки из набора запросов/общих представлений

У меня довольно простой набор запросов и связанные общие представления:

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 с порогом, установленным в один из них, кажется, что это лучший вариант.