以子/继承形式覆盖Parent django表单的clean()方法

时间:2017-06-18 06:52:24

标签: django

我真的很难搞清楚这一点。最根本的问题是我需要以某种方式设置密码字段的初始值或覆盖方法validate_member的调用方式。

我有这个表单,当成员需要直接注册到系统时调用:

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()以保持DRY。现在,我有另一个场景,其中一个成员可以由另一个成员注册(具有一些权利)。在这种情况下,不需要密码和membertype字段,并在名为role的表单中添加一个新字段;所以我决定继承这个表格:

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_member方法中将第三个参数传递为False(在Parent类中为True)。 validate_member检查密码复杂性和内容。设置required = False有一定帮助,因为'这个字段是必需的'错误不再显示;但是,密码仍然是复杂的检查。如您所见,我将密码设置为通过密码设置的初始值,但无论我做什么,我仍然会收到错误。

2 个答案:

答案 0 :(得分:1)

还有另一种选择

# 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

答案 1 :(得分:0)

子类中的这一行导致父类的clean方法被调用:

self.cleaned_data=super(MemberAddForm,self).clean()

由于两者几乎相同,看起来孩子的一个人没有被召唤,即如果父母的clean成功通过,孩子的那个也会成功。< / p>

解决您的问题的方法是将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]

然后您在孩子的clean方法中所要做的就是:

def clean(self):
    return super(NewMemberForm,self).clean(validate_member=False)