views:

35

answers:

0

Updated with my final solution, below.

I wrote a custom Django form widget to create a range query. It renders two input fields to define the min and max values for a query.

With well-crafted forms and widgets, fields can be filled with the values from the last query like so:

form = my_form(request.GET)

However, I cannot figure out a way to fill the values of those fields in my custom widget. Here is the widget code:

class MinMax(Widget):
    input_type = None # Subclasses must define this.

    def _format_value(self, value):
        if self.is_localized:
            return formats.localize_input(value)
        return value

    def render(self, name, value, attrs=None):
        if value is None:
            value = ''
        final_attrs = self.build_attrs(attrs, type=self.input_type, name=name)
        if value != '':
            # Only add the 'value' attribute if a value is non-empty.
            final_attrs['value'] = force_unicode(self._format_value(value))
        return mark_safe(u'<input type="text" name="min-%s" /> to 
                            <input type="text" name="max-%s" />' % (name, name) )   

Probably because of the custom input field names, the values are not accessible. Is there a way to route them, or a way to rewrite the widget to include this useful functionality? One non-widget solution I can think of is some simple jquery logic, but that's less than optimal.


Here's the code I ended up using:

class MinMax(MultiWidget):
    def __init__(self, attrs=None):
        """ pass all these parameters to their respective widget constructors..."""
        widgets = (forms.TextInput(attrs=attrs), forms.TextInput(attrs=attrs)   )
        super(MinMax, self).__init__(widgets, attrs)

    def decompress(self, value):
        return value or ''

    def value_from_datadict(self, data, files, name):
        value = ''
        for key, value in data.items():
            value += value

    def format_output(self, rendered_widgets):
        """
        Given a list of rendered widgets (as strings), it inserts stuff
        between them.

        Returns a Unicode string representing the HTML for the whole lot.
        """
        rendered_widgets.insert(-1, ' to ')
        return u''.join(rendered_widgets)

Note that these fields are returned as fieldname_0, fieldname_1 (and so on if you add additional widgets).