Как получить последний и самый ранний из Django QuerySet - PullRequest
0 голосов
/ 02 апреля 2019

В моем приложении django есть несколько разных способов получения объекта QuerySet той же модели.

Я бы хотел использовать одну функцию для рендеринга данных - и она работала нормально, пока я не решил добавить как самое раннее , так и самое позднее время для отображения поверх список.

Вот моя последняя попытка:

def render_list(request, objList):
    latest = earliest = None
    if objList:
        latest = objList.latest('time').time
        earliest = objList.earliest('time').time

    context = {'objList': objList,
               'earliest': earliest,
               'latest': latest,
               }
    return render(request, 'list.html', context)

Появляется сообщение об ошибке:

TypeError: Cannot reverse a query once a slice has been taken.

Есть ли способ обойти эту проблему?

Подробнее: Функция render_list вызывается несколькими функциями просмотра в views.py, например:

def list_all(request):
    objList = MyTable.objects.order_by('ip')
    return render_list(request,objList)

def detail(request, ip, group):
    objList = MyTable.objects
    try:
        item = MyTable.objects.get(ip=ip)
        # display the details page...

    except MyTable.DoesNotExist:
        objList = MyTable.objects.complex_filter(...)
        # more code
        # ...
        return render_list(request, objList)

и соответствующие строки в urls.py

path('list', views.list_all)
path('<group>/<ip>', views.detail)

1 Ответ

1 голос
/ 02 апреля 2019

Чтобы обойти эту ошибку, используйте latest() и earliest() (а также first() и last() только для наборов запросов, которые не были разрезаны (например, используя queryset[:5] для получения верхнегопять записей). Вы objList, кажется, были нарезаны до того, как они были переданы функции.

Если у вас есть набор запросов, в котором записи находятся в правильном порядке (это означает, что самые ранние и самые поздние являются первыми ипоследний), у вас есть еще две опции:

  1. Используйте три дополнительных запроса, чтобы получить первую и последнюю запись:
earliest = objList[0]
latest = objList[objList.count()]
Создание объектов в наборе запросов (вызов len для этого делает это).Затем вы можете получить доступ к первому и последнему элементу без дополнительных запросов:
latest = objList[len(objList)-1]
earliest = objList[0]

Для этого требуется только один запрос, но он загружает все объекты в наборе запросов в память.

Повторим, это работает только в том случае, если набор запросов упорядочен таким образом, чтобы earliest и latest были первыми и последними.В противном случае вы должны определить отдельные наборы запросов.

...