【问题标题】:django how to get the 0th item from a possibly empty listdjango 如何从可能为空的列表中获取第 0 项
【发布时间】:2011-07-05 16:45:42
【问题描述】:

我有一个模型为“Post”的简单博客应用程序。如果我删除 Post 模型中的所有条目,当我尝试引用按日期排序的帖子列表中的第一项时会出现错误,我这样做是这样的:

latest_post = Post.objects.order_by('-date_created')[0]

错误是:IndexError: list index out of range

作为修复,我现在得到这样的项目:

all_posts = Post.objects.order_by('-date_created')
latest_post = ()
if (all_posts):
  latest_post = all_posts[0]

如果我的模型“Post”中没有项目,并且没有抛出异常,则此方法有效。 然而对我来说,这似乎是太多的代码来做一些相当简单的事情。我认为使用 django QuerySet API 有更好的方法来执行此操作,但在文档中找不到任何内容。

有什么想法吗?

编辑:奇怪的是,当 Post 模型中没有项目时,这不会引发错误:

latest_post_list = Post.objects.all().order_by('-date_created')[1:10]

【问题讨论】:

    标签: django django-queryset


    【解决方案1】:

    这并不奇怪,这完全是意料之中的行为。一个空列表(或本例中的查询集)的计算结果为 False,因此您永远不会索引到查询集。如果您尝试索引到一个空列表(就像您使用第一种方法一样),它会抛出一个 IndexError。

    你写的东西会起作用,但它不是最好的 imo。更好的写法是这样

    try:
        latest_post = Post.objects.order_by('-date_created')[0]
    except IndexError:
        latest_post = None
    

    这是一种更 Pythonic 的编写方式,更易于阅读和理解您要执行的操作。

    甚至更好

    try:
        latest_post = Post.objects.latest('date_created')
    except Post.DoesNotExist:
        latest_post = None
    

    请注意,在第二个示例中,它使用了 latest() 查询集方法。另请注意,参数只是字段名而不是-fieldname。你甚至可以在你的模型元类中指定get_latest_by = 'date_created',然后该行就变成latest_post = Post.objects.latest(),甚至不需要指定字段名参数

    【讨论】:

    • +1 表示try... except。请求宽恕比请求许可更容易。
    • +1 建议将 latest 作为解决问题的更好方法。
    • 请注意,.latest() 不会过滤掉任何空条目 - 并且空值通常首先排序:)。所以如果日期可以为空,你需要Post.objects.exclude(date_created=None).latest('date_created')
    【解决方案2】:

    一个简单的python修复方法是使用

    latest_post = Post.objects.order_by('-date_created')[0:1]
    

    【讨论】:

      【解决方案3】:
      latest_post = Post.objects.order_by('-date_created')[:1]
      if latest_post:
          latest_post = latest_post[0]
      

      这不会引发异常,您仍然可以在 latest_post 上检查空列表条件。

      您的问题来自使用绝对索引 IE: [0] 可能存在也可能不存在。通过使用切片 [:1] 你是说你想要一个列表,如果它存在,则列表中的第一项......如果它不存在,你只会得到一个空列表。

      【讨论】:

      • 对不起,stefan给出了类似的答案
      • 更正:使用[:1]时,如果没有结果,则得到一个空列表([]),而不是None
      • 更正了返回以反映空列表结果。
      • list[:1] 返回大小为 1 的列表或大小为 0 的列表。所以你仍然需要稍后检查列表的大小。我正在编辑答案以反映这一点。
      猜你喜欢
      • 1970-01-01
      • 2019-04-23
      • 2022-10-05
      • 1970-01-01
      • 2015-05-12
      • 2018-08-21
      • 2012-04-24
      • 1970-01-01
      • 2022-12-17
      相关资源
      最近更新 更多