我正在使用一个包含多个表单的 FormSet,每个表单都有一个数量字段,其定义如下:
quantity = TypedChoiceField(coerce=int, required=False)
我想知道是否至少有一个数量 > 0,所以在我的表单集的干净中,我写了这个:
def clean(self):
if sum([form.cleaned_data['quantity'] for form in self.forms]) == 0:
raise forms.ValidationError(_('No products selected'))
所以,通常这只是工作,并且 form.cleaned_data['quantity'] 是一个 int(由 coerce=int 设置)。但是每隔一段时间(比如每 2000 次对这个表单的请求一次),我得到一个异常告诉我:
TypeError: unsupported operand type(s) for +: 'int' and 'str'
在那一行,这意味着 form.cleaned_data['quantity'] 是一个字符串,而 sum() 不喜欢对字符串求和,所以它会抛出一个异常。您可以通过启动 python 控制台并键入以下内容自行测试:
>>> sum([u'1', u'2'])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'int' and 'unicode'
>>>
所以我的问题是,为什么会发生这种情况?还有为什么这种情况很少发生?django 文档告诉我 TypedChoiceField 的强制保证在 clean() 被调用之前完成,所以这不应该发生。
这个错误很难修复,因为它很难重现,所以我希望你们中的一个人遇到过类似的问题。
这是在 python 2.6 和 django 1.3.1 上。
提前致谢!
编辑 所以这里是堆栈跟踪:
File "****/handlers/products.py" in process
429. if formset.is_valid():
File "/usr/local/lib/python2.6/dist-packages/django/forms/formsets.py" in is_valid
263. err = self.errors
File "/usr/local/lib/python2.6/dist-packages/django/forms/formsets.py" in _get_errors
241. self.full_clean()
File "/usr/local/lib/python2.6/dist-packages/django/forms/formsets.py" in full_clean
287. self.clean()
File "****/handlers/products.py" in clean
217. if sum([form.cleaned_data['quantity'] for form in self.forms]) == 0:
异常类型:异常值处的 TypeError /****/url
:+ 不支持的操作数类型:“int”和“str”