cleaned_data 在 Django 1.11 中消失在哪里?
Where has cleaned_data vanished in Django 1.11?
我创建了一个 inlineformset_factory 如下:
formset = inlineformset_factory(Author, Book, form=BookForm,
formset=BaseBookFormSet,
can_order=False, can_delete=True,
extra=1, fields=('id', name)
)
书单如下:
class BookForm(forms.ModelForm):
name = forms.Charfield(required=True)
def __init__(self, *args, **kwargs):
super(BookForm, self).__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.form_tag = False
self.helper.layout = Layout(
Div(
Field("id", type="hidden"),
Field("name"),
Field("DELETE")
)
)
class Meta:
model = Book
fields = ('id', 'name')
def clean_name(self):
book_name = self.cleaned_data['name']
try:
book = Book.objects.get(name=book_name)
return book
except:
return book_name
def clean(self):
cleaned_data = super(BookForm, self).clean()
... other operations on cleaned_data ...
def has_changed(self):
changed = super(BookForm, self).has_changed()
cleaned_data = self.clean()
... other code here ...
提交表单时出现错误:
Exception Type: AttributeError
Exception Value: 'BookForm' object has no attribute 'cleaned_data'
当在 views.py 中调用 formset.is_valid() 时。 Traceback 首先显示 has_changed 中调用 self.clean 的行,然后显示调用 super clean 的 clean() 中的行。
这曾经在 django 1.10 中运行良好。
当我尝试在 Django 1.10 中打印 dir(self) 时,它确实显示 'cleaned_data' 作为属性之一,而在 Django 1.11 中则没有。
Django 1.11 中的 'cleaned_data' 在哪里消失了?
编辑:添加追溯:
Traceback (most recent call last):
File "/home/vagrant/venv/local/lib/python2.7/site-packages/django/core/handlers/exception.py", line 41, in inner
response = get_response(request)
File "/home/vagrant/venv/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 249, in _legacy_get_response
response = self._get_response(request)
File "/home/vagrant/venv/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 187, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/home/vagrant/venv/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 185, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/vagrant/venv/local/lib/python2.7/site-packages/django/views/generic/base.py", line 68, in view
return self.dispatch(request, *args, **kwargs)
File "/home/vagrant/venv/local/lib/python2.7/site-packages/django/views/generic/base.py", line 88, in dispatch
return handler(request, *args, **kwargs)
File "/vagrant/test_os/inventory/views.py", line 297, in post
if formset.is_valid():
File "/home/vagrant/venv/local/lib/python2.7/site-packages/django/forms/formsets.py", line 321, in is_valid
self.errors
File "/home/vagrant/venv/local/lib/python2.7/site-packages/django/forms/formsets.py", line 295, in errors
self.full_clean()
File "/home/vagrant/venv/local/lib/python2.7/site-packages/django/forms/formsets.py", line 345, in full_clean
if not form.has_changed():
File "/vagrant/test_os/inventory/forms.py", line 220, in has_changed
cleaned_data = self.clean()
File "/vagrant/test_os/inventory/forms.py", line 177, in clean
cleaned_data = super(BookForm, self).clean()
File "/home/vagrant/venv/local/lib/python2.7/site-packages/django/forms/models.py", line 344, in clean
return self.cleaned_data
AttributeError: 'BookForm' object has no attribute 'cleaned_data'
在 1.11 (in #26844) 中修复了表单集,以便在验证最少数量的表单时忽略空表单。作为副作用,表单集现在在验证表单之前在每个表单上调用 form.has_changed()
。 Django 期望 form.has_changed()
在验证表单之前可以安全调用,并且默认实现确实可以安全调用。
您已覆盖 form.has_changed()
以调用 self.clean()
,现在发生在验证表单之前。由于 form.clean()
要求验证表单,因此失败。
由于 form.full_clean()
实际上调用了 self.has_changed()
,您不能简单地从 form.has_changed()
中验证表单。您没有在 has_changed()
中显示您的操作,但将此代码放在其他地方很可能是个好主意。
我创建了一个 inlineformset_factory 如下:
formset = inlineformset_factory(Author, Book, form=BookForm,
formset=BaseBookFormSet,
can_order=False, can_delete=True,
extra=1, fields=('id', name)
)
书单如下:
class BookForm(forms.ModelForm):
name = forms.Charfield(required=True)
def __init__(self, *args, **kwargs):
super(BookForm, self).__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.form_tag = False
self.helper.layout = Layout(
Div(
Field("id", type="hidden"),
Field("name"),
Field("DELETE")
)
)
class Meta:
model = Book
fields = ('id', 'name')
def clean_name(self):
book_name = self.cleaned_data['name']
try:
book = Book.objects.get(name=book_name)
return book
except:
return book_name
def clean(self):
cleaned_data = super(BookForm, self).clean()
... other operations on cleaned_data ...
def has_changed(self):
changed = super(BookForm, self).has_changed()
cleaned_data = self.clean()
... other code here ...
提交表单时出现错误:
Exception Type: AttributeError
Exception Value: 'BookForm' object has no attribute 'cleaned_data'
当在 views.py 中调用 formset.is_valid() 时。 Traceback 首先显示 has_changed 中调用 self.clean 的行,然后显示调用 super clean 的 clean() 中的行。
这曾经在 django 1.10 中运行良好。
当我尝试在 Django 1.10 中打印 dir(self) 时,它确实显示 'cleaned_data' 作为属性之一,而在 Django 1.11 中则没有。
Django 1.11 中的 'cleaned_data' 在哪里消失了?
编辑:添加追溯:
Traceback (most recent call last):
File "/home/vagrant/venv/local/lib/python2.7/site-packages/django/core/handlers/exception.py", line 41, in inner
response = get_response(request)
File "/home/vagrant/venv/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 249, in _legacy_get_response
response = self._get_response(request)
File "/home/vagrant/venv/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 187, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/home/vagrant/venv/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 185, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/vagrant/venv/local/lib/python2.7/site-packages/django/views/generic/base.py", line 68, in view
return self.dispatch(request, *args, **kwargs)
File "/home/vagrant/venv/local/lib/python2.7/site-packages/django/views/generic/base.py", line 88, in dispatch
return handler(request, *args, **kwargs)
File "/vagrant/test_os/inventory/views.py", line 297, in post
if formset.is_valid():
File "/home/vagrant/venv/local/lib/python2.7/site-packages/django/forms/formsets.py", line 321, in is_valid
self.errors
File "/home/vagrant/venv/local/lib/python2.7/site-packages/django/forms/formsets.py", line 295, in errors
self.full_clean()
File "/home/vagrant/venv/local/lib/python2.7/site-packages/django/forms/formsets.py", line 345, in full_clean
if not form.has_changed():
File "/vagrant/test_os/inventory/forms.py", line 220, in has_changed
cleaned_data = self.clean()
File "/vagrant/test_os/inventory/forms.py", line 177, in clean
cleaned_data = super(BookForm, self).clean()
File "/home/vagrant/venv/local/lib/python2.7/site-packages/django/forms/models.py", line 344, in clean
return self.cleaned_data
AttributeError: 'BookForm' object has no attribute 'cleaned_data'
在 1.11 (in #26844) 中修复了表单集,以便在验证最少数量的表单时忽略空表单。作为副作用,表单集现在在验证表单之前在每个表单上调用 form.has_changed()
。 Django 期望 form.has_changed()
在验证表单之前可以安全调用,并且默认实现确实可以安全调用。
您已覆盖 form.has_changed()
以调用 self.clean()
,现在发生在验证表单之前。由于 form.clean()
要求验证表单,因此失败。
由于 form.full_clean()
实际上调用了 self.has_changed()
,您不能简单地从 form.has_changed()
中验证表单。您没有在 has_changed()
中显示您的操作,但将此代码放在其他地方很可能是个好主意。