这是一个真正的痛苦。我遇到过两次这个问题,仍然没有找到好的解决方案。
__init__
这是当您覆盖表单的方法时安全调试的示例。
class MyForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(MyForm, self).__init__(*args, **kwargs)
# Disable form validation for debugging purposes unless the
# object is fully initialized. Set breakpoints BELOW this line.
del self._errors
# Write some additional initializations here, debug safely.
...
# Initialization is finished. Enable form validation.
self._errors = None
如果要调试基本表单类,请以相同的方式修补 Django 代码。
您可以在调试后保留或删除此附加代码 - 这没有显着差异。但最好留到将来需要这个的情况下。
那么,这里到底发生了什么?
(Django 项目网站上的错误报告:https ://code.djangoproject.com/ticket/24710 )
似乎问题在于 Django 的BaseForm.errors
属性 getter(它实际上是一个带有@property
装饰器的方法)做得太多了。它调用full_clean()
更改_errors
属性值的方法,以便errors
getter 在重复调用时不会再次执行相同的工作。
class BaseForm(object):
@property
def errors(self):
if self._errors is None:
self.full_clean()
return self._errors
def full_clean(self):
self._errors = ErrorDict()
...
当然,PyCharm 调试器假定属性只是属性,它们不会对对象的内部状态进行关键更改。因此,当您调试方法时,调试器会调用errors
getter 在“变量”窗口中显示它的值。__ini__
这打破了正常的执行流程。
(这就是为什么你应该get_error()
在这种情况下定义方法,而不是属性)
__init__
一种可能的建议可能是避免在表单方法中设置断点和逐步执行。但是,如果您确实需要调试它,请修改代码,以便_errors
在逐步执行期间不存在该属性。这将阻止对该full_clean
方法的调用。PyCharm 调试器每次尝试访问该errors
属性时都会收到错误消息。
注意:errors
可以在暂停执行时的任何步骤上评估该属性,即使在__init__
方法之外也是如此。如果所有字段都已完全初始化,这可能不会影响结果(请记住__init__
仅在方法中执行此操作)。但是,您可能会发现您仍然无法调试表单验证过程,因为在您到达is_valid
方法调用之前表单似乎已验证。在这种情况下,在full_clean
方法内部设置一个断点,并且不要在表单实例化点和这个断点之间停止。