diff --git a/django/forms/models.py b/django/forms/models.py
index e6bbb98..1c3b606 100644
a
|
b
|
try:
|
19 | 19 | set |
20 | 20 | except NameError: |
21 | 21 | from sets import Set as set # Python 2.3 fallback |
| 22 | try: |
| 23 | sorted |
| 24 | except NameError: |
| 25 | from django.utils.itercompat import sorted |
| 26 | |
22 | 27 | |
23 | 28 | __all__ = ( |
24 | 29 | 'ModelForm', 'BaseModelForm', 'model_to_dict', 'fields_for_model', |
… |
… |
def fields_for_model(model, fields=None, exclude=None, formfield_callback=lambda
|
152 | 157 | # TODO: if fields is provided, it would be nice to return fields in that order |
153 | 158 | field_list = [] |
154 | 159 | opts = model._meta |
155 | | for f in opts.fields + opts.many_to_many: |
| 160 | for f in sorted(opts.fields + opts.many_to_many): |
156 | 161 | if not f.editable: |
157 | 162 | continue |
158 | 163 | if fields and not f.name in fields: |
diff --git a/tests/modeltests/model_forms/models.py b/tests/modeltests/model_forms/models.py
index e12363c..44eaa56 100644
a
|
b
|
familiar with the mechanics.
|
291 | 291 | OddForm is now an Article-related thing, because BadForm.Meta overrides |
292 | 292 | CategoryForm.Meta. |
293 | 293 | >>> OddForm.base_fields.keys() |
294 | | ['headline', 'slug', 'pub_date', 'writer', 'article', 'status', 'categories'] |
| 294 | ['headline', 'slug', 'pub_date', 'writer', 'article', 'categories', 'status'] |
295 | 295 | |
296 | 296 | >>> class ArticleForm(ModelForm): |
297 | 297 | ... class Meta: |
… |
… |
First class with a Meta class wins.
|
302 | 302 | >>> class BadForm(ArticleForm, CategoryForm): |
303 | 303 | ... pass |
304 | 304 | >>> OddForm.base_fields.keys() |
305 | | ['headline', 'slug', 'pub_date', 'writer', 'article', 'status', 'categories'] |
| 305 | ['headline', 'slug', 'pub_date', 'writer', 'article', 'categories', 'status'] |
306 | 306 | |
307 | 307 | Subclassing without specifying a Meta on the class will use the parent's Meta |
308 | 308 | (or the first parent in the MRO if there are multiple parent classes). |
… |
… |
fields with the 'choices' attribute are represented by a ChoiceField.
|
453 | 453 | <option value="2">Bob Woodward</option> |
454 | 454 | </select></td></tr> |
455 | 455 | <tr><th>Article:</th><td><textarea rows="10" cols="40" name="article"></textarea></td></tr> |
| 456 | <tr><th>Categories:</th><td><select multiple="multiple" name="categories"> |
| 457 | <option value="1">Entertainment</option> |
| 458 | <option value="2">It's a test</option> |
| 459 | <option value="3">Third test</option> |
| 460 | </select><br /> Hold down "Control", or "Command" on a Mac, to select more than one.</td></tr> |
456 | 461 | <tr><th>Status:</th><td><select name="status"> |
457 | 462 | <option value="" selected="selected">---------</option> |
458 | 463 | <option value="1">Draft</option> |
459 | 464 | <option value="2">Pending</option> |
460 | 465 | <option value="3">Live</option> |
461 | 466 | </select></td></tr> |
462 | | <tr><th>Categories:</th><td><select multiple="multiple" name="categories"> |
463 | | <option value="1">Entertainment</option> |
464 | | <option value="2">It's a test</option> |
465 | | <option value="3">Third test</option> |
466 | | </select><br /> Hold down "Control", or "Command" on a Mac, to select more than one.</td></tr> |
467 | 467 | |
468 | 468 | You can restrict a form to a subset of the complete list of fields |
469 | 469 | by providing a 'fields' argument. If you try to save a |
… |
… |
inserted as 'initial' data in each Field.
|
508 | 508 | <option value="2">Bob Woodward</option> |
509 | 509 | </select></li> |
510 | 510 | <li>Article: <textarea rows="10" cols="40" name="article">Hello.</textarea></li> |
| 511 | <li>Categories: <select multiple="multiple" name="categories"> |
| 512 | <option value="1">Entertainment</option> |
| 513 | <option value="2">It's a test</option> |
| 514 | <option value="3">Third test</option> |
| 515 | </select> Hold down "Control", or "Command" on a Mac, to select more than one.</li> |
511 | 516 | <li>Status: <select name="status"> |
512 | 517 | <option value="" selected="selected">---------</option> |
513 | 518 | <option value="1">Draft</option> |
514 | 519 | <option value="2">Pending</option> |
515 | 520 | <option value="3">Live</option> |
516 | 521 | </select></li> |
517 | | <li>Categories: <select multiple="multiple" name="categories"> |
518 | | <option value="1">Entertainment</option> |
519 | | <option value="2">It's a test</option> |
520 | | <option value="3">Third test</option> |
521 | | </select> Hold down "Control", or "Command" on a Mac, to select more than one.</li> |
| 522 | |
522 | 523 | >>> f = TestArticleForm({'headline': u'Test headline', 'slug': 'test-headline', 'pub_date': u'1984-02-06', 'writer': u'1', 'article': 'Hello.'}, instance=art) |
523 | 524 | >>> f.is_valid() |
524 | 525 | True |
… |
… |
Add some categories and test the many-to-many form output.
|
569 | 570 | <option value="2">Bob Woodward</option> |
570 | 571 | </select></li> |
571 | 572 | <li>Article: <textarea rows="10" cols="40" name="article">Hello.</textarea></li> |
| 573 | <li>Categories: <select multiple="multiple" name="categories"> |
| 574 | <option value="1" selected="selected">Entertainment</option> |
| 575 | <option value="2">It's a test</option> |
| 576 | <option value="3">Third test</option> |
| 577 | </select> Hold down "Control", or "Command" on a Mac, to select more than one.</li> |
572 | 578 | <li>Status: <select name="status"> |
573 | 579 | <option value="" selected="selected">---------</option> |
574 | 580 | <option value="1">Draft</option> |
575 | 581 | <option value="2">Pending</option> |
576 | 582 | <option value="3">Live</option> |
577 | 583 | </select></li> |
578 | | <li>Categories: <select multiple="multiple" name="categories"> |
579 | | <option value="1" selected="selected">Entertainment</option> |
580 | | <option value="2">It's a test</option> |
581 | | <option value="3">Third test</option> |
582 | | </select> Hold down "Control", or "Command" on a Mac, to select more than one.</li> |
583 | 584 | |
584 | 585 | >>> f = TestArticleForm({'headline': u'New headline', 'slug': u'new-headline', 'pub_date': u'1988-01-04', |
585 | 586 | ... 'writer': u'1', 'article': u'Hello.', 'categories': [u'1', u'2']}, instance=new_art) |
… |
… |
the data in the database when the form is instantiated.
|
685 | 686 | <option value="2">Bob Woodward</option> |
686 | 687 | </select></li> |
687 | 688 | <li>Article: <textarea rows="10" cols="40" name="article"></textarea></li> |
| 689 | <li>Categories: <select multiple="multiple" name="categories"> |
| 690 | <option value="1">Entertainment</option> |
| 691 | <option value="2">It's a test</option> |
| 692 | <option value="3">Third</option> |
| 693 | </select> Hold down "Control", or "Command" on a Mac, to select more than one.</li> |
688 | 694 | <li>Status: <select name="status"> |
689 | 695 | <option value="" selected="selected">---------</option> |
690 | 696 | <option value="1">Draft</option> |
691 | 697 | <option value="2">Pending</option> |
692 | 698 | <option value="3">Live</option> |
693 | 699 | </select></li> |
694 | | <li>Categories: <select multiple="multiple" name="categories"> |
695 | | <option value="1">Entertainment</option> |
696 | | <option value="2">It's a test</option> |
697 | | <option value="3">Third</option> |
698 | | </select> Hold down "Control", or "Command" on a Mac, to select more than one.</li> |
699 | 700 | >>> Category.objects.create(name='Fourth', url='4th') |
700 | 701 | <Category: Fourth> |
701 | 702 | >>> Writer.objects.create(name='Carl Bernstein') |
… |
… |
the data in the database when the form is instantiated.
|
711 | 712 | <option value="3">Carl Bernstein</option> |
712 | 713 | </select></li> |
713 | 714 | <li>Article: <textarea rows="10" cols="40" name="article"></textarea></li> |
714 | | <li>Status: <select name="status"> |
715 | | <option value="" selected="selected">---------</option> |
716 | | <option value="1">Draft</option> |
717 | | <option value="2">Pending</option> |
718 | | <option value="3">Live</option> |
719 | | </select></li> |
720 | 715 | <li>Categories: <select multiple="multiple" name="categories"> |
721 | 716 | <option value="1">Entertainment</option> |
722 | 717 | <option value="2">It's a test</option> |
723 | 718 | <option value="3">Third</option> |
724 | 719 | <option value="4">Fourth</option> |
725 | 720 | </select> Hold down "Control", or "Command" on a Mac, to select more than one.</li> |
| 721 | <li>Status: <select name="status"> |
| 722 | <option value="" selected="selected">---------</option> |
| 723 | <option value="1">Draft</option> |
| 724 | <option value="2">Pending</option> |
| 725 | <option value="3">Live</option> |
| 726 | </select></li> |
726 | 727 | |
727 | 728 | # ModelChoiceField ############################################################ |
728 | 729 | |