Newforms MultiValueField

0 views
Skip to first unread message

Phil Powell

unread,
Feb 6, 2007, 10:04:47 AM2/6/07
to django...@googlegroups.com
Hi,

Can anyone provide any pointers on how I use MultiValueField? Can I
use it straight out of the box, or do I have to subclass to create a
new field and a new MultiValueWidget?

I thought that this code would just work:

postcode = forms.MultiValueField(fields=(forms.CharField(max_length=4),
forms.CharField(max_length=4)))

But all I ever get rendered in my template (using {{ form.postcode }})
is a single text input.

Any advice would be much appreciated.

-Phil

canen

unread,
Feb 6, 2007, 4:51:29 PM2/6/07
to Django users
Phil,

I think you must subclass it and define the compress method. See the
comments here http://code.djangoproject.com/browser/django/trunk/
django/newforms/fields.py#L412. You will also need a MultiWidget to
go with the field.

canen

unread,
Feb 6, 2007, 5:02:49 PM2/6/07
to Django users
Phil,

Thought an example might help.

class VacationBudgetField(MultiValueField):
def __init__(self, required=True, label=None, widget=None,
initial=None, f_type=(), currency=(), amount=None):
fields = (ChoiceField(choices=f_type),
ChoiceField(choices=currency), IntegerField())
widget = widget or BudgetWidget(f_type=f_type,
currency=currency, amount=amount)
super(VacationBudgetField, self).__init__(fields, required,
widget, label, initial)

def compress(self, data_list):
if data_list:
return " ".join(str(i) for i in data_list)
return None

## Where BuggetWidget is
class BudgetWidget(MultiWidget):
def __init__(self, attrs=None, f_type=(), currency=(),
amount=None):
widgets = (Select(attrs=attrs, choices=f_type),
Select(attrs=attrs, choices=currency), TextInput())
super(BudgetWidget, self).__init__(widgets, attrs)

def decompress(self, value):
if value:
return value.split(' ', 2)
return ['', '', '']

## Used it like so...
budget = VacationBudgetField(f_type=[('a', 'a'), ('b', 'b')],
currency=[('d', 'd'), ('e', 'e')])

Hope that helps.

On Feb 6, 4:51 pm, "canen" <nesta.campb...@gmail.com> wrote:
> Phil,
>
> I think you must subclass it and define the compress method. See the

> comments herehttp://code.djangoproject.com/browser/django/trunk/

Phil Powell

unread,
Feb 7, 2007, 5:26:56 AM2/7/07
to django...@googlegroups.com
Thanks for the pointers.  I soon came to realise that I did indeed need to subclass the MultValue classes, and currently have something like this:

class PostcodeField(forms.MultiValueField):
  def compress(self, data_list):
    return ''.join(data_list)

class PostcodeWidget(forms.MultiWidget):
  def __init__(self, attrs=None):
    widgets = (forms.TextInput(attrs=attrs), forms.TextInput(attrs=attrs))
    super(PostcodeWidget, self).__init__(widgets, attrs)
  def decompress(self, value):
    if value:
      return value.split('__')
    return ['', '']
  def format_output(self, rendered_widgets):
    return u''.join(rendered_widgets)

Then in the form class:

  postcode = PostcodeField(
    fields = (
      forms.CharField(max_length = 4),
      forms.CharField(max_length = 4)
    ),
    widget = PostcodeWidget
  )

Far from perfect yet, but I understand a lot more about how this code functions.

-Phil
Reply all
Reply to author
Forward
0 new messages