【问题标题】:Django exists() versus DoesNotExistDjango exists() 与 DoesNotExist
【发布时间】:2017-04-16 01:29:28
【问题描述】:

我对 django exists()DoesNotExist 异常有一些疑问。

示例代码:

id = 1
# first
if User.objects.get(pk=id).exists():
    # my logic
    pass
# second
try:
    User.objects.get(pk=id)
    # my logic
    pass
except User.DoesNotExist:
    return 0

我经常使用get() 方法。哪种做法更好?哪个代码更好?第一个还是第二个?

【问题讨论】:

标签: python django web


【解决方案1】:

if User.objects.get(pk=id).exists()

这行不通,所以这个问题很容易回答:这种方式不如有效的方式:-)

我猜你实际上没有创建Minimal Complete Verifiable Example,所以在你发布未经验证的代码时错过了错误。


因此,我想您是在问:

  • QuerySet.exists() 当您有一个 QuerySet(例如来自过滤操作)时。

    例如:

  if User.objects.filter(pk=id).exists():
      # ... do the things that need that user to exist
  try:
      user = User.objects.get(pk=id)
  except User.DoesNotExist:
      # ... handle the case of that user not existing

区别在于:

  • QuerySet.exists 方法在查询集上,这意味着您向它询问查询(“是否有 任何 个实例与此查询匹配?”),而您尚未尝试检索任何特定实例。

  • 当您实际尝试检索一个实例时引发模型的 DoesNotExist 异常,但该实例不存在。

使用正确表达您意图的任何一个。

【讨论】:

  • if User.objects.filter(pk=id).exists():
【解决方案2】:

您可以在docs找到更多信息: 关于exists(),但exists() 仅适用于QuerySet

如果 QuerySet 包含任何结果,则返回 True,否则返回 False。这会尝试以最简单和最快的方式执行查询,但它确实执行与普通 QuerySet 查询几乎相同的查询。

exists() 对于与 QuerySet 中的对象成员资格以及 QuerySet 中是否存在任何对象相关的搜索非常有用,尤其是在大型 QuerySet 的上下文中。

ObjectDoesNotExist 仅适用于get()

您也可以尝试其他方法:

user = User.objects.filter(id=2)
if user:
    # put your logic
    pass

【讨论】:

    【解决方案3】:

    在 Django 模型中, 如果您要使用model.objects.get(),如果它不存在,则会引发错误。在这种情况下,您可以使用 DoesNotExistexcept:

    try:
      val = Model.objects.get(pk=val) # if nothing found it will raise an exception
    exception:
      you can trace an exception without mentioning anything on top.
    (or)
    exception ObjectDoesNotExist:
      # it will come here if exception is DoesNotExist
    

    【讨论】:

      【解决方案4】:

      对于 Django 版本 2.0.6,您可以执行以下操作,它会起作用:

      if Model.objects.filter(my_id=objectid).exists():
        myobject = get_object_or_404(Model, my_id=objectid)
        context = {'myobject': myobject}
        return render(request, self.template_name, context)
      

      您可以在此处获取更多信息:https://docs.djangoproject.com/en/2.1/ref/models/querysets/

      【讨论】:

        【解决方案5】:

        据我了解,您是在询问是使用 if 语句还是尝试在您的代码上使用 catch。我个人更喜欢避免使用 try catch,认为这是一种丑陋的语法,当我确实想引发异常时,我使用 python 关键字 raise,对我来说,它使代码更清晰。

        代码示例:

        user = User.objects.filter(id=2)
        if not user:
           raise ObjectDoesNotExist
        

        【讨论】:

          【解决方案6】:

          由于我们在 Django 中,我们将尝试使用 Django 功能而不是常用方法(即在 Python 中使用异常)来捕获错误。

          id = 1
          def a_query(id):
            qs = User.objects.filter(pk=id)
            if qs.exists():
              return qs.first()
            return None
          

          在这里,exists() 方法可以帮助你捕捉错误(如果有的话)。

          参考:https://docs.djangoproject.com/en/3.0/ref/models/querysets/#django.db.models.query.QuerySet.exists

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2016-04-30
            • 2011-01-09
            • 1970-01-01
            • 1970-01-01
            • 2012-06-21
            • 2011-09-03
            • 1970-01-01
            • 2013-05-14
            相关资源
            最近更新 更多