>让我们考虑我正在尝试查找主键为 20 的用户是否存在?我可以通过两种方式做到这一点。
第一个 :
try:
user = User.objects.get(pk=20)
except User.DoesNotExist:
handle_non_existent_user()
另一种方式可能是:
users = User.objects.filter(pk=20)
if not users.exists():
handle_non_existent_user()
哪种方法更适合检查存在?
这可能与此有关:检查 django 中是否存在数据的最佳方法是什么? 然而,人们倾向于第一种方法,因为指定的例子没有模型查询集的引用。
同样在以下问题的答案中:验证对象是否存在于 django 视图中而不返回 404 的正确方法是什么? 它主要是基于因为我们没有得到相关对象的引用。
TLDR:对于几乎总是确定对象是 db 的情况,最好使用try:get
对于该对象不存在的可能性为 50% 的情况,最好使用if:filter.exists
这实际上取决于代码上下文。例如,在某些情况下if
语句比try/except
在 python 中使用 try vs if
更好所以对于你的问题,Django 的 filter(( 和 get(( 方法之间的区别是一样的。get
调用下面的方法filter
https://github.com/django/django/blob/stable/1.11.x/django/db/models/query.py#L366
def get(self, *args, **kwargs):
"""
Performs the query and returns a single object matching the given
keyword arguments.
"""
clone = self.filter(*args, **kwargs)
if self.query.can_filter() and not self.query.distinct_fields:
clone = clone.order_by()
num = len(clone)
if num == 1:
return clone._result_cache[0]
if not num:
raise self.model.DoesNotExist(
"%s matching query does not exist." %
self.model._meta.object_name
)
raise self.model.MultipleObjectsReturned(
"get() returned more than one %s -- it returned %s!" %
(self.model._meta.object_name, num)
)
因此,万一当您将filter
与exists
一起使用时.它将执行几乎相同的代码,因为下面的exists
这样做
def exists(self):
if self._result_cache is None:
return self.query.has_results(using=self.db)
return bool(self._result_cache)
正如你所看到的filter.exists
将执行更少的代码并且应该工作得更快,但它不会返回一个对象。
在我看来,第一个是最好的方法,因为如果我忘记检查用户是否存在,即使我不使用try / except
子句,它也会给我一个错误。
此外,get
是专门为获得一件物品而制作的。