假设我想获得一个与值匹配的记录,我有两种方法可以做到:
首先:
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查找。
答案 0 :(得分:11)
第一个在Python中是首选,基于 EAFP 设计原则("更容易请求宽恕而不是权限")。除了速度之外,这个系统的一个优点是没有竞争条件 - 在第二个例子中,如果对数据库的其他并发访问改变了第一行和第二行代码执行之间的结果,那么你的结果将是不一致。
根据您对事务的使用,竞争条件可能不是问题,但一般来说 EAFP 是Python中的一个突出的设计模式,经验丰富的Python编码器在阅读代码时不会有任何问题以那种形式。
ETA:哦,我忘记了:不要使用except:
(你确实需要冒号)。使用except IndexError:
或您正在寻找的任何其他特定例外。这样,如果您遇到完全意外的错误,例如无法访问数据库,它将传播通过而不会被隐藏。您不希望出现这样的情况:您稍后会在抛出异常的情况下编写代码来表示"没有结果"而系统正试图告诉你"数据库已关闭"。
答案 1 :(得分:0)
怎么样
matches = Model.objects.filter(field=value)[:1]
obj = matches[0] if matches else None
查询只会被评估一次(当评估条件表达式的matches
部分中的if
时),这用于空白检查和检索结果。请注意切片以限制返回的对象数。