有没有更好的方法来处理DoesNotExist查询集

时间:2012-10-06 21:02:15

标签: python django

可能有一种更好的方法来处理不存在的查询集......! 我对此代码的问题是,如果正常情况为真,它会引发异常!即:如果db中具有相同名称的工作空间名称不存在。

但是我没有异常,而是希望找到一个不返回DoesNotExist但是为true或false的查询

我的代码不错:

 try:
            is_workspace_name = Workspace.objects.get(workspace_name=workspace_name,user=self.user.id )
 except:
        return workspace_name
 if is_workspace_name:
            raise forms.ValidationError(u'%s already exists as a workspace name! Please choose a different one!' %workspace_name  ) 

非常感谢!

3 个答案:

答案 0 :(得分:3)

您可以使用exists()方法。引用文档:

  

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

备注: 最简单,最快捷的方法。 使用exists(比count)更便宜,因为exists数据库在第一次出现时停止计数。

if Workspace.objects.filter(workspace_name=workspace_name, 
                            user=self.user.id).exists()
    raise forms.ValidationError(u'%s already exists ...!' % workspace_name)
else:
    return workspace_name

答案 1 :(得分:1)

检查是否存在记录。

如果要测试数据库中是否存在记录,可以使用Workspace.objects.filter(workspace_name = workspace_name,user = self.user.id).count()

这将返回与您的条件匹配的记录数。如果没有,则该数字将为0,这将很容易与if子句一起使用。我相信这是我在这里做你需要的最标准和最简单的方法。

##编辑##实际上这是错误的,您可能需要使用Queryset.exists检查danihp的答案以获得更好的解决方案!

警告:在插入之前检查存在的情况

使用这样的构造时要小心,特别是如果您打算在尝试插入记录之前检查是否有重复内容。在这种情况下,最好的解决方案是尝试创建记录并查看它是否引发异常。

确实,您可能处于以下情况:

  1. 请求1到达服务器
  2. 请求2到达服务器
  3. 检查已完成请求1,不存在任何对象。
  4. 检查已完成请求2,不存在任何对象。
  5. 在请求1中继续创建。
  6. 在请求2中继续创建。
  7. 并且......你有一个副本 - 这被称为race condition,并且在处理并行代码时是一个常见问题。

    长话短说,在处理插入时,您应该使用tryexpectunique限制。

    按照init3的建议使用get_or_create也有帮助。确实,get_or_create is aware of this,只要不必要的重复会引发IntegrityError

    ,您就会安全

答案 2 :(得分:0)

obj, created = Workspace.objects.get_or_create(workspace_name=workspace_name, user=self.user.id)

if created:
    # everything ok
    # do something
    pass
else:
    # not ok
    # respond he should choose anything else
    pass

read more at the docs