我正在尝试使用 Pycharm 在 Django 中调试表单验证。我通过 ImageField 上传的图像验证我的表单失败,我想找出它失败的原因。但是,每当我尝试调试验证过程并使用 POST 数据进入并完成表单初始化时,它甚至不会尝试进行验证,并且在尝试将表单数据保存到数据库。它让我发疯......行为如何根据我是否观察到各个步骤而改变?
我还尝试设置几个断点,例如在 BaseForm 类的 full-clean 方法期间,但它似乎永远不会到达那里。
编辑:这是一些代码
我的型号和形式:
class Car(models.Model):
...
image = models.ImageField(upload_to='car_images/',blank=True,null=True)
class CarForm(ModelForm):
class Meta:
model = Car
我的看法:
def create_car(request):
if request.method == 'POST':
car_form = CarForm(request.POST,request.FILES)
if car_form.is_valid():
...
最佳答案
这是一个真正的痛苦。我已经两次遇到这个问题,但仍然没有找到好的解决方案。
这是当您覆盖表单的 __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
时都会收到错误消息。属性(property)。备注 :
errors
暂停执行时,可以在任何步骤上评估属性,即使在 __init__
之外方法。如果所有字段都已完全初始化,这可能不会影响结果(请记住仅在 __init__
方法中执行此操作)。但是,您可能会发现您仍然无法调试表单验证过程,因为在您到达 is_valid
之前,表单似乎已验证。方法调用。在这种情况下,在 full_clean
内设置一个断点方法,并且不要停在表单实例化点和这个断点之间。
关于django - 在 Pycharm 中调试表单验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12142819/