| | 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']]) |
|---|
| | 3350 | u'some text,JP,2007-04-25 06:24:00' |
|---|
| | 3351 | >>> f.clean(['some text',['X'], ['2007-04-25','6:24:00']]) |
|---|
| | 3352 | Traceback (most recent call last): |
|---|
| | 3353 | ... |
|---|
| | 3354 | ValidationError: [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']]) |
|---|
| | 3358 | Traceback (most recent call last): |
|---|
| | 3359 | ... |
|---|
| | 3360 | ValidationError: [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 | |
|---|