Ticket #4412: 4412-r6025.diff
File 4412-r6025.diff, 10.7 KB (added by , 17 years ago) |
---|
-
django/db/models/base.py
324 324 325 325 def _get_FIELD_display(self, field): 326 326 value = getattr(self, field.attname) 327 return force_unicode(dict(field.choices).get(value, value), strings_only=True) 327 flatchoices = [] 328 for choice in field.choices: 329 if type(choice[1]) in (list, tuple): 330 flatchoices.extend(choice[1]) 331 else: 332 flatchoices.append(choice) 333 return force_unicode(dict(flatchoices).get(value, value), strings_only=True) 328 334 329 335 def _get_next_or_previous_by_FIELD(self, field, is_next, **kwargs): 330 336 qn = connection.ops.quote_name -
django/newforms/fields.py
473 473 value = smart_unicode(value) 474 474 if value == u'': 475 475 return value 476 valid_values = set([smart_unicode(k) for k, v in self.choices]) 476 valid_values = [] 477 for k, v in self.choices: 478 if type(v) in (tuple, list): 479 valid_values.extend([k2[0] for k2 in v]) 480 else: 481 valid_values.append(k) 482 valid_values = set([smart_unicode(v) for v in valid_values]) 477 483 if value not in valid_values: 478 484 raise ValidationError(ugettext(u'Select a valid choice. That choice is not one of the available choices.')) 479 485 return value … … 494 500 raise ValidationError(ugettext(u'Enter a list of values.')) 495 501 new_value = [smart_unicode(val) for val in value] 496 502 # Validate that each value in the value list is in self.choices. 497 valid_values = set([smart_unicode(k) for k, v in self.choices]) 503 valid_values = [] 504 for k, v in self.choices: 505 if type(v) in (tuple, list): 506 valid_values.extend([k2[0] for k2 in v]) 507 else: 508 valid_values.append(k) 509 valid_values = set([smart_unicode(v) for v in valid_values]) 498 510 for val in new_value: 499 511 if val not in valid_values: 500 512 raise ValidationError(ugettext(u'Select a valid choice. %s is not one of the available choices.') % val) -
django/newforms/widgets.py
174 174 output = [u'<select%s>' % flatatt(final_attrs)] 175 175 str_value = force_unicode(value) # Normalize to string. 176 176 for option_value, option_label in chain(self.choices, choices): 177 option_value = force_unicode(option_value) 178 selected_html = (option_value == str_value) and u' selected="selected"' or '' 179 output.append(u'<option value="%s"%s>%s</option>' % (escape(option_value), selected_html, escape(force_unicode(option_label)))) 177 if type(option_label) in (list, tuple): 178 output.append(u'<optgroup label="%s">' % escape(force_unicode(option_value))) 179 for group_option_value, group_option_label in option_label: 180 group_option_value = force_unicode(group_option_value) 181 selected_html = (group_option_value == str_value) and u' selected="selected"' or '' 182 output.append(u'<option value="%s"%s>%s</option>' % (escape(group_option_value), selected_html, escape(force_unicode(group_option_label)))) 183 output.append(u'</optgroup>') 184 else: 185 option_value = force_unicode(option_value) 186 selected_html = (option_value == str_value) and u' selected="selected"' or '' 187 output.append(u'<option value="%s"%s>%s</option>' % (escape(option_value), selected_html, escape(force_unicode(option_label)))) 180 188 output.append(u'</select>') 181 189 return u'\n'.join(output) 182 190 … … 211 219 output = [u'<select multiple="multiple"%s>' % flatatt(final_attrs)] 212 220 str_values = set([force_unicode(v) for v in value]) # Normalize to strings. 213 221 for option_value, option_label in chain(self.choices, choices): 214 option_value = force_unicode(option_value) 215 selected_html = (option_value in str_values) and ' selected="selected"' or '' 216 output.append(u'<option value="%s"%s>%s</option>' % (escape(option_value), selected_html, escape(force_unicode(option_label)))) 222 if type(option_label) in (list, tuple): 223 output.append(u'<optgroup label="%s">' % escape(force_unicode(option_value))) 224 for group_option_value, group_option_label in option_label: 225 group_option_value = force_unicode(group_option_value) 226 selected_html = (group_option_value in str_values) and u' selected="selected"' or '' 227 output.append(u'<option value="%s"%s>%s</option>' % (escape(group_option_value), selected_html, escape(force_unicode(group_option_label)))) 228 output.append(u'</optgroup>') 229 else: 230 option_value = force_unicode(option_value) 231 selected_html = (option_value in str_values) and u' selected="selected"' or '' 232 output.append(u'<option value="%s"%s>%s</option>' % (escape(option_value), selected_html, escape(force_unicode(option_label)))) 217 233 output.append(u'</select>') 218 234 return u'\n'.join(output) 219 235 -
tests/regressiontests/forms/tests.py
395 395 <option value="4">4</option> 396 396 </select> 397 397 398 Choices can be nested one level in order to create HTML optgroups: 399 >>> w = Select(choices=(('outer1', 'Outer 1'), ('Group 1', (('inner1', 'Inner 1'), ('inner2', 'Inner 2'))))) 400 >>> print w.render('nestchoice', None) 401 <select name="nestchoice"> 402 <option value="outer1">Outer 1</option> 403 <optgroup label="Group 1"> 404 <option value="inner1">Inner 1</option> 405 <option value="inner2">Inner 2</option> 406 </optgroup> 407 </select> 408 >>> print w.render('nestchoice', 'outer1') 409 <select name="nestchoice"> 410 <option value="outer1" selected="selected">Outer 1</option> 411 <optgroup label="Group 1"> 412 <option value="inner1">Inner 1</option> 413 <option value="inner2">Inner 2</option> 414 </optgroup> 415 </select> 416 >>> print w.render('nestchoice', 'inner1') 417 <select name="nestchoice"> 418 <option value="outer1">Outer 1</option> 419 <optgroup label="Group 1"> 420 <option value="inner1" selected="selected">Inner 1</option> 421 <option value="inner2">Inner 2</option> 422 </optgroup> 423 </select> 424 398 425 # NullBooleanSelect Widget #################################################### 399 426 400 427 >>> w = NullBooleanSelect() … … 536 563 >>> w.render('nums', ['ŠĐĆŽćžšđ'], choices=[('ŠĐĆŽćžšđ', 'ŠĐabcĆŽćžšđ'), ('ćžšđ', 'abcćžšđ')]) 537 564 u'<select multiple="multiple" name="nums">\n<option value="1">1</option>\n<option value="2">2</option>\n<option value="3">3</option>\n<option value="\u0160\u0110\u0106\u017d\u0107\u017e\u0161\u0111" selected="selected">\u0160\u0110abc\u0106\u017d\u0107\u017e\u0161\u0111</option>\n<option value="\u0107\u017e\u0161\u0111">abc\u0107\u017e\u0161\u0111</option>\n</select>' 538 565 566 Choices can be nested one level in order to create HTML optgroups: 567 >>> w = SelectMultiple(choices=(('outer1', 'Outer 1'), ('Group 1', (('inner1', 'Inner 1'), ('inner2', 'Inner 2'))))) 568 >>> print w.render('nestchoice', None) 569 <select multiple="multiple" name="nestchoice"> 570 <option value="outer1">Outer 1</option> 571 <optgroup label="Group 1"> 572 <option value="inner1">Inner 1</option> 573 <option value="inner2">Inner 2</option> 574 </optgroup> 575 </select> 576 >>> print w.render('nestchoice', ['outer1']) 577 <select multiple="multiple" name="nestchoice"> 578 <option value="outer1" selected="selected">Outer 1</option> 579 <optgroup label="Group 1"> 580 <option value="inner1">Inner 1</option> 581 <option value="inner2">Inner 2</option> 582 </optgroup> 583 </select> 584 >>> print w.render('nestchoice', ['inner1']) 585 <select multiple="multiple" name="nestchoice"> 586 <option value="outer1">Outer 1</option> 587 <optgroup label="Group 1"> 588 <option value="inner1" selected="selected">Inner 1</option> 589 <option value="inner2">Inner 2</option> 590 </optgroup> 591 </select> 592 >>> print w.render('nestchoice', ['outer1', 'inner2']) 593 <select multiple="multiple" name="nestchoice"> 594 <option value="outer1" selected="selected">Outer 1</option> 595 <optgroup label="Group 1"> 596 <option value="inner1">Inner 1</option> 597 <option value="inner2" selected="selected">Inner 2</option> 598 </optgroup> 599 </select> 600 539 601 # RadioSelect Widget ########################################################## 540 602 541 603 >>> w = RadioSelect() -
docs/newforms.txt
1083 1083 * Validates that the given value exists in the list of choices. 1084 1084 1085 1085 Takes one extra argument, ``choices``, which is an iterable (e.g., a list or 1086 tuple) of 2-tuples to use as choices for this field. 1086 tuple) of 2-tuples to use as choices for this field. This argument accepts 1087 the same formats as the ``choices`` argument to a model field. See the 1088 `model API documentation on choices`_ for more details. 1087 1089 1090 .. _model API documentation on choices: ../model-api#choices 1091 1088 1092 ``DateField`` 1089 1093 ~~~~~~~~~~~~~ 1090 1094 -
docs/model-api.txt
552 552 class Foo(models.Model): 553 553 gender = models.CharField(max_length=1, choices=GENDER_CHOICES) 554 554 555 You can also collect your available choices into named groups, which will 556 be used for display purposes:: 557 558 MEDIA_CHOICES = ( 559 ('Audio', ( 560 ('vinyl', 'Vinyl'), 561 ('cd', 'CD'), 562 ) 563 ), 564 ('Video', ( 565 ('vhs', 'VHS Tape'), 566 ('dvd', 'DVD'), 567 ) 568 ), 569 ('unknown', 'Unknown'), 570 ) 571 572 The first element in each tuple is the name to apply to the group. The 573 second element is an iterable of 2-tuples, with each 2-tuple containing 574 a value and a human-readable name for an option. Grouped options may be 575 combined with ungrouped options within a single list (such as the 576 `unknown` option in this example). 577 555 578 For each model field that has ``choices`` set, Django will add a method to 556 579 retrieve the human-readable name for the field's current value. See 557 580 `get_FOO_display`_ in the database API documentation.