重写子/继承表单中父django表单的clean()方法
我真的很难弄明白这一点。最根本的问题是,我需要以某种方式为password字段设置初始值,或者覆盖方法validate_成员的调用方式 我有一个表格,当会员需要直接向系统注册时,它被称为:重写子/继承表单中父django表单的clean()方法,django,Django,我真的很难弄明白这一点。最根本的问题是,我需要以某种方式为password字段设置初始值,或者覆盖方法validate_成员的调用方式 我有一个表格,当会员需要直接向系统注册时,它被称为: class NewMemberForm(forms.Form): ''' Called when user wants to register with our system from web/mobile. Ask password here ''' firstName=
class NewMemberForm(forms.Form):
'''
Called when user wants to register with our system from web/mobile. Ask password here
'''
firstName=forms.CharField(max_length=25,required=True,widget=forms.TextInput())
lastName=forms.CharField(max_length=25,required=True,widget=forms.TextInput())
birthdate=forms.DateField(required=True)
gender=forms.ChoiceField(choices=Profile.GENDER,required=True)
idnumber=forms.CharField(required=False,max_length=25)
phone=forms.IntegerField(required=True)
email=forms.EmailField(required=True)
password=forms.CharField(max_length=16,widget=forms.PasswordInput())
memberType=forms.ChoiceField(choices=Profile.TYPE_OF_MEMBER,widget=forms.Select())
maritalStatus=forms.ChoiceField(choices=Profile.MARITAL_STATUS,widget=forms.Select())
def clean(self):
'''
Grouped cleaning
'''
self.cleaned_data=super(NewMemberForm,self).clean()
validate_member_form=validate_member(self.cleaned_data,False)
#do we have error messages now?
if len(validate_member_form[0])>0: #yes we have error messages
raise forms.ValidationError(_(validate_member_form[0]),code='invalid')
return validate_member_form[1]
validate_member函数在编辑和添加信息时使用,因此清洁了clean()以保持干燥。现在,我有另一个场景,其中一个成员可以由另一个成员注册(具有一些权限)。在这种情况下,在名为role的表单中添加一个新字段时,不需要password和membertype字段;所以我决定继承表格:
class MemberAddForm(NewMemberForm):
#memberType=forms.CharField(initial='Individual',required=False,widget=forms.Select()) #iignored: here to simple override the Required declaraton in memberform
#password=forms.CharField(max_length=16,widget=forms.PasswordInput(),required=False,initial='111111') #note pwd is ignored during saving and a new is generated
role=forms.ModelChoiceField(widget=forms.Select(),required=True,queryset=Activity.objects.filter(active='Active').only('id','name'),empty_label=None)
def __init__(self,*args,**kwargs):
super(MemberAddForm,self).__init__(*args,**kwargs)
self.fields['password'].initial='123456' #note this is meangingless and in place to pass validate_member
self.fields['password'].required=False
self.fields['memberType'].initial='Individual'
self.fields['memberType'].required=False
def clean(self):
'''
This is not been used at all.
'''
self.cleaned_data=super(MemberAddForm,self).clean()
self.cleaned_data['password']='!983.kIl'
#validate_member_form=validate_member(self.cleaned_data,False,False)
#do we have error messages now?
if len(validate_member_form[0])>0: #yes we have error messages
raise forms.ValidationError(_(validate_member_form[0]),code='invalid')
现在,我注意到子类中的clean()方法被完全忽略,验证只由parent.clean()处理。我真的需要在validate_成员方法中将第三个参数作为False传递(在父类中为True)。validate_成员检查密码复杂性和其他内容。设置required=False有一定帮助,因为不再显示“此字段为required”错误;但是,密码仍然处于检查状态。如您所见,我将密码设置为通过密码设置的初始值,但无论我做什么,仍然会出现错误。子类中的这一行导致调用父类的
clean
方法:
self.cleaned_data=super(MemberAddForm,self).clean()
由于两者几乎相同,看起来孩子的一个没有被调用,也就是说,如果父母的clean
成功通过,孩子的一个也会被调用
您的问题的解决方案是将paren的clean
方法修改为:
def clean(self, validate_member=True):
'''
Grouped cleaning
'''
self.cleaned_data=super(NewMemberForm,self).clean()
if validate_member:
validate_member_form=validate_member(self.cleaned_data, False)
# Do we have error messages now?
if len(validate_member_form[0]) > 0: # yes we have error messages
raise forms.ValidationError(_(validate_member_form[0]), code='invalid')
return validate_member_form[1]
然后,在child的clean
方法中,您需要做的就是:
def clean(self):
return super(NewMemberForm,self).clean(validate_member=False)
还有另一种选择
# dynamic form creation
class CreateUpdateView(FormView):
template_name = 'apps/frontend/create_update_view.j2'
def get_form_class(self):
# url like: /user/(?P<mode>[^/]+)/ - /user/register/ or /user/update/
is_password_required = self.kwargs.get('mode') == 'register'
class _Form(forms.Form):
if is_password_required:
password = forms.CharField(widget=forms.PasswordInput)
first_name = forms.CharField(max_length=25, required=True)
return _Form
#动态表单创建
类CreateUpdateView(FormView):
template_name='apps/frontend/create_update_view.j2'
def get_form_类(自我):
#url类似于:/user/(?P[^/]+)/-/user/register/或/user/update/
是否需要密码=self.kwargs.get('mode')='register'
班级表格(表格.表格):
如果需要密码:
password=forms.CharField(widget=forms.PasswordInput)
first_name=forms.CharField(最大长度=25,必需=True)
报税表
它确实有效,但我认为Domen的解决方案更容易合并到我当前运行的应用程序中。感谢Vadimchin提供了我根本没有想到的替代解决方案。很抱歉,我错误地将您的评论标记为答案。但我不确定clean()方法是否接受参数?或者它是完全干净的,不干净。请让我试试。可以定义额外的参数(即在父函数clean
函数中),只需确保设置默认值,这样就可以用标准的Django方式调用它们。