Se *_*orm 6 django django-forms pycharm
我正在尝试使用Pycharm在Django中调试表单验证.我通过ImageField上传的图片验证了我的表单失败,我想找出它失败的原因.但是,每当我尝试调试验证过程并使用POST数据进入表单初始化时,它甚至都不会尝试验证,并且在尝试将表单数据保存到数据库.它让我疯了......根据我是否遵守各个步骤,行为如何变化?我也尝试设置几个断点,例如在BaseForm类的完全清理方法期间,但它似乎没有达到目的.
编辑:这是一些代码
我的模特和形式:
class Car(models.Model):
...
image = models.ImageField(upload_to='car_images/',blank=True,null=True)
class CarForm(ModelForm):
class Meta:
model = Car
Run Code Online (Sandbox Code Playgroud)
我的看法:
def create_car(request):
if request.method == 'POST':
car_form = CarForm(request.POST,request.FILES)
if car_form.is_valid():
...
Run Code Online (Sandbox Code Playgroud)
这是一个真正的痛苦.我有两次这个问题,仍然没有找到好的解决方案.
这是覆盖表单__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
Run Code Online (Sandbox Code Playgroud)
如果要调试基本表单类,则以相同方式修补Django代码.
您可以在调试后保留或删除此附加代码 - 这不会产生显着差异.但是最好留下你将来需要它的情况.
那么,这里到底发生了什么?
(Django项目网站上的bug报告:https://code.djangoproject.com/ticket/24710)
似乎问题是Django的BaseForm.errors属性getter(实际上是@property装饰器的方法)做得太多了.它调用full_clean()更改_errors属性值的方法,以便errorsgetter在重复调用时不会再次执行相同的操作.
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()
...
Run Code Online (Sandbox Code Playgroud)
当然,PyCharm调试器假定属性只是属性,并且它们不会对对象的内部状态进行重要更改.因此,errors当您调试__ini__方法时,调试器会调用getter以在"Variables"窗口中显示它的值.这打破了正常的执行流程.
(这就是为什么你应该定义类似get_error()情况的方法,而不是属性)
一种可能的建议可能是避免在表单__init__方法中的断点和逐步执行.但是,如果您确实需要对其进行调试,请修改代码,以便_errors在逐步执行期间不存在该属性.这将阻止对full_clean方法的调用.PyCharm调试器每次尝试访问该errors属性时都会收到错误.
注意:errors即使在__init__方法之外,也可以在执行暂停时对任何步骤评估属性.如果所有字段都已完全初始化,这可能不会影响结果(请记住__init__仅在方法中执行此操作).但是,您可能会发现仍然无法调试表单验证过程,因为在您到达is_valid方法调用之前表单似乎已经过验证.在这种情况下,在full_clean方法内部设置断点,并且不要在表单实例化点和此断点之间停止.
| 归档时间: |
|
| 查看次数: |
775 次 |
| 最近记录: |