验证对象是不是存在于 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 而不是