【问题标题】:How to get latest and earliest from a django QuerySet如何从 django QuerySet 中获取最新和最早的
【发布时间】:2019-04-01 21:46:28
【问题描述】:

在我的 django 应用中,有几种不同的方法可以获取相同模型的 QuerySet 对象。

我想使用一个函数来呈现数据——这一直很好,直到我决定添加 earliestlatest 时间来显示名列前茅。

这是我最近的尝试:

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)

【问题讨论】:

  • 这里的objList 是什么?这看起来像一个视图函数(因为它的第一个参数被称为request 并且它返回一个呈现的模板) - 你如何将看似复杂的对象(不是简单的字符串或数字)作为 URL 的一部分传递?
  • 这是一个被多个视图函数调用的函数

标签: python django django-models django-views django-queryset


【解决方案1】:

解决此错误的方法是使用latest()earliest()(以及first()last(),仅用于未切片的查询集(例如,使用queryset[:5] 获得顶部5 条记录)。你objList 似乎在传递给函数之前已经被切片了。

如果您的查询集具有正确顺序的记录(意味着最早和最晚在第一和最后),您还有两个选择:

  1. 使用三个额外的查询来获取第一条和最后一条记录:
earliest = objList[0]
latest = objList[objList.count()]
  1. 实例化查询集中的对象(在它上面调用len)。然后,您无需额外查询即可访问第一项和最后一项:
latest = objList[len(objList)-1]
earliest = objList[0]

这只需要一个查询,但是它将查询集中的所有对象加载到内存中。

重复一遍,这仅在查询集被排序以便具有earliestlatest 的第一个和最后一个时才有效。否则你必须定义单独的查询集。

【讨论】:

  • 一些调用render_list的视图函数对queryset进行切片,顺序不同...
  • 我发现我可以将额外的参数传递给render_list,并在那里进行任何必要的切片。谢谢!
猜你喜欢
  • 2022-07-21
  • 2014-05-29
  • 1970-01-01
  • 2020-05-04
  • 2017-08-25
  • 2013-06-04
  • 1970-01-01
  • 2021-09-29
  • 1970-01-01
相关资源
最近更新 更多