how to work with modelform and multiwidget

672 views Asked by At

Newbie to all this! i'm working on displaying phone field displayed as (xxx)xxx-xxxx on front end.below is my code. My question is 1. all fields are mandatory, for some reason,phone is not behaving as expected.Even if it is left blank its not complaining and 2.how can i test this widget's functionality

class USPhoneNumberWidget(forms.MultiWidget):
        def __init__(self,attrs=None):
            widgets = (forms.TextInput(attrs={'size':'3','maxlength':'3'}),forms.TextInput(attrs={'size':'3','maxlength':'3'}),forms.TextInput(attrs={'size':'3','maxlength':'4'}))
            super(USPhoneNumberWidget,self).__init__(widgets,attrs=attrs)

        def decompress(self, value):
            if value:
                val = value.split('-')
                return [val[0],val[1],val[2]]
            return [None,None,None]

        def compress(self, data_list):
            if data_list[0] and data_list[1] and data_list[2]:
                ph1 = self.check_value(data_list[0])
                ph2 = self.check_value(data_list[1])
                ph3 = self.check_value(data_list[2])
                return '%s''%s''%s' %(ph1,ph2,ph3)
            else:
                return None

        def check_value(self,val):
            try:
                if val.isdigit():
                    return val
            except:
                raise forms.ValidationError('This Field has to be a number!')

        def clean(self, value):
            try:
                value = re.sub('(\(|\)|\s+)','',smart_unicode(value))
                m = phone_digits_re.search(value)
                if m:
                    return u'%s%s%s' % (m.group(1),m.group(2),m.group(3))
            except:
                raise ValidationError('Phone Number is required.')

        def value_from_datadict(self,data,files,name):
            val_list = [widget.value_from_datadict(data,files,name+'_%s' %i) for i,widget in enumerate(self.widgets)]
            try:
                return val_list
            except ValueError:
                return ''

        def format_output(self,rendered_widgets):
            return '('+rendered_widgets[0]+')'+rendered_widgets[1]+'-'+rendered_widgets[2]

    class CustomerForm(ModelForm):
    phone = forms.CharField(required=True,widget=USPhoneNumberWidget())
       class Meta:
            model = Customer
            fields = ('fname','lname','address1','address2','city','state','zipcode','phone')

In models blank and null are not true. Any input it highly appreciated.Thanks

1

There are 1 answers

0
stackover On

Here is the phone field:

phone = forms.CharField(label = 'Phone',widget=USPhoneNumberWidget() 
class USPhoneNumberWidget(forms.MultiWidget):
        """
        A widget that splits phone number into areacode/next3/last4 with textinput.
        """
        def __init__(self,attrs=None):
        widgets = (forms.TextInput(attrs={'size':'3','maxlength':'3'}),forms.TextInput(attrs={'size':'3','maxlength':'3'}),forms.TextInput(attrs={'size':'4','maxlength':'4'}))
        super(USPhoneNumberWidget,self).__init__(widgets,attrs=attrs)

    def decompress(self, value):
        if value:
            val = value
            return val[:3],val[3:6],val[6:]
        return None,None,None

    def compress(self, data_list):
        if data_list[0] and data_list[1] and data_list[2]:
            return '%s''%s''%s' %(data_list[0],data_list[1],data_list[2])
        else:
            return None

    def value_from_datadict(self,data,files,name):
        val_list = [widget.value_from_datadict(data,files,name+'_%s' %i) for i,widget in enumerate(self.widgets)]
        if val_list:
            return '%s''%s''%s' %(val_list[0],val_list[1],val_list[2])

    def format_output(self,rendered_widgets):
        return '( '+rendered_widgets[0]+' )'+rendered_widgets[1]+' - '+rendered_widgets[2]

But depending on how you store the phone# in db 'return' line is to be changed. here I'm accepting it as (xxx)-xxx-xxxx format.In compress it receives ph_0(areacode),ph_1(next 3),ph_2(last4) in that order.but I'm storing it as xxxxxxxxxx.

Firebug helped me understand better about what return values should be. I'll update the answer when i come to know how testing could be done.