Django

Code

Changeset 5088

Show
Ignore:
Timestamp:
04/26/07 07:46:04 (2 years ago)
Author:
russellm
Message:

Fixed #3787, #3788 -- Corrected check for IndexError? on MultiValueField?, and fixed the value_from_datadict method for MultiWidgets? to handle Multiwidgets containing Multiwidgets. Also added a testcase walking through the use of MultiWidget/MultiValueField?. Thanks to Max Derkachev for reporting these issues and providing fixes.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/trunk/django/newforms/fields.py

    r5053 r5088  
    458458            try: 
    459459                field_value = value[i] 
    460             except KeyError: 
     460            except IndexError: 
    461461                field_value = None 
    462462            if self.required and field_value in EMPTY_VALUES: 
  • django/trunk/django/newforms/widgets.py

    r5065 r5088  
    348348 
    349349    def value_from_datadict(self, data, name): 
    350         return [data.get(name + '_%s' % i) for i in range(len(self.widgets))] 
     350        return [widget.value_from_datadict(data, name + '_%s' % i) for i, widget in enumerate(self.widgets)] 
    351351 
    352352    def format_output(self, rendered_widgets): 
  • django/trunk/tests/regressiontests/forms/tests.py

    r5065 r5088  
    66>>> from django.newforms import * 
    77>>> import datetime 
     8>>> import time 
    89>>> import re 
    910 
     
    32983299</select> 
    32993300 
     3301# MultiWidget and MultiValueField ############################################# 
     3302# MultiWidgets are widgets composed of other widgets. They are usually  
     3303# combined with MultiValueFields - a field that is composed of other fields. 
     3304# MulitWidgets can themselved be composed of other MultiWidgets. 
     3305# SplitDateTimeWidget is one example of a MultiWidget. 
     3306 
     3307>>> class ComplexMultiWidget(MultiWidget): 
     3308...     def __init__(self, attrs=None): 
     3309...         widgets = ( 
     3310...             TextInput(),  
     3311...             SelectMultiple(choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))), 
     3312...             SplitDateTimeWidget(), 
     3313...         ) 
     3314...         super(ComplexMultiWidget, self).__init__(widgets, attrs) 
     3315... 
     3316...     def decompress(self, value): 
     3317...         if value: 
     3318...             data = value.split(',') 
     3319...             return [data[0], data[1], datetime.datetime(*time.strptime(data[2], "%Y-%m-%d %H:%M:%S")[0:6])] 
     3320...         return [None, None, None] 
     3321...     def format_output(self, rendered_widgets): 
     3322...         return u'\n'.join(rendered_widgets) 
     3323>>> w = ComplexMultiWidget() 
     3324>>> print w.render('name', 'some text,JP,2007-04-25 06:24:00') 
     3325<input type="text" name="name_0" value="some text" /> 
     3326<select multiple="multiple" name="name_1"> 
     3327<option value="J" selected="selected">John</option> 
     3328<option value="P" selected="selected">Paul</option> 
     3329<option value="G">George</option> 
     3330<option value="R">Ringo</option> 
     3331</select> 
     3332<input type="text" name="name_2_0" value="2007-04-25" /><input type="text" name="name_2_1" value="06:24:00" /> 
     3333 
     3334>>> class ComplexField(MultiValueField): 
     3335...     def __init__(self, required=True, widget=None, label=None, initial=None):  
     3336...         fields = ( 
     3337...             CharField(),  
     3338...             MultipleChoiceField(choices=(('J', 'John'), ('P', 'Paul'), ('G', 'George'), ('R', 'Ringo'))), 
     3339...             SplitDateTimeField() 
     3340...         ) 
     3341...         super(ComplexField, self).__init__(fields, required, widget, label, initial)  
     3342... 
     3343...     def compress(self, data_list): 
     3344...         if data_list: 
     3345...             return '%s,%s,%s' % (data_list[0],''.join(data_list[1]),data_list[2]) 
     3346...         return None 
     3347 
     3348>>> f = ComplexField(widget=w) 
     3349>>> f.clean(['some text', ['J','P'], ['2007-04-25','6:24:00']]) 
     3350u'some text,JP,2007-04-25 06:24:00' 
     3351>>> f.clean(['some text',['X'], ['2007-04-25','6:24:00']]) 
     3352Traceback (most recent call last): 
     3353... 
     3354ValidationError: [u'Select a valid choice. X is not one of the available choices.'] 
     3355 
     3356# If insufficient data is provided, None is substituted 
     3357>>> f.clean(['some text',['JP']]) 
     3358Traceback (most recent call last): 
     3359... 
     3360ValidationError: [u'This field is required.'] 
     3361 
     3362>>> class ComplexFieldForm(Form): 
     3363...     field1 = ComplexField(widget=w) 
     3364>>> f = ComplexFieldForm() 
     3365>>> print f 
     3366<tr><th><label for="id_field1_0">Field1:</label></th><td><input type="text" name="field1_0" id="id_field1_0" /> 
     3367<select multiple="multiple" name="field1_1" id="id_field1_1"> 
     3368<option value="J">John</option> 
     3369<option value="P">Paul</option> 
     3370<option value="G">George</option> 
     3371<option value="R">Ringo</option> 
     3372</select> 
     3373<input type="text" name="field1_2_0" id="id_field1_2_0" /><input type="text" name="field1_2_1" id="id_field1_2_1" /></td></tr> 
     3374 
     3375>>> f = ComplexFieldForm({'field1_0':'some text','field1_1':['J','P'], 'field1_2_0':'2007-04-25', 'field1_2_1':'06:24:00'}) 
     3376>>> print f 
     3377<tr><th><label for="id_field1_0">Field1:</label></th><td><input type="text" name="field1_0" value="some text" id="id_field1_0" /> 
     3378<select multiple="multiple" name="field1_1" id="id_field1_1"> 
     3379<option value="J" selected="selected">John</option> 
     3380<option value="P" selected="selected">Paul</option> 
     3381<option value="G">George</option> 
     3382<option value="R">Ringo</option> 
     3383</select> 
     3384<input type="text" name="field1_2_0" value="2007-04-25" id="id_field1_2_0" /><input type="text" name="field1_2_1" value="06:24:00" id="id_field1_2_1" /></td></tr> 
     3385 
     3386>>> f.clean_data 
     3387{'field1': u'some text,JP,2007-04-25 06:24:00'} 
     3388 
    33003389################################# 
    33013390# Tests of underlying functions #