Changeset 4506
- Timestamp:
- 02/14/07 17:44:46 (2 years ago)
- Files:
-
- django/trunk/django/newforms/forms.py (modified) (1 diff)
- django/trunk/docs/newforms.txt (modified) (1 diff)
- django/trunk/tests/regressiontests/forms/tests.py (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
django/trunk/django/newforms/forms.py
r4504 r4506 32 32 33 33 class DeclarativeFieldsMetaclass(type): 34 "Metaclass that converts Field attributes to a dictionary called 'base_fields'." 34 """ 35 Metaclass that converts Field attributes to a dictionary called 36 'base_fields', taking into account parent class 'base_fields' as well. 37 """ 35 38 def __new__(cls, name, bases, attrs): 36 39 fields = [(field_name, attrs.pop(field_name)) for field_name, obj in attrs.items() if isinstance(obj, Field)] 37 40 fields.sort(lambda x, y: cmp(x[1].creation_counter, y[1].creation_counter)) 41 42 # If this class is subclassing another Form, add that Form's fields. 43 # Note that we loop over the bases in *reverse*. This is necessary in 44 # order to preserve the correct order of fields. 45 for base in bases[::-1]: 46 if hasattr(base, 'base_fields'): 47 fields = base.base_fields.items() + fields 48 38 49 attrs['base_fields'] = SortedDictFromList(fields) 39 50 return type.__new__(cls, name, bases, attrs) django/trunk/docs/newforms.txt
r4440 r4506 572 572 '' 573 573 574 Subclassing forms 575 ----------------- 576 577 If you subclass a custom ``Form`` class, the resulting ``Form`` class will 578 include all fields of the parent class(es), followed by the fields you define 579 in the subclass. 580 581 In this example, ``ContactFormWithPriority`` contains all the fields from 582 ``ContactForm``, plus an additional field, ``priority``. The ``ContactForm`` 583 fields are ordered first:: 584 585 >>> class ContactFormWithPriority(ContactForm): 586 ... priority = forms.CharField() 587 >>> f = ContactFormWithPriority(auto_id=False) 588 >>> print f.as_ul() 589 <li>Subject: <input type="text" name="subject" maxlength="100" /></li> 590 <li>Message: <input type="text" name="message" /></li> 591 <li>Sender: <input type="text" name="sender" /></li> 592 <li>Cc myself: <input type="checkbox" name="cc_myself" /></li> 593 <li>Priority: <input type="text" name="priority" /></li> 594 595 It's possible to subclass multiple forms, treating forms as "mix-ins." In this 596 example, ``BeatleForm`` subclasses both ``PersonForm`` and ``InstrumentForm`` 597 (in that order), and its field list includes the fields from the parent 598 classes:: 599 600 >>> class PersonForm(Form): 601 ... first_name = CharField() 602 ... last_name = CharField() 603 >>> class InstrumentForm(Form): 604 ... instrument = CharField() 605 >>> class BeatleForm(PersonForm, InstrumentForm): 606 ... haircut_type = CharField() 607 >>> b = Beatle(auto_id=False) 608 >>> print b.as_ul() 609 <li>First name: <input type="text" name="first_name" /></li> 610 <li>Last name: <input type="text" name="last_name" /></li> 611 <li>Instrument: <input type="text" name="instrument" /></li> 612 <li>Haircut type: <input type="text" name="haircut_type" /></li> 613 574 614 Fields 575 615 ====== django/trunk/tests/regressiontests/forms/tests.py
r4504 r4506 2683 2683 <li>Password: <input type="password" name="password" /><input type="hidden" name="next" value="/" /></li> 2684 2684 2685 # Subclassing forms ########################################################### 2686 2687 You can subclass a Form to add fields. The resulting form subclass will have 2688 all of the fields of the parent Form, plus whichever fields you define in the 2689 subclass. 2690 >>> class Person(Form): 2691 ... first_name = CharField() 2692 ... last_name = CharField() 2693 ... birthday = DateField() 2694 >>> class Musician(Person): 2695 ... instrument = CharField() 2696 >>> p = Person(auto_id=False) 2697 >>> print p.as_ul() 2698 <li>First name: <input type="text" name="first_name" /></li> 2699 <li>Last name: <input type="text" name="last_name" /></li> 2700 <li>Birthday: <input type="text" name="birthday" /></li> 2701 >>> m = Musician(auto_id=False) 2702 >>> print m.as_ul() 2703 <li>First name: <input type="text" name="first_name" /></li> 2704 <li>Last name: <input type="text" name="last_name" /></li> 2705 <li>Birthday: <input type="text" name="birthday" /></li> 2706 <li>Instrument: <input type="text" name="instrument" /></li> 2707 2708 Yes, you can subclass multiple forms. The fields are added in the order in 2709 which the parent classes are listed. 2710 >>> class Person(Form): 2711 ... first_name = CharField() 2712 ... last_name = CharField() 2713 ... birthday = DateField() 2714 >>> class Instrument(Form): 2715 ... instrument = CharField() 2716 >>> class Beatle(Person, Instrument): 2717 ... haircut_type = CharField() 2718 >>> b = Beatle(auto_id=False) 2719 >>> print b.as_ul() 2720 <li>First name: <input type="text" name="first_name" /></li> 2721 <li>Last name: <input type="text" name="last_name" /></li> 2722 <li>Birthday: <input type="text" name="birthday" /></li> 2723 <li>Instrument: <input type="text" name="instrument" /></li> 2724 <li>Haircut type: <input type="text" name="haircut_type" /></li> 2725 2685 2726 # Forms with prefixes ######################################################### 2686 2727
