Django

Code

Changeset 5867

Show
Ignore:
Timestamp:
08/12/07 01:25:05 (1 year ago)
Author:
russellm
Message:

Added documentation for widgets in newforms.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/trunk/docs/newforms.txt

    r5855 r5867  
    963963 
    964964The ``widget`` argument lets you specify a ``Widget`` class to use when 
    965 rendering this ``Field``. See "Widgets" below for more information. 
     965rendering this ``Field``. See "Widgets"_ below for more information. 
    966966 
    967967``help_text`` 
     
    14381438        cc_myself = forms.BooleanField() 
    14391439 
     1440Widgets 
     1441======= 
     1442 
     1443A widget is Django's representation of a HTML input element. The widget 
     1444handles the rendering of the HTML, and the extraction of data from a GET/POST 
     1445dictionary that corresponds to the widget. 
     1446 
     1447Django provides a representation of all the basic HTML widgets, plus some 
     1448commonly used groups of widgets: 
     1449 
     1450    ============================  =========================================== 
     1451    Widget                        HTML Equivalent 
     1452    ============================  =========================================== 
     1453    ``TextInput``                 ``<input type='text' ...`` 
     1454    ``PasswordInput``             ``<input type='password' ...`` 
     1455    ``HiddenInput``               ``<input type='hidden' ...`` 
     1456    ``MultipleHiddenInput``       Multiple ``<input type='hidden' ...`` 
     1457                                  instances. 
     1458    ``FileInput``                 ``<input type='file' ...`` 
     1459    ``Textarea``                  ``<textarea>...</textarea>`` 
     1460    ``CheckboxInput``             ``<input type='checkbox' ...`` 
     1461    ``Select``                    ``<select><option ...`` 
     1462    ``NullBooleanSelect``         Select widget with options 'Unknown',  
     1463                                  'Yes' and 'No' 
     1464    ``SelectMultiple``            ``<select multiple='multiple'><option ...`` 
     1465    ``RadioSelect``               ``<ul><li><input type='radio' ...``  
     1466    ``CheckboxSelectMultiple``    ``<ul><li><input type='checkbox' ...`` 
     1467    ``MultiWidget``               Wrapper around multiple other widgets 
     1468    ``SplitDateTimeWidget``       Wrapper around two ``TextInput`` widgets: 
     1469                                  one for the Date, and one for the Time. 
     1470    ============================  =========================================== 
     1471 
     1472Specifying widgets 
     1473------------------ 
     1474 
     1475Whenever you specify a field on a form, Django will use a default widget 
     1476that is appropriate to the type of data that is to be displayed. To find  
     1477which widget is used on which field, see the documentation for the 
     1478built-in Field classes. 
     1479 
     1480However, if you want to use a different widget for a field, you can -  
     1481just use the 'widget' argument on the field definition. For example:: 
     1482 
     1483    class CommentForm(forms.Form): 
     1484        name = forms.CharField() 
     1485        url = forms.URLField() 
     1486        comment = forms.CharField(widget=forms.TextArea) 
     1487         
     1488This would specify a form with a comment that uses a larger TextArea widget,  
     1489rather than the default TextInput widget. 
     1490 
     1491Customizing widget instances 
     1492---------------------------- 
     1493 
     1494When Django renders a widget as HTML, it only renders the bare minimum 
     1495HTML - Django doesn't add a class definition, or any other widget-specific 
     1496attributes. This means that all 'TextInput' widgets will appear the same 
     1497on your web page. 
     1498 
     1499If you want to make one widget look different to another, you need to  
     1500specify additional attributes for each widget. When you specify a  
     1501widget, you can provide a list of attributes that will be added to the 
     1502rendered HTML for the widget. 
     1503 
     1504For example, take the following simple form:: 
     1505 
     1506    class CommentForm(forms.Form): 
     1507        name = forms.CharField() 
     1508        url = forms.URLField() 
     1509        comment = forms.CharField() 
     1510 
     1511This form will include three default TextInput widgets, with default rendering - 
     1512no CSS class, no extra attributes. This means that the inputs boxes provided for 
     1513each widget will be rendered exactly the same:: 
     1514 
     1515    >>> f = CommentForm(auto_id=False) 
     1516    >>> f.as_table() 
     1517    <tr><th>Name:</th><td><input type="text" name="name" /></td></tr> 
     1518    <tr><th>Url:</th><td><input type="text" name="url"/></td></tr> 
     1519    <tr><th>Comment:</th><td><input type="text" name="comment" /></td></tr> 
     1520 
     1521On a real web page, you probably don't want every widget to look the same. You 
     1522might want a larger input element for the comment, and you might want the  
     1523'name' widget to have some special CSS class. To do this, you specify a  
     1524custom widget for your fields, and specify some attributes to use  
     1525when rendering those widgets:: 
     1526 
     1527    class CommentForm(forms.Form): 
     1528        name = forms.CharField(                    
     1529                    widget=forms.TextInput(attrs={'class':'special'})) 
     1530        url = forms.URLField() 
     1531        comment = forms.CharField( 
     1532                   widget=forms.TextInput(attrs={'size':'40'})) 
     1533 
     1534Django will then include the extra attributes in the rendered output:: 
     1535 
     1536    >>> f = CommentForm(auto_id=False) 
     1537    >>> f.as_table() 
     1538    <tr><th>Name:</th><td><input type="text" name="name" class="special"/></td></tr> 
     1539    <tr><th>Url:</th><td><input type="text" name="url"/></td></tr> 
     1540    <tr><th>Comment:</th><td><input type="text" name="comment" size="40"/></td></tr> 
     1541 
     1542Custom Widgets 
     1543-------------- 
     1544 
     1545When you start to write a lot of forms, you will probably find that you will 
     1546reuse certain sets of widget attributes over and over again. Rather than  
     1547repeat these attribute definitions every time you need them, Django allows  
     1548you to capture those definitions as a custom widget. 
     1549 
     1550For example, if you find that you are including a lot of comment fields on forms, 
     1551you could capture the idea of a ``TextInput`` with a specific ``size`` attribute  
     1552as a custom extension to the ``TextInput`` widget:: 
     1553 
     1554    class CommentWidget(forms.TextInput): 
     1555        def __init__(self, *args, **kwargs): 
     1556            kwargs.setdefault('attrs',{}).update({'size': '40'}) 
     1557            super(forms.TextInput, self).__init__(*args, **kwargs) 
     1558             
     1559Then you can use this widget in your forms:: 
     1560 
     1561    class CommentForm(forms.Form): 
     1562        name = forms.CharField() 
     1563        url = forms.URLField() 
     1564        comment = forms.CharField(widget=CommentWidget) 
     1565 
     1566You can even customize your custom widget, in the same way as you would  
     1567any other widget. Adding a once-off class to your ``CommentWidget`` is as  
     1568simple as adding an attribute definition:: 
     1569 
     1570    class CommentForm(forms.Form): 
     1571        name = forms.CharField(max_length=20) 
     1572        url = forms.URLField() 
     1573        comment = forms.CharField( 
     1574                    widget=CommentWidget(attrs={'class': 'special'})) 
     1575 
     1576Django also makes it easy to specify a custom field type that uses your custom 
     1577widget. For example, you could define a customized field type for comments 
     1578by defining:: 
     1579 
     1580    class CommentInput(forms.CharField): 
     1581        widget = CommentWidget 
     1582         
     1583You can then use this field whenever you have a form that requires a comment:: 
     1584 
     1585    class CommentForm(forms.Form): 
     1586        name = forms.CharField() 
     1587        url = forms.URLField() 
     1588        comment = CommentInput() 
     1589         
    14401590Generating forms for models 
    14411591===========================