kq1d5a
Last Updated: July 08, 2019
·
19.54K
· mdomans

Handling multiple input values for single Django form field

Imagine this scenario: you are to write a form that handles customer address, with a field for phone number, including area code.

from django import forms

class PhoneForm(forms.Form):
    # very basic
    number = forms.CharField()
    area_code = forms.CharField()

Seems easy? What if you have to write HTML with two inputs, one for phone number and one for area code, but in the database there's only one field, for a phone number with area code?

First answer would be to handle this in the clean method, like so:

class PhoneForm(forms.ModelForm):
    number = forms.CharField()
    area_code = forms.CharField()

    def clean(self):
        number = self.cleaned_data['number']
        code = self.cleaned_data['area_code']
        self.cleaned_data['full_number'] = code + number

But this is: a) nasty b) inextensible. You can't simply reuse any of that code and you keep action not directly cleaning anything in the clean method.

But, there's a better way - enter the Django MultiValueField

To use it effectively we need to subclass MultiValueField and MultiWidget. You then set the widget subclass as the field subclass widget, so that you can handle both data manipulation and display.

Final thing to remember is that you need to implement compress and decompress methods for field and widget respectively. This is because the field has to return a single value and is given a single, no matter how many inputs you actually display or how much data is submitted.

E.g.

class PhoneNumberWidget(forms.MultiWidget):
    def __init__(self, *args, **kwargs):
        super(PhoneNumberWidget, self).__init__(*args, **kwargs)
        self.widgets = [
            forms.TextInput(),
            forms.TextInput()
        ]
    def decompress(self, value):
        if value:
            return value.split(' ')
        return [None, None]

class PhoneNumberField(forms.MultiValueField):
    widget = PhoneNumberWidget

    def __init__(self, *args, **kwargs):
        super(PhoneNumberField, self).__init__(*args, **kwargs)
        fields = (
            forms.CharField(),
            forms.CharField()
        )

    def compress(self, data_list):
        return ' '.join(data_list)


class PhoneForm(forms.ModelForm):
    phone_number = PhoneNumberField()

    def __init__(self, *args, **kwargs):
        super(PhoneForm, self).__init__(self, *args, **kwargs)
        self.initial['phone_number'] = ['+1','11111111']

This is a bit more code, but it lets you nicely wrap business logic with code. If you need a field to handle a phone number with area code this way anywhere else, you can just import the field instead of using the copy-paste method.

2 Responses
Add your response

33807

Looking at the mixer on the pc or have a stand alone mixer, they're all designed to try to to a similar issue. the primary time you checked out a mixer you will have felt each happiness and confusion. Here i'll take the confusion out and leave you pushing buttons and moving sliders with additional confidence.An important piece of the puzzle is knowing however and wherever signal flows in your console, having the ability to Imagine associate invisible signal that you simply will trace along with your finger over your inter mixture console can place you ahead. associate input strip is that the 1st a part of a inter mixture console and once you perceive one strip you'll sit with confidence behind a forty two track console. This space is ampere as a result of signal coming back from a mike is low.

Regards,
https://essayservices.org/

about 1 month ago ·
34310

It's looking trouble in the code I have shared below;
class PhoneNumberWidget(forms.MultiWidget):
def init(self, args, *kwargs):
super(PhoneNumberWidget, self).init(args, *kwargs)
self.widgets = [
forms.TextInput(),
forms.TextInput()
]
def decompress(self, value):
if value:
return value.split(' ')
return [None, None]
I have done work for the web design agency and have an year of experience. You can visit the below shared website I have done work on.
https://www.webexperts.pk/

25 days ago ·