Reputation: 1435
In my django app, there are a few different ways that I get a QuerySet object of the same model.
I would like to use one function to render the data -- and this has been working fine, until I decided to add both earliest and latest time to display on top of the list.
Here's my latest attempt:
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)
This produces the error message:
TypeError: Cannot reverse a query once a slice has been taken.
Is there a way to get around this problem?
More details:
The function render_list
is being called by multiple view functions in views.py
, for example :
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)
and corresponding lines in urls.py
path('list', views.list_all)
path('<group>/<ip>', views.detail)
Upvotes: 0
Views: 3865
Reputation: 5740
The way to get around this error is to use latest()
and earliest()
(as well as first()
and last()
only on querysets that haven't been sliced (e.g. using queryset[:5]
to get the top five records). You objList
seems to have been sliced before it was passed to the function.
If you have a queryset that has the records in the correct order (meaning that the earliest and latest are first and last), you have two more options:
earliest = objList[0]
latest = objList[objList.count()]
len
on it does that). Then you can access the first and last item without additional queries:latest = objList[len(objList)-1]
earliest = objList[0]
This needs only one query, but it loads all objects in the queryset into memory.
To repeat, this only works if the queryset is ordered so as to have earliest
and latest
first and last. Otherwise you have to define separate querysets.
Upvotes: 1