Ticket #4412: 4412.2.diff
File 4412.2.diff, 11.9 KB (added by , 16 years ago) |
---|
-
django/db/models/base.py
429 429 430 430 def _get_FIELD_display(self, field): 431 431 value = getattr(self, field.attname) 432 return force_unicode(dict(field.choices).get(value, value), strings_only=True) 432 flatchoices = [] 433 for choice in field.choices: 434 if type(choice[1]) in (list, tuple): 435 flatchoices.extend(choice[1]) 436 else: 437 flatchoices.append(choice) 438 return force_unicode(dict(flatchoices).get(value, value), strings_only=True) 433 439 434 440 def _get_next_or_previous_by_FIELD(self, field, is_next, **kwargs): 435 441 op = is_next and 'gt' or 'lt' -
django/db/models/fields/__init__.py
299 299 else: 300 300 field_objs = [oldforms.SelectField] 301 301 302 params['choices'] = self.get_choices_default() 302 flatchoices = [] 303 for choice in self.get_choices_default(): 304 if type(choice[1]) in (list, tuple): 305 flatchoices.extend(choice[1]) 306 else: 307 flatchoices.append(choice) 308 309 params['choices'] = flatchoices 303 310 else: 304 311 field_objs = self.get_manipulator_field_objs() 305 312 return (field_objs, params) -
django/newforms/fields.py
615 615 value = smart_unicode(value) 616 616 if value == u'': 617 617 return value 618 valid_values = set([smart_unicode(k) for k, v in self.choices]) 618 valid_values = [] 619 for k, v in self.choices: 620 if type(v) in (tuple, list): 621 valid_values.extend([k2[0] for k2 in v]) 622 else: 623 valid_values.append(k) 624 valid_values = set([smart_unicode(v) for v in valid_values]) 619 625 if value not in valid_values: 620 626 raise ValidationError(self.error_messages['invalid_choice'] % {'value': value}) 621 627 return value … … 640 646 raise ValidationError(self.error_messages['invalid_list']) 641 647 new_value = [smart_unicode(val) for val in value] 642 648 # Validate that each value in the value list is in self.choices. 643 valid_values = set([smart_unicode(k) for k, v in self.choices]) 649 valid_values = [] 650 for k, v in self.choices: 651 if type(v) in (tuple, list): 652 valid_values.extend([k2[0] for k2 in v]) 653 else: 654 valid_values.append(k) 655 valid_values = set([smart_unicode(v) for v in valid_values]) 644 656 for val in new_value: 645 657 if val not in valid_values: 646 658 raise ValidationError(self.error_messages['invalid_choice'] % {'value': val}) -
django/newforms/widgets.py
212 212 if value is None: value = '' 213 213 final_attrs = self.build_attrs(attrs, name=name) 214 214 output = [u'<select%s>' % flatatt(final_attrs)] 215 # Normalize to string. 216 str_value = force_unicode(value) 217 for option_value, option_label in chain(self.choices, choices): 218 option_value = force_unicode(option_value) 219 selected_html = (option_value == str_value) and u' selected="selected"' or '' 220 output.append(u'<option value="%s"%s>%s</option>' % ( 221 escape(option_value), selected_html, 222 conditional_escape(force_unicode(option_label)))) 223 output.append(u'</select>') 215 options = self.render_options(choices, [value]) 216 if options: 217 output.append(options) 218 output.append('</select>') 224 219 return mark_safe(u'\n'.join(output)) 225 220 221 def render_options(self, choices, selected_choices): 222 def render_option(option_value, option_label): 223 option_value = force_unicode(option_value) 224 selected_html = (option_value in selected_choices) and u' selected="selected"' or '' 225 return u'<option value="%s"%s>%s</option>' % ( 226 escape(option_value), selected_html, 227 conditional_escape(force_unicode(option_label))) 228 # Normalize to strings. 229 selected_choices = set([force_unicode(v) for v in selected_choices]) 230 output = [] 231 for option_value, option_label in chain(self.choices, choices): 232 if isinstance(option_label, (list, tuple)): 233 output.append(u'<optgroup label="%s">' % escape(force_unicode(option_value))) 234 for option in option_label: 235 output.append(render_option(*option)) 236 output.append(u'</optgroup>') 237 else: 238 output.append(render_option(option_value, option_label)) 239 return u'\n'.join(output) 240 226 241 class NullBooleanSelect(Select): 227 242 """ 228 243 A Select Widget intended to be used with NullBooleanField. … … 242 257 value = data.get(name, None) 243 258 return {u'2': True, u'3': False, True: True, False: False}.get(value, None) 244 259 245 class SelectMultiple(Widget): 246 def __init__(self, attrs=None, choices=()): 247 super(SelectMultiple, self).__init__(attrs) 248 # choices can be any iterable 249 self.choices = choices 250 260 class SelectMultiple(Select): 251 261 def render(self, name, value, attrs=None, choices=()): 252 262 if value is None: value = [] 253 263 final_attrs = self.build_attrs(attrs, name=name) 254 264 output = [u'<select multiple="multiple"%s>' % flatatt(final_attrs)] 255 str_values = set([force_unicode(v) for v in value]) # Normalize to strings. 256 for option_value, option_label in chain(self.choices, choices): 257 option_value = force_unicode(option_value) 258 selected_html = (option_value in str_values) and ' selected="selected"' or '' 259 output.append(u'<option value="%s"%s>%s</option>' % ( 260 escape(option_value), selected_html, 261 conditional_escape(force_unicode(option_label)))) 262 output.append(u'</select>') 265 options = self.render_options(choices, value) 266 if options: 267 output.append(options) 268 output.append('</select>') 263 269 return mark_safe(u'\n'.join(output)) 264 270 265 271 def value_from_datadict(self, data, files, name): -
tests/regressiontests/forms/widgets.py
419 419 <option value="4">4</option> 420 420 </select> 421 421 422 Choices can be nested one level in order to create HTML optgroups: 423 >>> w.choices=(('outer1', 'Outer 1'), ('Group "1"', (('inner1', 'Inner 1'), ('inner2', 'Inner 2')))) 424 >>> print w.render('nestchoice', None) 425 <select name="nestchoice"> 426 <option value="outer1">Outer 1</option> 427 <optgroup label="Group "1""> 428 <option value="inner1">Inner 1</option> 429 <option value="inner2">Inner 2</option> 430 </optgroup> 431 </select> 432 >>> print w.render('nestchoice', 'outer1') 433 <select name="nestchoice"> 434 <option value="outer1" selected="selected">Outer 1</option> 435 <optgroup label="Group "1""> 436 <option value="inner1">Inner 1</option> 437 <option value="inner2">Inner 2</option> 438 </optgroup> 439 </select> 440 >>> print w.render('nestchoice', 'inner1') 441 <select name="nestchoice"> 442 <option value="outer1">Outer 1</option> 443 <optgroup label="Group "1""> 444 <option value="inner1" selected="selected">Inner 1</option> 445 <option value="inner2">Inner 2</option> 446 </optgroup> 447 </select> 448 422 449 # NullBooleanSelect Widget #################################################### 423 450 424 451 >>> w = NullBooleanSelect() … … 573 600 >>> w.render('nums', ['ŠĐĆŽćžšđ'], choices=[('ŠĐĆŽćžšđ', 'ŠĐabcĆŽćžšđ'), ('ćžšđ', 'abcćžšđ')]) 574 601 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>' 575 602 603 # Choices can be nested one level in order to create HTML optgroups: 604 >>> w.choices = (('outer1', 'Outer 1'), ('Group "1"', (('inner1', 'Inner 1'), ('inner2', 'Inner 2')))) 605 >>> print w.render('nestchoice', None) 606 <select multiple="multiple" name="nestchoice"> 607 <option value="outer1">Outer 1</option> 608 <optgroup label="Group "1""> 609 <option value="inner1">Inner 1</option> 610 <option value="inner2">Inner 2</option> 611 </optgroup> 612 </select> 613 >>> print w.render('nestchoice', ['outer1']) 614 <select multiple="multiple" name="nestchoice"> 615 <option value="outer1" selected="selected">Outer 1</option> 616 <optgroup label="Group "1""> 617 <option value="inner1">Inner 1</option> 618 <option value="inner2">Inner 2</option> 619 </optgroup> 620 </select> 621 >>> print w.render('nestchoice', ['inner1']) 622 <select multiple="multiple" name="nestchoice"> 623 <option value="outer1">Outer 1</option> 624 <optgroup label="Group "1""> 625 <option value="inner1" selected="selected">Inner 1</option> 626 <option value="inner2">Inner 2</option> 627 </optgroup> 628 </select> 629 >>> print w.render('nestchoice', ['outer1', 'inner2']) 630 <select multiple="multiple" name="nestchoice"> 631 <option value="outer1" selected="selected">Outer 1</option> 632 <optgroup label="Group "1""> 633 <option value="inner1">Inner 1</option> 634 <option value="inner2" selected="selected">Inner 2</option> 635 </optgroup> 636 </select> 637 576 638 # RadioSelect Widget ########################################################## 577 639 578 640 >>> w = RadioSelect() -
docs/model-api.txt
568 568 class Foo(models.Model): 569 569 gender = models.CharField(max_length=1, choices=GENDER_CHOICES) 570 570 571 You can also collect your available choices into named groups, which will 572 be used for display purposes:: 573 574 MEDIA_CHOICES = ( 575 ('Audio', ( 576 ('vinyl', 'Vinyl'), 577 ('cd', 'CD'), 578 ) 579 ), 580 ('Video', ( 581 ('vhs', 'VHS Tape'), 582 ('dvd', 'DVD'), 583 ) 584 ), 585 ('unknown', 'Unknown'), 586 ) 587 588 The first element in each tuple is the name to apply to the group. The 589 second element is an iterable of 2-tuples, with each 2-tuple containing 590 a value and a human-readable name for an option. Grouped options may be 591 combined with ungrouped options within a single list (such as the 592 `unknown` option in this example). 593 571 594 For each model field that has ``choices`` set, Django will add a method to 572 595 retrieve the human-readable name for the field's current value. See 573 596 `get_FOO_display`_ in the database API documentation. -
docs/newforms.txt
1233 1233 * Error message keys: ``required``, ``invalid_choice`` 1234 1234 1235 1235 Takes one extra argument, ``choices``, which is an iterable (e.g., a list or 1236 tuple) of 2-tuples to use as choices for this field. 1236 tuple) of 2-tuples to use as choices for this field. This argument accepts 1237 the same formats as the ``choices`` argument to a model field. See the 1238 `model API documentation on choices`_ for more details. 1237 1239 1240 .. _model API documentation on choices: ../model-api#choices 1241 1238 1242 ``DateField`` 1239 1243 ~~~~~~~~~~~~~ 1240 1244