27

这是我在处理 Django 项目时遇到的一个问题。这是关于表单验证的。

在 Django 中,当您有一个提交的表单时,您可以调用is_valid()相应的表单对象来触发验证并返回一个布尔值。所以,通常你的视图函数中有这样的代码:

if form.is_valid():
    # code to save the form data

is_valid()不仅验证表单数据,还向表单对象添加错误消息,之后可以显示给用户。

在一个页面上,我同时使用了两个表单,并且还希望仅当两个表单都包含有效数据时才保存数据。这意味着我必须is_valid()在执行代码之前调用这两个表单来保存数据。最明显的方式:

if form1.is_valid() and form2.is_valid():
    # ...

由于逻辑运算符的短路评估而无法工作。如果form1无效,form2则不会进行评估,并且会丢失其错误消息。

这只是一个例子。据我所知,在其他语言(即 Smalltalk)中没有and/的贪婪替代品。or我可以想象在不同的​​情况下会出现这个问题(不仅在 Python 中)。我能想到的解决方案都是笨拙的(嵌套ifs,将返回值分配给局部变量并在if语句中使用它们)。我想知道解决此类问题的pythonic方法。

4

3 回答 3

39

怎么样:

if all([form1.is_valid(), form2.is_valid()]):
   ...

在一般情况下,可以使用列表理解,以便预先计算结果(与此上下文中常用的生成器表达式相反)。例如:

if all([ form.is_valid() for form in (form1,form2) ])  

这也将很好地扩展到任意数量的条件......唯一的问题是它们都需要通过 " and" 而不是if foo and bar or baz: ....

(对于非短路or,您可以使用any代替all)。

于 2012-09-05T12:32:46.297 回答
27

您可以简单地使用二元&运算符,它将对布尔值执行非短路逻辑

if form1.is_valid() & form2.is_valid():
   ...
于 2012-09-05T12:43:30.777 回答
1

您可以使用中缀运算符(ActiveState Python 配方)来定义您自己的布尔运算符:

aand = Infix(lambda x,y: bool(x) and bool(y))
1 |aand| 2  # Will return `True` instead of `1`
于 2019-12-19T18:30:31.703 回答