让我们考虑一下我是否想找到主键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()
哪种方法可以检查存在?
这可能与此有关:What is the best way to check if data is present in django? 但是,由于指定的示例没有模型查询集的引用,人们更喜欢第一种方法。
同样在以下问题的答案中:what is the right way to validate if an object exists in a django view without returning 404? 它主要是因为我们没有得到有问题的对象的参考。
答案 0 :(得分:1)
TLDR:对于几乎总是确定对象是db的情况,最好使用try:get
来处理当对象不存在的可能性为50%的情况时最好使用if:filter.exists
这实际上取决于代码上下文。例如,有些情况if
语句优于try/except
Using try vs if in python
所以对于你的问题,它是相同的Difference between Django's filter() and get() methods。调用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
将执行更少的代码并且应该更快地工作,但它不会返回给您一个对象。
答案 1 :(得分:0)
在我看来,第一个是最好的方法,因为如果我忘记检查用户是否存在,即使我不使用try / except
子句,它也会给我一个错误。
此外,get
专门用于获得一件商品。