2

假设我想获得与值匹配的记录,并且我有两种方法可以做到:

第一的:

try:
  obj = Model.objects.get(field = value)
except
  pass

第二:

if Model.objects.filter(field = value).count() > 0:
  obj = Model.objects.filter(field_value)[0]

让我们把代码注释放在一边,我应该使用哪种方式或者您更喜欢哪种方式阅读?第一种似乎更快,因为只查找 1 个 DB,但第二种方式似乎更具可读性,但需要 2 个 DB 查找。

4

2 回答 2

11

第一个是 Python 中的首选,基于EAFP设计原则(“请求宽恕比许可更容易”)。除了速度,这个系统的一个优点是没有竞争条件——在第二个例子中,如果其他对数据库的并发访问在执行第一行和第二行代码之间改变了结果,那么你的结果将不一致。

根据您对事务的使用,竞争条件的可能性可能不是问题,但一般来说,EAFP是 Python 中一种突出的设计模式,经验丰富的 Python 编码人员在阅读这种形式的代码时不会遇到任何问题。

ETA:哦,我忘了:不要使用except:(你需要冒号)。使用except IndexError:或您正在寻找的任何其他特定例外。这样,如果您遇到完全意外的错误,例如无法访问数据库,它将传播而不会被隐藏。您不希望出现这样一种情况,即您稍后编写代码计数被抛出的异常意味着“没有结果”,而是系统试图告诉您“数据库已关闭”。

于 2012-11-14T00:30:51.200 回答
0

怎么样

matches = Model.objects.filter(field=value)[:1]
obj = matches[0] if matches else None

查询只会被评估一次(在条件表达式matchesif部分评估时),这用于空性检查和检索结果。请注意切片以限制返回对象的数量。

于 2012-11-14T00:43:12.513 回答