django - 在 Pycharm 中调试表单验证

标签 django django-forms pycharm

我正在尝试使用 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/

相关文章:

python - : import Boto 3

python - Django 规则重用谓词

python - 参数 Django 中的斜杠

python - 如何将两个相似的 View 组合成一个响应?

django - 错误 'NoneType' 对象没有属性 '__dict__'

python - PyCharm:如何在多线程代码中使用断点?

javascript - 在 Django 中将页面下载为 JSON

django - 赋值前引用的局部变量 'context'

django - 将多个模型添加到 inlineformset_factory

intellij-idea - 如何将 IntelliJ/Pycharm 设置置于版本控制之下?