Added documentation for widgets in newforms.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@5867 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
dd0f5d9284
commit
3d012a18ce
|
@ -962,7 +962,7 @@ validation if a particular field's value is not given. ``initial`` values are
|
|||
~~~~~~~~~~
|
||||
|
||||
The ``widget`` argument lets you specify a ``Widget`` class to use when
|
||||
rendering this ``Field``. See "Widgets" below for more information.
|
||||
rendering this ``Field``. See "Widgets"_ below for more information.
|
||||
|
||||
``help_text``
|
||||
~~~~~~~~~~~~~
|
||||
|
@ -1437,6 +1437,156 @@ like so::
|
|||
senders = MultiEmailField()
|
||||
cc_myself = forms.BooleanField()
|
||||
|
||||
Widgets
|
||||
=======
|
||||
|
||||
A widget is Django's representation of a HTML input element. The widget
|
||||
handles the rendering of the HTML, and the extraction of data from a GET/POST
|
||||
dictionary that corresponds to the widget.
|
||||
|
||||
Django provides a representation of all the basic HTML widgets, plus some
|
||||
commonly used groups of widgets:
|
||||
|
||||
============================ ===========================================
|
||||
Widget HTML Equivalent
|
||||
============================ ===========================================
|
||||
``TextInput`` ``<input type='text' ...``
|
||||
``PasswordInput`` ``<input type='password' ...``
|
||||
``HiddenInput`` ``<input type='hidden' ...``
|
||||
``MultipleHiddenInput`` Multiple ``<input type='hidden' ...``
|
||||
instances.
|
||||
``FileInput`` ``<input type='file' ...``
|
||||
``Textarea`` ``<textarea>...</textarea>``
|
||||
``CheckboxInput`` ``<input type='checkbox' ...``
|
||||
``Select`` ``<select><option ...``
|
||||
``NullBooleanSelect`` Select widget with options 'Unknown',
|
||||
'Yes' and 'No'
|
||||
``SelectMultiple`` ``<select multiple='multiple'><option ...``
|
||||
``RadioSelect`` ``<ul><li><input type='radio' ...``
|
||||
``CheckboxSelectMultiple`` ``<ul><li><input type='checkbox' ...``
|
||||
``MultiWidget`` Wrapper around multiple other widgets
|
||||
``SplitDateTimeWidget`` Wrapper around two ``TextInput`` widgets:
|
||||
one for the Date, and one for the Time.
|
||||
============================ ===========================================
|
||||
|
||||
Specifying widgets
|
||||
------------------
|
||||
|
||||
Whenever you specify a field on a form, Django will use a default widget
|
||||
that is appropriate to the type of data that is to be displayed. To find
|
||||
which widget is used on which field, see the documentation for the
|
||||
built-in Field classes.
|
||||
|
||||
However, if you want to use a different widget for a field, you can -
|
||||
just use the 'widget' argument on the field definition. For example::
|
||||
|
||||
class CommentForm(forms.Form):
|
||||
name = forms.CharField()
|
||||
url = forms.URLField()
|
||||
comment = forms.CharField(widget=forms.TextArea)
|
||||
|
||||
This would specify a form with a comment that uses a larger TextArea widget,
|
||||
rather than the default TextInput widget.
|
||||
|
||||
Customizing widget instances
|
||||
----------------------------
|
||||
|
||||
When Django renders a widget as HTML, it only renders the bare minimum
|
||||
HTML - Django doesn't add a class definition, or any other widget-specific
|
||||
attributes. This means that all 'TextInput' widgets will appear the same
|
||||
on your web page.
|
||||
|
||||
If you want to make one widget look different to another, you need to
|
||||
specify additional attributes for each widget. When you specify a
|
||||
widget, you can provide a list of attributes that will be added to the
|
||||
rendered HTML for the widget.
|
||||
|
||||
For example, take the following simple form::
|
||||
|
||||
class CommentForm(forms.Form):
|
||||
name = forms.CharField()
|
||||
url = forms.URLField()
|
||||
comment = forms.CharField()
|
||||
|
||||
This form will include three default TextInput widgets, with default rendering -
|
||||
no CSS class, no extra attributes. This means that the inputs boxes provided for
|
||||
each widget will be rendered exactly the same::
|
||||
|
||||
>>> f = CommentForm(auto_id=False)
|
||||
>>> f.as_table()
|
||||
<tr><th>Name:</th><td><input type="text" name="name" /></td></tr>
|
||||
<tr><th>Url:</th><td><input type="text" name="url"/></td></tr>
|
||||
<tr><th>Comment:</th><td><input type="text" name="comment" /></td></tr>
|
||||
|
||||
On a real web page, you probably don't want every widget to look the same. You
|
||||
might want a larger input element for the comment, and you might want the
|
||||
'name' widget to have some special CSS class. To do this, you specify a
|
||||
custom widget for your fields, and specify some attributes to use
|
||||
when rendering those widgets::
|
||||
|
||||
class CommentForm(forms.Form):
|
||||
name = forms.CharField(
|
||||
widget=forms.TextInput(attrs={'class':'special'}))
|
||||
url = forms.URLField()
|
||||
comment = forms.CharField(
|
||||
widget=forms.TextInput(attrs={'size':'40'}))
|
||||
|
||||
Django will then include the extra attributes in the rendered output::
|
||||
|
||||
>>> f = CommentForm(auto_id=False)
|
||||
>>> f.as_table()
|
||||
<tr><th>Name:</th><td><input type="text" name="name" class="special"/></td></tr>
|
||||
<tr><th>Url:</th><td><input type="text" name="url"/></td></tr>
|
||||
<tr><th>Comment:</th><td><input type="text" name="comment" size="40"/></td></tr>
|
||||
|
||||
Custom Widgets
|
||||
--------------
|
||||
|
||||
When you start to write a lot of forms, you will probably find that you will
|
||||
reuse certain sets of widget attributes over and over again. Rather than
|
||||
repeat these attribute definitions every time you need them, Django allows
|
||||
you to capture those definitions as a custom widget.
|
||||
|
||||
For example, if you find that you are including a lot of comment fields on forms,
|
||||
you could capture the idea of a ``TextInput`` with a specific ``size`` attribute
|
||||
as a custom extension to the ``TextInput`` widget::
|
||||
|
||||
class CommentWidget(forms.TextInput):
|
||||
def __init__(self, *args, **kwargs):
|
||||
kwargs.setdefault('attrs',{}).update({'size': '40'})
|
||||
super(forms.TextInput, self).__init__(*args, **kwargs)
|
||||
|
||||
Then you can use this widget in your forms::
|
||||
|
||||
class CommentForm(forms.Form):
|
||||
name = forms.CharField()
|
||||
url = forms.URLField()
|
||||
comment = forms.CharField(widget=CommentWidget)
|
||||
|
||||
You can even customize your custom widget, in the same way as you would
|
||||
any other widget. Adding a once-off class to your ``CommentWidget`` is as
|
||||
simple as adding an attribute definition::
|
||||
|
||||
class CommentForm(forms.Form):
|
||||
name = forms.CharField(max_length=20)
|
||||
url = forms.URLField()
|
||||
comment = forms.CharField(
|
||||
widget=CommentWidget(attrs={'class': 'special'}))
|
||||
|
||||
Django also makes it easy to specify a custom field type that uses your custom
|
||||
widget. For example, you could define a customized field type for comments
|
||||
by defining::
|
||||
|
||||
class CommentInput(forms.CharField):
|
||||
widget = CommentWidget
|
||||
|
||||
You can then use this field whenever you have a form that requires a comment::
|
||||
|
||||
class CommentForm(forms.Form):
|
||||
name = forms.CharField()
|
||||
url = forms.URLField()
|
||||
comment = CommentInput()
|
||||
|
||||
Generating forms for models
|
||||
===========================
|
||||
|
||||
|
|
Loading…
Reference in New Issue