Code

Ticket #16264: django-16264.2.diff

File django-16264.2.diff, 15.4 KB (added by bpeschier, 3 years ago)
Line 
1diff -r b0201f30c3bb docs/ref/forms/fields.txt
2--- a/docs/ref/forms/fields.txt Wed Jun 15 17:29:10 2011 +0000
3+++ b/docs/ref/forms/fields.txt Thu Jun 16 08:07:06 2011 +0200
4@@ -278,6 +278,7 @@
5 See the :ref:`format localization <format-localization>` documentation for
6 more information.
7 
8+.. _built-in fields:
9 
10 Built-in ``Field`` classes
11 --------------------------
12diff -r b0201f30c3bb docs/ref/forms/widgets.txt
13--- a/docs/ref/forms/widgets.txt        Wed Jun 15 17:29:10 2011 +0000
14+++ b/docs/ref/forms/widgets.txt        Thu Jun 16 08:07:06 2011 +0200
15@@ -11,9 +11,155 @@
16 handles the rendering of the HTML, and the extraction of data from a GET/POST
17 dictionary that corresponds to the widget.
18 
19+Specifying widgets
20+------------------
21+
22+Whenever you specify a field on a form, Django will use a default widget
23+that is appropriate to the type of data that is to be displayed. To find
24+which widget is used on which field, see the documentation about
25+:ref:`built-in fields`.
26+
27+However, if you want to use a different widget for a field, you can
28+just use the :attr:`~Field.widget` argument on the field definition. For example:
29+
30+    .. code-block:: python
31+
32+        from django import forms
33+
34+        class CommentForm(forms.Form):
35+            name = forms.CharField()
36+            url = forms.URLField()
37+            comment = forms.CharField(widget=forms.Textarea)
38+
39+This would specify a form with a comment that uses a larger Textarea widget,
40+rather than the default TextInput widget.
41+
42+
43+Setting arguments for widgets
44+-----------------------------
45+
46+Some widgets take over arguments from the fields they represent, for example
47+:class:`RadioSelect` or :class:`MultipleChoiceField` will use the choices of
48+the underlying field. Some widgets have optional extra arguments; they can be
49+set when defining the widget on the field. The reference below describes which
50+options can be set.
51+
52+In this example, the :attr:`SelectDateWidget.years` attribute is set for a
53+:class:`~django.forms.widgets.extras.SelectDateWidget`:
54+
55+    .. code-block:: python
56+
57+        from django import forms
58+        from django.forms.widgets.extras import SelectDateWidget
59+
60+        YEAR_CHOICES = ('2010', '2009',)
61+        RADIO_CHOICES = (('1','Radio 1',), ('2','Radio 2',),)
62+        CHECKBOX_CHOICES = (('1','The first choice',), ('2','The Second Choice',),)
63+
64+        class SimpleForm(forms.Form):
65+            radio = forms.ChoiceField(widget=forms.RadioSelect, choices=RADIO_CHOICES)
66+            checkboxes = forms.MultipleChoiceField(required=False,
67+                widget=forms.CheckboxSelectMultiple, choices=CHECKBOX_CHOICES)
68+            date = forms.DateField(widget=SelectDateWidget(years=YEAR_CHOICES))
69+
70+
71+Widgets with choices
72+^^^^^^^^^^^^^^^^^^^^
73+
74+Widgets based on the :class:`Select` widget deal with choices. In the default
75+case these are "owned" by a field based on :class:`ChoiceField`. The
76+:class:`ChoiceField` dictates what the choices are and resets the choices on
77+the widget everytime they get changed on the field.
78+
79+Widgets which offer a ``choices`` attribute can however be used with fields
80+which are not based on choice - such as a :class:`TextField` - but it is
81+recommended to use a :class:`ChoiceField`-based field when the choices are
82+inherent to the model and not just the representational widget.
83+
84+Customizing widget instances
85+----------------------------
86+
87+When Django renders a widget as HTML, it only renders the bare minimum
88+HTML - Django doesn't add a class definition, or any other widget-specific
89+attributes. This means that all 'TextInput' widgets will appear the same
90+on your Web page.
91+
92+If you want to make one widget look different to another, you need to
93+specify additional attributes for each widget. When you specify a
94+widget, you can provide a list of attributes that will be added to the
95+rendered HTML for the widget.
96+
97+For example, take the following simple form:
98+
99+    .. code-block:: python
100+
101+        from django import forms
102+
103+        class CommentForm(forms.Form):
104+            name = forms.CharField()
105+            url = forms.URLField()
106+            comment = forms.CharField()
107+
108+This form will include three default TextInput widgets, with default rendering -
109+no CSS class, no extra attributes. This means that the input boxes provided for
110+each widget will be rendered exactly the same:
111+
112+    .. code-block:: python
113+
114+        >>> f = CommentForm(auto_id=False)
115+        >>> f.as_table()
116+        <tr><th>Name:</th><td><input type="text" name="name" /></td></tr>
117+        <tr><th>Url:</th><td><input type="text" name="url"/></td></tr>
118+        <tr><th>Comment:</th><td><input type="text" name="comment" /></td></tr>
119+
120+
121+On a real Web page, you probably don't want every widget to look the same. You
122+might want a larger input element for the comment, and you might want the 'name'
123+widget to have some special CSS class. To do this, you use the :attr:`Widget.attrs`
124+argument when creating the widget:
125+
126+For example:
127+
128+    .. code-block:: python
129+
130+        class CommentForm(forms.Form):
131+            name = forms.CharField(
132+                        widget=forms.TextInput(attrs={'class':'special'}))
133+            url = forms.URLField()
134+            comment = forms.CharField(
135+                       widget=forms.TextInput(attrs={'size':'40'}))
136+
137+Django will then include the extra attributes in the rendered output:
138+
139+    .. code-block:: python
140+
141+        >>> f = CommentForm(auto_id=False)
142+        >>> f.as_table()
143+        <tr><th>Name:</th><td><input type="text" name="name" class="special"/></td></tr>
144+        <tr><th>Url:</th><td><input type="text" name="url"/></td></tr>
145+        <tr><th>Comment:</th><td><input type="text" name="comment" size="40"/></td></tr>
146+
147+Built-in widgets
148+----------------
149+
150 Django provides a representation of all the basic HTML widgets, plus some
151 commonly used groups of widgets:
152 
153+.. class:: Widget
154+
155+    This abstract class cannot be rendered, but provides the basic attribute :attr:`~Widget.attrs`.
156+
157+    .. attribute:: Widget.attrs
158+   
159+        A dictionary containing HTML attributes to be set on the rendered widget.
160+
161+        .. code-block:: python
162+           
163+            >>> name = forms.TextInput(attrs={'size': 10, 'title': 'Your name',})
164+            >>> name.render('name', 'A name')
165+            u'<input title="Your name" type="text" name="name" value="A name" size="10" />'
166+
167+
168 .. class:: TextInput
169 
170     Text input: ``<input type='text' ...>``
171@@ -29,10 +175,10 @@
172         Determines whether the widget will have a value filled in when the
173         form is re-displayed after a validation error (default is ``False``).
174 
175-.. versionchanged:: 1.3
176-    The default value for
177-    :attr:`~PasswordInput.render_value` was
178-    changed from ``True`` to ``False``
179+        .. versionchanged:: 1.3
180+            The default value for
181+            :attr:`~PasswordInput.render_value` was
182+            changed from ``True`` to ``False``
183 
184 .. class:: HiddenInput
185 
186@@ -42,6 +188,14 @@
187 
188     Multiple ``<input type='hidden' ...>`` widgets.
189 
190+    A widget that handles multiple hidden widgets for fields that have a list of values.
191+
192+    .. attribute:: MultipleHiddenInput.choices
193+
194+        This attribute is optional when the field does not have a :attr:`~Field.choices`
195+        attribute. If it does, it will override anything you set here when the attribute
196+        is updated on the :class:`Field`.
197+
198 .. class:: FileInput
199 
200     File upload input: ``<input type='file' ...>``
201@@ -64,7 +218,8 @@
202 
203         The format in which this field's initial value will be displayed.
204 
205-    If no ``format`` argument is provided, the default format is ``'%Y-%m-%d'``.
206+    If no ``format`` argument is provided, the default format is the first
207+    format found in :setting:`DATE_INPUT_FORMATS`.
208 
209 .. class:: DateTimeInput
210 
211@@ -76,8 +231,8 @@
212 
213         The format in which this field's initial value will be displayed.
214 
215-    If no ``format`` argument is provided, the default format is ``'%Y-%m-%d
216-    %H:%M:%S'``.
217+    If no ``format`` argument is provided, the default format is the first
218+    format found in :setting:`DATETIME_INPUT_FORMATS`.
219 
220 .. class:: TimeInput
221 
222@@ -89,7 +244,8 @@
223 
224         The format in which this field's initial value will be displayed.
225 
226-    If no ``format`` argument is provided, the default format is ``'%H:%M:%S'``.
227+    If no ``format`` argument is provided, the default format is the first
228+    format found in :setting:`TIME_INPUT_FORMATS`.
229 
230 .. class:: Textarea
231 
232@@ -111,7 +267,11 @@
233 
234     Select widget: ``<select><option ...>...</select>``
235 
236-    Requires that your field provides :attr:`~Field.choices`.
237+    .. attribute:: Select.choices
238+
239+        This attribute is optional when the field does not have a :attr:`~Field.choices`
240+        attribute. If it does, it will override anything you set here when the attribute
241+        is updated on the :class:`Field`.
242 
243 .. class:: NullBooleanSelect
244 
245@@ -119,14 +279,12 @@
246 
247 .. class:: SelectMultiple
248 
249-    Select widget allowing multiple selection: ``<select
250-    multiple='multiple'>...</select>``
251-
252-    Requires that your field provides :attr:`~Field.choices`.
253+    Similar to :class:`Select`, but allows multiple selection:
254+    ``<select multiple='multiple'>...</select>``
255 
256 .. class:: RadioSelect
257 
258-    A list of radio buttons:
259+    Similar to :class:`Select`, but rendered as a list of radio buttons:
260 
261     .. code-block:: html
262 
263@@ -135,11 +293,9 @@
264           ...
265         </ul>
266 
267-    Requires that your field provides :attr:`~Field.choices`.
268-
269 .. class:: CheckboxSelectMultiple
270 
271-    A list of checkboxes:
272+    Similar to :class:`SelectMultiple`, but rendered as a list of check buttons:
273 
274     .. code-block:: html
275 
276@@ -150,111 +306,66 @@
277 
278 .. class:: MultiWidget
279 
280-    Wrapper around multiple other widgets
281+    Wrapper around multiple other widgets.
282+
283+    Its ``render`` method is different than other widgets', because it has to
284+    figure out how to split a single value for display in multiple widgets.
285+    The ``value`` argument can be one of two things:
286+
287+    * A list.
288+    * A normal value (e.g., a string) that has been "compressed" from
289+      a list of values.
290+
291+    In the second case - i.e., if the value is NOT a list - render() will
292+    first "decompress" the value into a list before rendering it. It does so by
293+    calling the decompress() method, which MultiWidget subclasses must
294+    implement. This method takes a single "compressed" value and returns a
295+    list.
296+
297+    When render() does its HTML rendering, each value in the list is rendered
298+    with the corresponding widget - the first value is rendered in the first
299+    widget, the second value is rendered in the second widget, etc.
300+
301+    Subclasses may implement format_output(), which takes the list of rendered
302+    widgets and returns a string of HTML that formats them any way you'd like.
303+
304+    You'll probably want to use this class with :class:`MultiValueField`.
305+
306+    .. attribute:: widgets
307+
308+        An iterable containing the widgets needed.
309 
310 .. class:: SplitDateTimeWidget
311 
312-    Wrapper around two widgets: ``DateInput`` for the date, and ``TimeInput``
313-    for the time.
314+    Wrapper (using :class:`MultiWidget`) around two widgets: :class:`DateInput`
315+    for the date, and :class:`TimeInput` for the time.
316 
317-    Takes two optional arguments, ``date_format`` and ``time_format``, which
318-    work just like the ``format`` argument for ``DateInput`` and ``TimeInput``.
319+    ``SplitDateTimeWidget`` has two optional attributes:
320 
321-.. currentmodule:: django.forms.extras.widgets
322+    .. attribute:: SplitDateTimeWidget.date_format
323+
324+        Similar to :attr:`DateInput.format`
325+
326+    .. attribute:: SplitDateTimeWidget.time_format
327+
328+        Similar to :attr:`TimeInput.format`
329+
330+
331+.. class:: SplitHiddenDateTimeWidget
332+
333+    Similar to :class:`SplitDateTimeWidget`, but uses :class:`HiddenInput` for
334+    both date and time.
335+
336+.. currentmodule:: django.forms.widgets.extras
337 
338 .. class:: SelectDateWidget
339 
340-    Wrapper around three select widgets: one each for month, day, and year.
341+    Wrapper around three :class:`~django.forms.Select` widgets: one each for month, day, and year.
342     Note that this widget lives in a separate file from the standard widgets.
343 
344     Takes one optional argument:
345 
346-    .. attribute:: List.years
347+    .. attribute:: SelectDateWidget.years
348 
349         An optional list/tuple of years to use in the "year" select box.
350         The default is a list containing the current year and the next 9 years.
351-
352-    .. code-block:: python
353-
354-        from django.forms.extras.widgets import SelectDateWidget
355-
356-        date = forms.DateField(widget=SelectDateWidget())
357-
358-Specifying widgets
359-------------------
360-.. currentmodule:: django.forms
361-
362-.. attribute:: Form.widget
363-
364-Whenever you specify a field on a form, Django will use a default widget
365-that is appropriate to the type of data that is to be displayed. To find
366-which widget is used on which field, see the documentation for the
367-built-in Field classes.
368-
369-However, if you want to use a different widget for a field, you can -
370-just use the 'widget' argument on the field definition. For example::
371-
372-    from django import forms
373-
374-    class CommentForm(forms.Form):
375-        name = forms.CharField()
376-        url = forms.URLField()
377-        comment = forms.CharField(widget=forms.Textarea)
378-
379-This would specify a form with a comment that uses a larger Textarea widget,
380-rather than the default TextInput widget.
381-
382-Customizing widget instances
383-----------------------------
384-
385-When Django renders a widget as HTML, it only renders the bare minimum
386-HTML - Django doesn't add a class definition, or any other widget-specific
387-attributes. This means that all 'TextInput' widgets will appear the same
388-on your Web page.
389-
390-If you want to make one widget look different to another, you need to
391-specify additional attributes for each widget. When you specify a
392-widget, you can provide a list of attributes that will be added to the
393-rendered HTML for the widget.
394-
395-For example, take the following simple form::
396-
397-    class CommentForm(forms.Form):
398-        name = forms.CharField()
399-        url = forms.URLField()
400-        comment = forms.CharField()
401-
402-This form will include three default TextInput widgets, with default rendering -
403-no CSS class, no extra attributes. This means that the input boxes provided for
404-each widget will be rendered exactly the same::
405-
406-    >>> f = CommentForm(auto_id=False)
407-    >>> f.as_table()
408-    <tr><th>Name:</th><td><input type="text" name="name" /></td></tr>
409-    <tr><th>Url:</th><td><input type="text" name="url"/></td></tr>
410-    <tr><th>Comment:</th><td><input type="text" name="comment" /></td></tr>
411-
412-
413-On a real Web page, you probably don't want every widget to look the same. You
414-might want a larger input element for the comment, and you might want the 'name'
415-widget to have some special CSS class. To do this, you use the ``attrs``
416-argument when creating the widget:
417-
418-.. attribute:: Widget.attrs
419-
420-For example::
421-
422-    class CommentForm(forms.Form):
423-        name = forms.CharField(
424-                    widget=forms.TextInput(attrs={'class':'special'}))
425-        url = forms.URLField()
426-        comment = forms.CharField(
427-                   widget=forms.TextInput(attrs={'size':'40'}))
428-
429-Django will then include the extra attributes in the rendered output::
430-
431-    >>> f = CommentForm(auto_id=False)
432-    >>> f.as_table()
433-    <tr><th>Name:</th><td><input type="text" name="name" class="special"/></td></tr>
434-    <tr><th>Url:</th><td><input type="text" name="url"/></td></tr>
435-    <tr><th>Comment:</th><td><input type="text" name="comment" size="40"/></td></tr>