0

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

但是我不想有一个例外,我想去一个不返回 DoesNotExist 但真或假的查询

我不优雅的代码:

 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  ) 

非常感谢!

4

3 回答 3

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
于 2012-10-06T21:14:12.593 回答
1

检查记录是否存在。

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

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

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

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

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

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

  1. 请求 1 到达服务器
  2. 请求 2 到达服务器
  3. 检查请求 1,不存在对象。
  4. 检查请求 2,不存在对象。
  5. 继续请求 1 中的创建。
  6. 继续请求 2 中的创建。

而且......你有一个重复 - 这被称为竞争条件,并且是处理并行代码时的常见问题。

长话短说,您应该在处理插入时使用try,expect和约束。unique

按照 init3 的建议,使用get_or_create也有帮助。确实,get_or_create知道这一点,只要不需要的重复会引发IntegrityError

于 2012-10-06T21:09:46.423 回答
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

在文档中阅读更多内容

于 2012-10-06T21:04:13.667 回答