验证对象是不是存在于 django 视图中而不返回 404 的正确方法是啥?

Posted

技术标签:

【中文标题】验证对象是不是存在于 django 视图中而不返回 404 的正确方法是啥?【英文标题】:What is the right way to validate if an object exists in a django view without returning 404?验证对象是否存在于 django 视图中而不返回 404 的正确方法是什么? 【发布时间】:2010-10-12 23:52:51 【问题描述】:

我需要验证对象是否存在并返回该对象,然后根据该对象执行操作。不返回 404 的正确方法是什么?

try:
    listing = RealEstateListing.objects.get(slug_url = slug)
except:
    listing = None

if listing:

【问题讨论】:

Rasiel,我可以建议您考虑接受其他答案吗?这似乎是做到这一点的正确方法,并且得到的投票比接受的答案要多得多。 我可以考虑,但是存在是在 2010 年 5 月 17 日发布的 Django 1.2 中引入的,如果您注意到我的问题是在 09 年提交的......这是当时的正确答案。如果现在认为 Exists() 是最好的方法,我想选择第二个答案在语义上是正确的,对吧? Rasiel,这在当时是正确的答案是有道理的。但是,*** 站点似乎与构建一组具有最佳答案的好/官方问题一样多,因为这些站点正在寻找解决人们问题的方法。因此,我建议选择现在“官方正确”的答案。 if listing: 应该是 else: 【参考方案1】:

你也可以这样做:

if not RealEstateListing.objects.filter(slug_url=slug).exists():
    # do stuff...

有时使用try: except: 块会更清晰,有时使用单行代码exists() 会使代码看起来更清晰......这一切都取决于您的应用程序逻辑。

【讨论】:

.exists() 更快:docs.djangoproject.com/en/dev/ref/models/querysets/#exists 这是更好的方法,应该有答案 我假设exists() 不适用于get(),对吧? 请注意,此解决方案仅在您不打算使用相关对象时才有效。否则(例如在 OP 的情况下)它是错误的,并且比公认的解决方案慢很多:如果您稍后执行 get(),它将向数据库发送第二个查询。 如果您正在检查是否存在以对对象执行某些操作(如果存在),那么我会更喜欢 try-except 而不是 exists()【参考方案2】:

如果您没有得到 404,我不会使用 404 包装器。这是对意图的滥用。只需抓住 DoesNotExist 即可。

try:
    listing = RealEstateListing.objects.get(slug_url=slug)
except RealEstateListing.DoesNotExist:
    listing = None

【讨论】:

+1:是的,如果您不想要 404,这比公认的解决方案更好。 yap,这似乎是更好的解决方案 如果您需要对对象执行某些操作,此解决方案比 exists() 效果更好。 我喜欢加values_list('id', flat=True)。如果我只需要看看是否存在listing = RealEstateListing.objects.values_list('id', flat=True).get(slug_url=slug) 我觉得这种语法奇怪的是RealEstateListing.DoesNotExist 指的是模型,而不是对象本身。为什么不是RealEstateListing.objects.get(slug_url=slug).DoesNotExist【参考方案3】:
listing = RealEstateListing.objects.filter(slug_url=slug).first() 

【讨论】:

如果您以后需要使用潜在对象,这是最好的解决方案,因为它只需要一次赋值,并且避免了使用 try/except 块。请注意,您稍后可以简单地使用 if listing: 测试是否存在 避免 try/except 是不好的做法。软件开发最重要的方面之一是控制异常的可用性,这能够提供良好的用户体验。让人们知道什么时候不能正常工作。第二;如果要测试 QuerySet 的存在,请使用 .exists() 否则是一个对象。使用它们的主键测试是否存在.... if object.pk: // run code() 这个查询比检索对象的所有数据要快得多。你只想知道是否存在。 已经有使用 try/except 和 .exists() 的解决方案。我认为在 SO 中有多个不同的答案来做事是个好主意。也许这对于那些也想使用该对象(如果存在)的人来说更好。如果应避免使用 try/except,我不会制定任何规则。有时它很好,有时它很糟糕,例如,如果你只想编写非常紧凑的代码。【参考方案4】:

我会这样做很简单:

listing = RealEstateListing.objects.filter(slug_url=slug)
if listing:
    # do stuff

我认为不需要 try/catch。如果结果中可能存在多个对象,则使用用户 Henrik Heino 所示的 first()

【讨论】:

除非您对查询集执行 .first() 或在条件中执行 .first(),否则这将始终返回 True。 不正确,django 中的空查询集 == False

以上是关于验证对象是不是存在于 django 视图中而不返回 404 的正确方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

python 如果对象存在,Django会在视图中验证/验证

存储过程,视图

数据库(存储视图)

python django ajax:ValueError:视图没有返回 HttpResponse 对象。它返回 None 而不是

过滤器数组存在于对象数组中而​​不影响主数组

11月20日--存储过程视图