我目前有一个事件模型,其中对象按event_time (UTC UNIX时间戳)排序,存储为Django IntergerField,按ASC顺序。因为我没有按ID排序,所以这在分页时产生了一个问题,特别是在查询集不断增长的情况下。下面是我的事件模型:
# models.py
class Event(models.Model):
name = models.CharField(max_length=200)
event_time = models.IntegerField(default= 0, null=True, blank=True)
created = models.DateTimeField(auto_now_add=True)
现在为我的视图。py
# views.py
def events_view(request):
# range of queryset sent in request params
last_event_id = int(request.GET.get('last_event_id'))
start_time = int(request.GET.get('start_time'))
end_time = int(request.GET.get('end_time'))
if last_event_id == 0:
queryset = Event.objects.filter(event_time__gte = start_time,
event_time__lte = end_time).order_by('event_time')[:10]
else:
'''This is the part I'm having trouble with,
when the client requests the second page,
they will send the same start_time and event_time
as before but also send the event id of the last
event object from the first page. I need
to be able to get the next 10 objects in the
queryset after that event ID.'''
return HttpResponse(status=200)
因为我是按event_time排序的,所以我需要一些唯一的东西来分页查询集。我需要确保当用户请求下一页时,他们不会看到我们已经从上一页发送的相同对象。我怎样才能得到后面的10行呢?
只是为了清楚,我不能使用id__gte, lte, gt, lt.查询集不是基于ID排序的,它是基于event_time排序的。
你可以使用Django分页来实现。
这将删除代码中的if-else部分,然后您将不需要担心last_event_id
。只需将所有queryset
对象发送到Paginator
,以及您希望在每个页面上拥有的项目数量,它将为您提供访问每个页面项目的方法。
要获取特定页面的对象列表,只需在请求中发送一个额外的参数page_no
。
试试这个:
from django.core.paginator import Paginator
def events_view(request):
# range of queryset sent in request params
start_time = int(request.GET.get('start_time'))
end_time = int(request.GET.get('end_time'))
page_no = int(request.GET.get('page_no', 1))
objects = Event.objects.filter(event_time__gte = start_time,
event_time__lte = end_time).order_by('event_time')
p = Paginator(objects, 10)
requested_page = p.page(page_no)
requested_objects_list = requested_page.object_list # required objects list
return HttpResponse(status=200)