优先用 filter().first() 避免 doesnotexist 异常;必须用 get() 时需捕获对应模型的 doesnotexist 子类;视图层查资源可直接用 get_object_or_404();自定义 queryset 封装 get_or_none 等逻辑提升复用性。

直接用 get() 时怎么避免 DoesNotExist 崩程序?
别让 get() 直接抛异常中断流程——它本就不是为“可能找不到”设计的。真要查单条且不确定是否存在,优先改用 filter().first(),返回 None 而非异常,后续判空更自然。
如果必须用 get()(比如业务逻辑强依赖“必须存在”),那就得明确捕获异常:
try:
user = User.objects.get(id=123)
except User.DoesNotExist:
# 处理不存在的情况,比如返回默认对象、记录日志、抛自定义异常
user = None
注意:User.DoesNotExist 是每个模型类动态生成的子类,不能统一 import,也不能写成 ObjectDoesNotExist(那是基类,不推荐直接捕获,会掩盖其他问题)。
get_or_404() 和 get_object_or_404() 适合什么场景?
在 Django 视图里查单条资源(如用户页、文章详情页),且“不存在就 404”是合理响应时,直接上 get_object_or_404() 最省事:
from django.shortcuts import get_object_or_404
<p>def article_detail(request, pk):
article = get_object_or_404(Article, pk=pk) # 找不到自动 return Http404
return render(request, 'article.html', {'article': article})</p>
它本质是封装了 try/except + raise Http404,但只适用于视图层;别在 model 或 service 层滥用——那里不该耦合 HTTP 状态码。
另外:get_or_404() 已废弃,一律用 get_object_or_404()。
批量查询时 DoesNotExist 根本不会抛,但你可能误判了结果
filter()、all()、values_list() 这些从不抛 DoesNotExist,它们返回空 QuerySet 或空列表。常见误区是写了 if qs.get(...) 却没意识到 qs 是 QuerySet,结果还是触发异常。
容易踩的坑:
-
MyModel.objects.filter(...).get()—— 这里get()是 QuerySet 方法,照样抛DoesNotExist或MultipleObjectsReturned -
list(MyModel.objects.filter(...))后判if not result:没问题,但若用result[0]就可能IndexError,和DoesNotExist无关 - 用
exists()提前判断再get()?多一次 DB 查询,不必要;直接filter().first()更高效
自定义 Manager 或 QuerySet 时怎么统一处理“查不到”逻辑?
如果多个地方都要对某类查询做“查不到则返回默认值/创建新实例/抛特定异常”,可以封装进自定义 QuerySet:
class UserQuerySet(models.QuerySet):
def get_or_none(self, **kwargs):
try:
return self.get(**kwargs)
except self.model.DoesNotExist:
return None
<p>class UserManager(models.Manager):
def get_queryset(self):
return UserQuerySet(self.model, using=self._db)</p><pre class="brush:python;toolbar:false;">def get_or_none(self, **kwargs):
return self.get_queryset().get_or_none(**kwargs)
这样就能写 User.objects.get_or_none(username='alice'),干净又复用。但注意:别把所有“查不到”都吞掉——有些场景(比如权限校验中查 admin 用户)必须显式失败,否则埋下安全漏洞。
真正难的不是捕获异常,而是想清楚“查不到”到底意味着什么:是数据缺失、参数错误、还是业务规则被绕过?这个判断比代码本身更重要。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











