diff --git a/django/forms/widgets.py b/django/forms/widgets.py
index cb12586..fc80732 100644
a
|
b
|
class CheckboxInput(Widget):
|
495 | 495 | return bool(initial) != bool(data) |
496 | 496 | |
497 | 497 | class Select(Widget): |
| 498 | allow_multiple_selected = False |
| 499 | |
498 | 500 | def __init__(self, attrs=None, choices=()): |
499 | 501 | super(Select, self).__init__(attrs) |
500 | 502 | # choices can be any iterable, but we may need to render this widget |
… |
… |
class Select(Widget):
|
514 | 516 | |
515 | 517 | def render_option(self, selected_choices, option_value, option_label): |
516 | 518 | option_value = force_unicode(option_value) |
517 | | selected_html = (option_value in selected_choices) and u' selected="selected"' or '' |
| 519 | if option_value in selected_choices: |
| 520 | selected_html = u' selected="selected"' |
| 521 | if not self.allow_multiple_selected: |
| 522 | # Only allow for a single selection. |
| 523 | selected_choices.remove(option_value) |
| 524 | else: |
| 525 | selected_html = '' |
518 | 526 | return u'<option value="%s"%s>%s</option>' % ( |
519 | 527 | escape(option_value), selected_html, |
520 | 528 | conditional_escape(force_unicode(option_label))) |
… |
… |
class NullBooleanSelect(Select):
|
567 | 575 | return initial != data |
568 | 576 | |
569 | 577 | class SelectMultiple(Select): |
| 578 | allow_multiple_selected = True |
| 579 | |
570 | 580 | def render(self, name, value, attrs=None, choices=()): |
571 | 581 | if value is None: value = [] |
572 | 582 | final_attrs = self.build_attrs(attrs, name=name) |
diff --git a/tests/regressiontests/forms/widgets.py b/tests/regressiontests/forms/widgets.py
index 10483a7..785b302 100644
a
|
b
|
over multiple times without getting consumed:
|
463 | 463 | <option value="4">4</option> |
464 | 464 | </select> |
465 | 465 | |
| 466 | Only one option can be selected: |
| 467 | >>> print w.render('choices', 0, choices=(('0', 'extra'),)) |
| 468 | <select name="choices"> |
| 469 | <option value="0" selected="selected">0</option> |
| 470 | <option value="1">1</option> |
| 471 | <option value="2">2</option> |
| 472 | <option value="3">3</option> |
| 473 | <option value="4">4</option> |
| 474 | <option value="0">extra</option> |
| 475 | </select> |
| 476 | |
| 477 | Ensure that it still selects the first element next time round: |
| 478 | >>> print w.render('choices', 0, choices=(('0', 'extra'),)) |
| 479 | <select name="choices"> |
| 480 | <option value="0" selected="selected">0</option> |
| 481 | <option value="1">1</option> |
| 482 | <option value="2">2</option> |
| 483 | <option value="3">3</option> |
| 484 | <option value="4">4</option> |
| 485 | <option value="0">extra</option> |
| 486 | </select> |
| 487 | |
466 | 488 | Choices can be nested one level in order to create HTML optgroups: |
467 | 489 | >>> w.choices=(('outer1', 'Outer 1'), ('Group "1"', (('inner1', 'Inner 1'), ('inner2', 'Inner 2')))) |
468 | 490 | >>> print w.render('nestchoice', None) |
… |
… |
True
|
674 | 696 | >>> w._has_changed([1, 2], [u'1', u'3']) |
675 | 697 | True |
676 | 698 | |
| 699 | Multiple options (with the same value) can be selected: |
| 700 | >>> print w.render('choices', [1], choices=(('1', 'extra'),)) |
| 701 | <select multiple="multiple" name="choices"> |
| 702 | <option value="1" selected="selected">1</option> |
| 703 | <option value="2">2</option> |
| 704 | <option value="3">3</option> |
| 705 | <option value="1" selected="selected">extra</option> |
| 706 | </select> |
| 707 | |
677 | 708 | # Choices can be nested one level in order to create HTML optgroups: |
678 | 709 | >>> w.choices = (('outer1', 'Outer 1'), ('Group "1"', (('inner1', 'Inner 1'), ('inner2', 'Inner 2')))) |
679 | 710 | >>> print w.render('nestchoice', None) |