在Pycharm中调试表单验证 [英] Debugging form validation in Pycharm
问题描述
我也试图设置几个断点,例如在BaseForm类的全干净的方法中,但似乎没有到达那里。
编辑:这是一些代码
我的模型&形式:
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):
如果request.method =='POST':
car_form = CarForm(request.POST,request.FILES)
如果car_form.is_valid():
...
这是一个真正的痛苦。我有两次这个问题,仍然没有找到很好的解决方案。
这是一个例子,当你覆盖窗体的 __ init __
方法。
class MyForm(forms.ModelForm):
def __init __(self,* args,** kwargs):
super(MyForm,self).__ init __(* args,** kwargs)
#禁用表单验证用于调试目的,除非
#对象被完全初始化。在此行之下设置断点。
del self._errors
#在这里编写一些其他初始化,安全调试。
...
#初始化完成。启用表单验证。
self._errors =无
如果要调试基本表单类,则修补Django代码以相同的方式。
您可以在调试后离开或删除此附加代码 - 这并没有显着差异。但是最好在今后需要这种情况下离开。
那么这里真的发生了什么?
(Django项目网站上的bugreport: https://code.djangoproject .com / ticket / 24710 )
似乎问题是Django的 BaseForm.errors
属性getter(这是一个真正的方法, @property
decorator)太多了。它调用 full_clean()
方法,该方法更改 _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调试器假设属性只是属性,它们不会对对象的内部状态进行重大更改。所以当调试 __ ini __
方法时,调试器调用错误
getter在变量窗口中显示它的值。这就打破了正常的执行流程。
(这就是为什么你应该像这样定义 get_error()
案例而不是属性)
一个可能的建议可能是避免在窗体的 __ init __ $ c中的断点和分步执行$ c>方法。但是,如果您真的需要调试它,然后修改代码,以便在逐步执行期间不存在
_errors
属性。这将阻止调用 full_clean
方法。 PyCharm调试器每次尝试访问错误
属性时会收到错误。
注意:执行暂停时,即使在 __ init __
方法之外的任何步骤都可以评估错误
属性。如果所有字段都已被完全初始化,这可能不会影响结果(请记住仅在 __ init __
方法中执行此操作)。但是,您可能会发现,您仍然无法调试表单验证过程,因为在达到 is_valid
方法调用之前,表单将显示验证。在这种情况下,在 full_clean
方法内设置断点,并且不要在表单实例化点和此断点之间停止。
I am trying to debug form validation in Django with Pycharm. Validation of my form fails at an image I upload via an ImageField and I want to find out why it's failing on it. However, whenever I try to debug the validation process and step into and through the form initialization with the POST data, it doesn't even try validating and at the end throws an error because of empty fields when trying to save the form data to the database. It is driving me nuts... how can the behavior change depending on whether I observe the individual steps or not? I also tried to set several break points, e.g. during the full-clean method of the BaseForm class, but it doesn't seem to ever get there.
Edit: Here is some code
My model & form:
class Car(models.Model):
...
image = models.ImageField(upload_to='car_images/',blank=True,null=True)
class CarForm(ModelForm):
class Meta:
model = Car
My View:
def create_car(request):
if request.method == 'POST':
car_form = CarForm(request.POST,request.FILES)
if car_form.is_valid():
...
This is a real pain. I've got this problem twice, and still have not found good solution.
This is an example of safe debugging when you override the form's __init__
method.
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
If you want to debug the base form classes then patch Django code in the same way.
You can either leave or remove this additional code after debugging - this does not make significant difference. But it's better to leave for the case you need this in the future.
So, what is really going on here?
(bugreport on Django project site: https://code.djangoproject.com/ticket/24710)
It seems the problem is that Django's BaseForm.errors
property getter (which is really a method with @property
decorator) does too much. It calls the full_clean()
method which changes the _errors
property value so that errors
getter does not do same work again on repeating calls.
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()
...
Of course PyCharm debugger assumes that properties are just properties, and they do not do critical changes to the internal state of the objects. So the debugger calls the errors
getter to show it's value in the "Variables" window when you debug the __ini__
method. And this breaks the normal execution flow.
(This is why you should define methods like get_error()
in such cases, not properties)
One possible suggestion may be to avoid breakpoints and step-by-step execution inside of the form's __init__
method. But if you really need to debug it then modify the code so that the _errors
property does not exist during the step-by-step execution. This will prevent calls to the full_clean
method. PyCharm debugger will receive error each time it will try to access the errors
property.
Note: the errors
property may be evaluated on any step when execution is paused, even outside of the __init__
method. This probably will not affect the result if all fields are fully initialized already (remember to do this in the __init__
method only). However you may find that you still can not debug the form validation process because the form appears validated before you reach the is_valid
method call. In this case set a breakpoint inside of the full_clean
method, and don't stop between the form instantiation point and this breakpoint.
这篇关于在Pycharm中调试表单验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!