How to use Django MultiWidget?

The documentation is a bit missing regarding this feature.

from django import forms class TwoInputWidget(forms.MultiWidget): """An example widget which concatenates two text inputs with a space""" def __init__(self, attrs=None): widgets = [forms.TextInput, forms.TextInput] 

I see that I need to create a widgets property with a list of other widgets, but after that it gets a little Sherlock Holmes.

Someone please explain to me how to use the MultiWidget widget?

+41
django django-widget
Aug 18 '10 at 12:07
source share
2 answers

An interesting question, and I think that perhaps I deserve more attention in the documents.

Here is an example from the question I just asked :

 class DateSelectorWidget(widgets.MultiWidget): def __init__(self, attrs=None, dt=None, mode=0): if dt is not None: self.datepos = dt else: self.datepos = date.today() # bits of python to create days, months, years # example below, the rest snipped for neatness. years = [(year, year) for year in year_digits] _widgets = ( widgets.Select(attrs=attrs, choices=days), widgets.Select(attrs=attrs, choices=months), widgets.Select(attrs=attrs, choices=years), ) super(DateSelectorWidget, self).__init__(_widgets, attrs) def decompress(self, value): if value: return [value.day, value.month, value.year] return [None, None, None] def format_output(self, rendered_widgets): return u''.join(rendered_widgets) 

What I've done?

  • subclassed django.forms.widgets.MultiWidget
  • A constructor is implemented that creates several widgets widgets.WidgetName in a tuple. This is important because the superclass uses the existence of this tuple to take care of a few things for you.
  • My output format is end-to-end, but the idea is that you can add custom html here if you want
  • I also implemented decompress because you need to - you should expect values ​​to be transferred from the database in a single value object. decompress breaks it for display in widgets. How and what you do here is up to you and up to the widget.

Things that I don’t have, but could, overriden:

  • render , this is actually responsible for rendering widgets, so you definitely need to call the superrange method if you subclass it. You can change how things are displayed immediately before rendering, by subclassing this.

Example, django markitup render method:

 def render(self, name, value, attrs=None): html = super(MarkItUpWidget, self).render(name, value, attrs) if self.auto_preview: auto_preview = "$('a[title=\"Preview\"]').trigger('mouseup');" else: auto_preview = '' html += ('<script type="text/javascript">' '(function($) { ' '$(document).ready(function() {' ' $("#%(id)s").markItUp(mySettings);' ' %(auto_preview)s ' '});' '})(jQuery);' '</script>' % {'id': attrs['id'], 'auto_preview': auto_preview }) return mark_safe(html) 
  • value_from_datadict - see my question here . value_from_datadict pulls the value associated with this widget from the data dictionary of all the data presented using this form. In the case of a multividkov representing one field, you need to restore this value from several sub-sections, namely, how the data will be sent.
  • _get_media can be useful for you if you want to get media using the django media view. By default, the widget implementation requests media; if you subclass it and use any fancy widgets, you need to call super; if your widget needs any media, you need to add it using this.

For example, the markitup django widget does this:

 def _media(self): return forms.Media( css= {'screen': (posixpath.join(self.miu_skin, 'style.css'), posixpath.join(self.miu_set, 'style.css'))}, js=(settings.JQUERY_URL, absolute_url('markitup/jquery.markitup.js'), posixpath.join(self.miu_set, 'set.js'))) media = property(_media) 

Again, it creates a tuple of paths to the correct location, just like my widget created a tuple of widgets in the __init__ method.

I think it covers it for important parts of the MultiWidget class. What you are trying to do depends on what you have created / which widgets you are using, so I cannot go into the details easily. However, if you want to see the base class for yourself and take a look at the comments, look at the source .

+49
Jan 11 '11 at 23:19
source share
β€” -

Read this blog post and related Django snippet . Hope this gives you some ideas.

0
Aug 18 '10 at 12:18
source share



All Articles