Подтвердить что ты не робот

Получение следующих и предыдущих объектов в Django

Я пытаюсь получить следующий и предыдущий объекты проблемы с комиксами. Простое изменение номера идентификатора или фильтрация с добавленной датой не будет работать, потому что я не добавляю проблемы последовательно.

Вот как мои представления настраиваются, и он РАБОТАЕТ для prev_issue и возвращает предыдущий объект, но возвращает последний объект для next_issue, и я не знаю почему.

def issue(request, issue_id):
issue = get_object_or_404(Issue, pk=issue_id)
title = Title.objects.filter(issue=issue)
prev_issue = Issue.objects.filter(title=title).filter(number__lt=issue.number)[0:1]
next_issue = Issue.objects.filter(title=title).filter(number__gt=issue.number)[0:1]
4b9b3361

Ответ 1

Добавьте предложение order_by, чтобы он заказывал number.

next_issue = Issue.objects.filter(title=title).filter(number__gt=issue.number).order_by('number')[0:1]

Ответ 2

Я знаю, что это немного поздно, но для кого-то еще у django есть лучший способ сделать это, см. https://docs.djangoproject.com/en/1.7/ref/models/instances/#django.db.models.Model.get_previous_by_FOO

Итак, ответ здесь будет чем-то вроде

next_issue = Issue.get_next_by_number(issue, title=title)

Менеджеры Django делают это с небольшим отклонением метакласса.

Ответ 3

Если требуется найти next и предыдущие объекты, упорядоченные по значениям полей, которые могут быть равны, и эти поля не относятся к Date* type, запрос становится немного сложным, потому что:

  • упорядочение объектов с одинаковыми значениями, ограничивающими [:1], всегда будет давать одинаковый результат для нескольких объектов;
  • сам объект может быть включен в результирующий набор.

Вот запросы, которые также учитывают первичные ключи для получения правильного результата (если предположить, что параметр number из OP не уникален и опускает параметр title, как это не имеет значения для примера):

Предыдущий:

prev_issue = (Issue.objects
    .filter(number__lte=issue.number, id__lt=instance.id)
    .exclude(id=issue.id)
    .order_by('-number', '-id')
    .first())

Далее:

next_issue = (Issue.objects
    .filter(number__gte=issue.number, id__gt=instance.id)
    .exclude(id=issue.id)
    .order_by('number', 'id')
    .first())