我正在覆盖ModelForm
的保存方法,我不知道它为什么会导致递归:
@parsleyfy
class AccountForm(forms.ModelForm):
def save(self, *args, **kwargs):
# some other code...
return super(AccountForm, self).save(*args,**kwargs)
原因:
maximum recursion depth exceeded while calling a Python object
Stacktrace显示此行反复调用自己:
return super(AccountForm, self).save(*args,**kwargs)
现在,欧芹装饰师是这样的:
def parsleyfy(klass):
class ParsleyClass(klass):
# some code here to add more stuff to the class
return ParsleyClass
正如@DanielRoseman所说,扩展AccountForm
的Parsley装饰器导致super(AccountForm,self)
继续自我调用,解决方案是什么?
此外,我无法理解为什么这会导致递归。
答案 0 :(得分:6)
你能做的就是直接调用父方法:
@parsleyfy
class AccountForm(forms.ModelForm):
def save(self, *args, **kwargs):
# some other code...
return forms.ModelForm.save(self, *args,**kwargs)
这应该整齐地避免您的类装饰器引入的问题。另一种选择是在不同名称的基类上手动调用装饰器,而不是使用@
语法:
class AccountFormBase(forms.ModelForm):
def save(self, *args, **kwargs):
# some other code...
return super(AccountFormBase, self).save(*args,**kwargs)
AccountForm = parsleyfy(AccountFormBase)
但是,您可能还需要考虑使用pre-save signal,具体取决于您尝试执行的操作 - 通常会添加在Django中的其他模型保存过程之前应该发生的功能。
至于为什么正在发生这种情况,请考虑评估代码时会发生什么。
首先,声明一个类。我们将这个原始类定义称为Foo
,以区别于装饰器将创建的后一个类定义。这个类有一个save
方法,可以进行super(AccountForm, self).save(...)
调用。
然后将此类传递给装饰器,装饰器定义一个我们称之为Bar
的新类,并继承自Foo
。因此,Bar.save
相当于Foo.save
- 它也会调用super(AccountForm, self).save(...)
。然后从装饰器返回第二个类。
返回的班级(Bar
)已分配到名称AccountForm
。
因此,当您创建AccountForm
对象时,您将创建一个Bar
类型的对象。当您在其上调用.save(...)
时,它会查找Bar.save
,实际上是Foo.save
,因为它继承自Foo
并且从未被覆盖。
正如我们之前提到的,Foo.save
会调用super(AccountForm, self).save(...)
。 问题在于,由于类装饰器,AccountForm
不是Foo
,而是Bar
- 而Bar
的父级是Foo
。 强>
因此当Foo.save
查找AccountForm
的父级时,它会获得...... Foo
。这意味着当它试图在该父级上调用.save(...)
时,它实际上只是调用自身,因此无休止的递归。
答案 1 :(得分:0)
以下是我为使其工作所做的工作,我可以更改parsleyfy类来覆盖这样的save方法:
def parsleyfy(klass):
class ParsleyClass(klass):
def save(self, *args, **kwargs):
return super(klass, self).save(*args, **kwargs)
return ParsleyClass
或将AccountForm的save方法更改为:
@parsleyfy
class AccountForm(forms.ModelForm):
def save(self, *args, **kwargs):
return super(forms.ModelForm, self).save(*args,**kwargs)
我不知道有什么区别,super(Class, self)
vs super(Parent, self)
我问了这个问题question