Django get_object_or_404或过滤器存在

Mut*_*vel 3 python django filter

我们需要确定对象是否在模型中可用。

有两种方法可以检查是否存在,

MyModel.objects.filter(pk=pk).exists()
Run Code Online (Sandbox Code Playgroud)

要么

get_object_or_404(MyModel, pk=pk)
Run Code Online (Sandbox Code Playgroud)

哪个查询更好更有效?

注意:无需使用该对象(pk)执行任何操作。只想知道是否存在..

Ala*_*air 10

使用

get_object_or_404(MyModel, pk=pk)
Run Code Online (Sandbox Code Playgroud)

是捷径

try:
    my_model = MyModel.objects.get(pk=pk)
except:
    raise Http404
Run Code Online (Sandbox Code Playgroud)

因此,只有get_object_or_404在对象不存在时要返回 404 错误时才应使用。

如果您实际上不需要模型对象,那么理论上使用exists()代替会更有效get(),因为exists()实际上并不返回对象:

if not MyModel.objects.exists():
    raise Http404
Run Code Online (Sandbox Code Playgroud)

在实践中,我不确定您是否真的会注意到差异。因此,您可能会选择使用get_object_or_404使代码稍微简单一些。


kxx*_*ing 5

使用exists会更快,但不会那么明显。我们可以通过记录SQL查询来了解这些查询在内部的作用:

import logging
l = logging.getLogger('django.db.backends')
l.setLevel(logging.DEBUG)
l.addHandler(logging.StreamHandler())

User.objects.filter(pk=1).exists()
get_object_or_404(User, pk=1)

? (0.000) SELECT (1) AS "a" FROM "users" WHERE "users"."id" = 1 LIMIT 1; args=(1,)
? (0.001) SELECT "users"."id", "users"."password", ... FROM "users" WHERE "users"."id" = 1; args=(1,)
Run Code Online (Sandbox Code Playgroud)

那么答案就显而易见了。他们有几乎相同的查询,但get_object_or_404将获得的所有列在一个表中,而exist只需要one。但这绝不是什么大问题。