2013-03-15 28 views
5

Tôi đang sử dụng một FormSet có chứa nhiều hình thức mà mỗi người đều có một lĩnh vực số lượng được định nghĩa như thế này:FormSet sử dụng TypedChoiceField không bị ép buộc để int một lần ~ 2000 yêu cầu

quantity = TypedChoiceField(coerce=int, required=False) 

Tôi muốn biết liệu tại ít nhất một số lượng> 0, vì vậy trong formset của tôi sạch sẽ, tôi viết những dòng này:

def clean(self): 
    if sum([form.cleaned_data['quantity'] for form in self.forms]) == 0: 
     raise forms.ValidationError(_('No products selected')) 

vì vậy, thông thường này chỉ hoạt động, và form.cleaned_data [ 'lượng'] là một int (như thiết lập bởi ép buộc = int) . Nhưng mỗi một lần trong một thời gian (như một lần mỗi 2000 yêu cầu hình thức này), tôi nhận được một ngoại lệ mà nói với tôi:

TypeError: unsupported operand type(s) for +: 'int' and 'str' 

On line đó, có nghĩa là form.cleaned_data [ 'lượng'] là một chuỗi , và sum() không thích chuỗi tổng hợp, vì vậy nó ném một ngoại lệ. Bạn có thể tự mình kiểm tra điều này bằng cách bắt đầu bảng điều khiển python và nhập:

>>> 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' 
>>> 

Vì vậy, câu hỏi của tôi là, tại sao điều này xảy ra? Và tại sao điều này lại hiếm khi xảy ra? Các tài liệu django nói với tôi việc ép buộc của TypedChoiceField được đảm bảo phải được thực hiện trước khi clean() được gọi, do đó, điều này không nên xảy ra.

Lỗi này rất khó khắc phục vì rất khó để tái tạo, vì vậy tôi hy vọng một trong các bạn đã gặp sự cố tương tự như vậy.

Đây là trên trăn 2.6 và django 1.3.1.

Cảm ơn trước!

EDIT Vì vậy, đây là stacktrace:

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: 

Exception Loại: Loại lỗi tại /****/url Value Ngoại lệ: không được hỗ trợ loại toán hạng (s) cho +: 'int' và 'str'

+0

Vấn đề này nghe có vẻ cục bộ, nhưng tôi bắt đầu bắt ngoại lệ cụ thể trong mã trực tiếp của bạn và đăng nhập biến cục bộ xung quanh điểm dừng đó, sau đó đợi cho nó xảy ra lần nữa để bạn có ít nhất một cái gì đó để gỡ lỗi. Btw Sentry là một công cụ tốt để tự động hóa điều này, goodluck –

Trả lời

1

Mặc định empty_value cho số TypedChoiceField là chuỗi rỗng, theo số the docs và giá trị đó không bị ép buộc.

Tôi nghĩ rất có khả năng bạn sẽ nhận được giá trị trống vào dịp này, và chuỗi đang ném TypeError của bạn là chuỗi rỗng. Hãy thử:

quantity = TypedChoiceField(coerce=int, required=False, empty_value=0) 
+0

Đó là lạ mặc dù, bởi vì tôi có một dấu vết ngoại lệ trong Sentry mà còn lưu các nội dung bài viết, và giá trị số lượng chứa u'1 '. Vì vậy, đó rõ ràng không phải là một giá trị rỗng. – jaapz

+0

Tôi có thể xem xét theo dõi đó không? – Hamms

+0

Tôi đã thêm stacktrace vào bài đăng :) – jaapz