更好的方法来检查一个对象是否存在于获取/过滤器中的 Django ORM 中?



>让我们考虑我正在尝试查找主键为 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)
)

因此,万一当您将filterexists一起使用时.它将执行几乎相同的代码,因为下面的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是专门为获得一件物品而制作的。

最新更新