django如何从可能为空的列表中获取第0项

Boo*_*aka 8 django django-queryset

我有一个简单的博客应用程序与模型"发布".如果我删除Post模型中的所有条目,当我尝试引用按日期排序的帖子列表中的第一项时,我会收到错误,我这样做:

latest_post = Post.objects.order_by('-date_created')[0]
Run Code Online (Sandbox Code Playgroud)

错误是:IndexError:列表索引超出范围

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

all_posts = Post.objects.order_by('-date_created')
latest_post = ()
if (all_posts):
  latest_post = all_posts[0]
Run Code Online (Sandbox Code Playgroud)

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

有任何想法吗?

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

latest_post_list = Post.objects.all().order_by('-date_created')[1:10]
Run Code Online (Sandbox Code Playgroud)

Joh*_*ohn 15

没有什么奇怪的,这是完全预期的行为.空列表(或在此情况下特别是查询集)的计算结果为False,因此您永远不会索引到查询集.如果您尝试索引到一个空列表(就像您使用第一种方法一样),它将抛出一个IndexError.

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

try:
    latest_post = Post.objects.order_by('-date_created')[0]
except IndexError:
    latest_post = None
Run Code Online (Sandbox Code Playgroud)

这是一种更加pythonic的写作方式,更容易阅读和理解你想要做的事情.

甚至更好

try:
    latest_post = Post.objects.latest('date_created')
except Post.DoesNotExist:
    latest_post = None
Run Code Online (Sandbox Code Playgroud)

请注意,在第二个示例中,它使用了latest()queryset方法.另请注意,参数只是fieldname而不是-fieldname.您甚至可以在模型中指定Meta类get_latest_by = 'date_created',然后该行latest_post = Post.objects.latest()甚至不需要指定fieldname参数

  • +1表示最新作为解决问题的更好方法. (2认同)