Code

Ticket #11185: 11185.diff

File 11185.diff, 16.0 KB (added by timo, 22 months ago)

Updated parts of fadeev that are still applicable

Line 
1diff --git a/docs/ref/forms/fields.txt b/docs/ref/forms/fields.txt
2index 082ec17..6a991a8 100644
3--- a/docs/ref/forms/fields.txt
4+++ b/docs/ref/forms/fields.txt
5@@ -842,7 +842,7 @@ Slightly complex built-in ``Field`` classes
6 ``MultiValueField``
7 ~~~~~~~~~~~~~~~~~~~
8 
9-.. class:: MultiValueField(**kwargs)
10+.. class:: MultiValueField(fields=(), **kwargs)
11 
12     * Default widget: ``TextInput``
13     * Empty value: ``''`` (an empty string)
14@@ -851,22 +851,39 @@ Slightly complex built-in ``Field`` classes
15       as an argument to the ``MultiValueField``.
16     * Error message keys: ``required``, ``invalid``
17 
18-    This abstract field (must be subclassed) aggregates the logic of multiple
19-    fields. Subclasses should not have to implement clean(). Instead, they must
20-    implement compress(), which takes a list of valid values and returns a
21-    "compressed" version of those values -- a single value.  For example,
22-    :class:`SplitDateTimeField` is a subclass which combines a time field and
23-    a date field into a datetime object.
24+    Aggregates the logic of multiple fields that together produce a single
25+    value.
26+
27+    This field is abstract and must be subclassed. In contrast with the
28+    single-value fields, subclasses of :class:`MultiValueField` must not
29+    implement :meth:`~django.forms.Field.clean` but instead - implement
30+    :meth:`~MultiValueField.compress`.
31 
32     Takes one extra required argument:
33 
34     .. attribute:: fields
35 
36-        A list of fields which are cleaned into a single field. Each value in
37-        ``clean`` is cleaned by the corresponding field in ``fields`` -- the first
38-        value is cleaned by the first field, the second value is cleaned by
39-        the second field, etc.  Once all fields are cleaned, the list of clean
40-        values is "compressed" into a single value.
41+        A tuple of fields whose values are cleaned and subsequently combined
42+        into a single value.  Each value of the field is cleaned by the
43+        corresponding field in ``fields`` -- the first value is cleaned by the
44+        first field, the second value is cleaned by the second field, etc.
45+        Once all fields are cleaned, the list of clean values is is combined
46+        into a single value by :meth:`~MultiValueField.compress`.
47+
48+    .. attribute:: MultiValueField.widget
49+
50+        Must be a subclass of :class:`django.forms.MultiWidget`.
51+        Default value is :class:`~django.forms.widgets.TextInput`, which is
52+        probably is not very useful in this case.
53+
54+    .. method:: compress(data_list)
55+
56+        Takes a list of valid values and returns  a "compressed" version of
57+        those values -- in a single value. For example,
58+        :class:`SplitDateTimeField` is a subclass which combines a time field
59+        and a date field into a ``datetime`` object.
60+
61+        This method must be implemented in the subclasses.
62 
63 ``SplitDateTimeField``
64 ~~~~~~~~~~~~~~~~~~~~~~
65diff --git a/docs/ref/forms/widgets.txt b/docs/ref/forms/widgets.txt
66index fb76573..4255de7 100644
67--- a/docs/ref/forms/widgets.txt
68+++ b/docs/ref/forms/widgets.txt
69@@ -11,6 +11,16 @@ A widget is Django's representation of a HTML input element. The widget
70 handles the rendering of the HTML, and the extraction of data from a GET/POST
71 dictionary that corresponds to the widget.
72 
73+.. tip::
74+
75+    Widgets should not be confused with the :doc:`form fields </ref/forms/fields>`.
76+    Form fields deal with the logic of input validation and are used directly
77+    in templates. Widgets deal with rendering of HTML form input elements on
78+    the web page and extraction of raw submitted data. However, widgets do
79+    need to be :ref:`assigned <widget-to-field>` to form fields.
80+
81+.. _widget-to-field:
82+
83 Specifying widgets
84 ------------------
85 
86@@ -95,15 +105,23 @@ choices are inherent to the model and not just the representational widget.
87 Customizing widget instances
88 ----------------------------
89 
90-When Django renders a widget as HTML, it only renders the bare minimum
91-HTML - Django doesn't add a class definition, or any other widget-specific
92-attributes. This means that all :class:`TextInput` widgets will appear the same
93-on your Web page.
94+When Django renders a widget as HTML, it only renders very minimal markup -
95+Django doesn't add class names, or any other widget-specific attributes. This
96+means, for example, that all :class:`TextInput` widgets will appear the same
97+on your Web pages.
98+
99+There are two ways to customize widgets: :ref:`per widget instance
100+<styling-widget-instances>` and :ref:`per widget class <styling-widget-classes>`.
101 
102-If you want to make one widget look different to another, you need to
103-specify additional attributes for each widget. When you specify a
104-widget, you can provide a list of attributes that will be added to the
105-rendered HTML for the widget.
106+.. _styling-widget-instances:
107+
108+Styling widget instances
109+^^^^^^^^^^^^^^^^^^^^^^^^
110+
111+If you want to make one widget instance look different from another, you will
112+need to specify additional attributes at the time when the widget object is
113+instantiated and assigned to a form field (and perhaps add some rules to your
114+css files).
115 
116 For example, take the following simple form::
117 
118@@ -127,9 +145,7 @@ provided for each widget will be rendered exactly the same::
119 On a real Web page, you probably don't want every widget to look the same. You
120 might want a larger input element for the comment, and you might want the
121 'name' widget to have some special CSS class. To do this, you use the
122-:attr:`Widget.attrs` argument when creating the widget:
123-
124-For example::
125+:attr:`Widget.attrs` argument when creating the widget::
126 
127     class CommentForm(forms.Form):
128         name = forms.CharField(
129@@ -146,24 +162,50 @@ Django will then include the extra attributes in the rendered output:
130     <tr><th>Url:</th><td><input type="text" name="url"/></td></tr>
131     <tr><th>Comment:</th><td><input type="text" name="comment" size="40"/></td></tr>
132 
133-.. _built-in widgets:
134+.. _styling-widget-classes:
135 
136-Built-in widgets
137-----------------
138+Styling widget classes
139+^^^^^^^^^^^^^^^^^^^^^^
140 
141-Django provides a representation of all the basic HTML widgets, plus some
142-commonly used groups of widgets:
143+With widgets, it is possible to add media (``css`` and ``javascript``)
144+and more deeply customise their appearance and behavior.
145 
146-``Widget``
147-~~~~~~~~~~
148+In a nutshell, you will need to subclass the widget and either
149+:ref:`define a class "Media" <media-as-a-static-definition>` as a member of the
150+subclass, or :ref:`create a property "media" <dynamic-property>`, returning an
151+instance of that class.
152+
153+These methods involve somewhat advanced Python programming and are described in
154+detail in the :doc:`Form Media </topics/forms/media>` topic guide.
155+
156+.. _base-widget-classes:
157+
158+Base Widget classes
159+-------------------
160 
161-.. class:: Widget
162+Base widget classes :class:`Widget` and :class:`MultiWidget` are subclassed by
163+all the :ref:`built-in widgets <built-in widgets>` and may serve as a
164+foundation for custom widgets (but, please see the warning below).
165 
166-    This abstract class cannot be rendered, but provides the basic attribute :attr:`~Widget.attrs`.
167+.. warning::
168+
169+    Interfaces of classes :class:`~django.forms.widgets.Widget` and
170+    :class:`~django.forms.widgets.MultiWidget` are still in flux, therefore -
171+    please take care to test all of your custom widgets when upgrading Django.
172+
173+    It is a particularly good idea to write :doc:`tests </topics/testing>`
174+    for any of your custom widgets.
175+
176+.. class:: Widget(attrs=None)
177+
178+    This abstract class cannot be rendered, but provides the basic attribute
179+    :attr:`~Widget.attrs`.  You may also implement or override the
180+    :meth:`~Widget.render()` method on custom widgets.
181 
182     .. attribute:: Widget.attrs
183 
184-        A dictionary containing HTML attributes to be set on the rendered widget.
185+        A dictionary containing HTML attributes to be set on the rendered
186+        widget.
187 
188         .. code-block:: python
189 
190@@ -171,6 +213,75 @@ commonly used groups of widgets:
191             >>> name.render('name', 'A name')
192             u'<input title="Your name" type="text" name="name" value="A name" size="10" />'
193 
194+    .. method:: render(name, value, attrs=None)
195+
196+        Returns HTML for the widget, as a Unicode string. This method must be
197+        implemented by the subclass, otherwise ``NotImplementedError`` will be
198+        raised.
199+
200+        The 'value' given is not guaranteed to be valid input, therefore
201+        subclass implementations should program defensively.
202+
203+.. class:: MultiWidget(widgets, attrs=None)
204+
205+    A widget that is composed of multiple widgets.
206+    :class:`~django.forms.widgets.MultiWidget` works hand in hand with the
207+    :class:`~django.forms.MultiValueField`.
208+
209+    .. method:: render(name, value, attrs=None)
210+
211+        Argument `value` is handled differently in this method from the
212+        subclasses of :class:`~Widget`.
213+
214+        If `value` is a list, output of :meth:`~MultiWidget.render` will be a
215+        concatenation of rendered child widgets. If `value` is not a list, it
216+        will be first processed by the method
217+        :meth:`~MultiWidget.decompress()` to create the
218+        list, and then processed as above.
219+
220+        Unlike in the single value widgets, method :meth:`~MultiWidget.render`
221+        need not be implemented in the subclasses.
222+
223+    .. method:: decompress(value)
224+
225+        Returns a list of "decompressed" values for the given value of the
226+        multi-value field that makes use of the widget. The input value can be
227+        assumed as valid, but not necessarily non-empty.
228+
229+        This method **must be implemented** by the subclass, and since the
230+        value may be empty, the implementation must be defensive.
231+
232+        The rationale behind "decompression" is that it is necessary to "split"
233+        the combined value of the form field into the values of the individual
234+        field encapsulated within the multi-value field (e.g. when displaying
235+        the partially or fully filled-out form).
236+
237+        .. tip::
238+
239+            Note that :class:`~django.forms.MultiValueField` has a
240+            complementary method :meth:`~django.forms.MultiValueField.compress`
241+            with the opposite responsibility - combine cleaned values of
242+            all memeber fields into one.
243+
244+
245+.. _built-in widgets:
246+
247+Built-in widgets
248+----------------
249+
250+Django provides a representation of all the basic HTML widgets, plus some
251+commonly used groups of widgets in the ``django.forms.widgets`` module,
252+including :ref:`the input of text <text-widgets>`, :ref:`various checkboxes
253+and selectors <selector-widgets>`, :ref:`uploading files <file-upload-widgets>`,
254+and :ref:`handling of multi-valued input <composite-widgets>`.
255+
256+.. _text-widgets:
257+
258+Widgets handling input of text
259+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
260+
261+These widgets make use of the HTML elements ``input`` and ``textarea``.
262+
263 ``TextInput``
264 ~~~~~~~~~~~~~
265 
266@@ -204,39 +315,8 @@ commonly used groups of widgets:
267 
268     Hidden input: ``<input type='hidden' ...>``
269 
270-``MultipleHiddenInput``
271-~~~~~~~~~~~~~~~~~~~~~~~
272-
273-.. class:: MultipleHiddenInput
274-
275-    Multiple ``<input type='hidden' ...>`` widgets.
276-
277-    A widget that handles multiple hidden widgets for fields that have a list
278-    of values.
279-
280-    .. attribute:: MultipleHiddenInput.choices
281-
282-        This attribute is optional when the field does not have a
283-        :attr:`~Field.choices` attribute. If it does, it will override anything
284-        you set here when the attribute is updated on the :class:`Field`.
285-
286-``FileInput``
287-~~~~~~~~~~~~~
288-
289-.. class:: FileInput
290-
291-    File upload input: ``<input type='file' ...>``
292-
293-``ClearableFileInput``
294-~~~~~~~~~~~~~~~~~~~~~~
295-
296-.. class:: ClearableFileInput
297-
298-    .. versionadded:: 1.3
299-
300-    File upload input: ``<input type='file' ...>``, with an additional checkbox
301-    input to clear the field's value, if the field is not required and has
302-    initial data.
303+    Note that there also is a :class:`MultipleHiddenInput`
304+    widget that encapsulates a set of hidden input elements.
305 
306 ``DateInput``
307 ~~~~~~~~~~~~~
308@@ -296,6 +376,11 @@ commonly used groups of widgets:
309 
310     Text area: ``<textarea>...</textarea>``
311 
312+.. _selector-widgets:
313+
314+Selector and checkbox widgets
315+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
316+
317 ``CheckboxInput``
318 ~~~~~~~~~~~~~~~~~
319 
320@@ -435,6 +520,50 @@ commonly used groups of widgets:
321           ...
322         </ul>
323 
324+.. _file-upload-widgets:
325+
326+File upload widgets
327+^^^^^^^^^^^^^^^^^^^
328+
329+``FileInput``
330+~~~~~~~~~~~~~
331+
332+.. class:: FileInput
333+
334+    File upload input: ``<input type='file' ...>``
335+
336+``ClearableFileInput``
337+~~~~~~~~~~~~~~~~~~~~~~
338+
339+.. class:: ClearableFileInput
340+
341+    .. versionadded:: 1.3
342+
343+    File upload input: ``<input type='file' ...>``, with an additional checkbox
344+    input to clear the field's value, if the field is not required and has
345+    initial data.
346+
347+.. _composite-widgets:
348+
349+Composite widgets
350+^^^^^^^^^^^^^^^^^
351+
352+``MultipleHiddenInput``
353+~~~~~~~~~~~~~~~~~~~~~~~
354+
355+.. class:: MultipleHiddenInput
356+
357+    Multiple ``<input type='hidden' ...>`` widgets.
358+
359+    A widget that handles multiple hidden widgets for fields that have a list
360+    of values.
361+
362+    .. attribute:: MultipleHiddenInput.choices
363+
364+        This attribute is optional when the field does not have a
365+        :attr:`~Field.choices` attribute. If it does, it will override anything
366+        you set here when the attribute is updated on the :class:`Field`.
367+
368 ``MultiWidget``
369 ~~~~~~~~~~~~~~~
370 
371diff --git a/docs/topics/forms/media.txt b/docs/topics/forms/media.txt
372index 615dd71..29a7829 100644
373--- a/docs/topics/forms/media.txt
374+++ b/docs/topics/forms/media.txt
375@@ -38,6 +38,8 @@ in a form suitable for easy inclusion on your Web page.
376     whichever toolkit suits your requirements. Django is able to integrate
377     with any JavaScript toolkit.
378 
379+.. _media-as-a-static-definition:
380+
381 Media as a static definition
382 ----------------------------
383 
384@@ -78,10 +80,8 @@ A dictionary describing the CSS files required for various forms of output
385 media.
386 
387 The values in the dictionary should be a tuple/list of file names. See
388-`the section on media paths`_ for details of how to specify paths to media
389-files.
390-
391-.. _the section on media paths: `Paths in media definitions`_
392+:ref:`the section on media paths <form-media-paths>` for details of how to
393+specify paths to media files.
394 
395 The keys in the dictionary are the output media types. These are the same
396 types accepted by CSS files in media declarations: 'all', 'aural', 'braille',
397@@ -117,8 +117,8 @@ If this last CSS definition were to be rendered, it would become the following H
398 ``js``
399 ~~~~~~
400 
401-A tuple describing the required JavaScript files. See
402-`the section on media paths`_ for details of how to specify paths to media
403+A tuple describing the required JavaScript files. See :ref:`the section on
404+media paths <form-media-paths>` for details of how to specify paths to media
405 files.
406 
407 ``extend``
408@@ -164,10 +164,10 @@ declaration to the media declaration::
409     <script type="text/javascript" src="http://static.example.com/whizbang.js"></script>
410 
411 If you require even more control over media inheritance, define your media
412-using a `dynamic property`_. Dynamic properties give you complete control over
413-which media files are inherited, and which are not.
414+using a :ref:`dynamic property <dynamic-property>`. Dynamic properties give
415+you complete control over which media files are inherited, and which are not.
416 
417-.. _dynamic property: `Media as a dynamic property`_
418+.. _dynamic-property:
419 
420 Media as a dynamic property
421 ---------------------------
422@@ -198,9 +198,9 @@ Paths in media definitions
423 .. versionchanged:: 1.3
424 
425 Paths used to specify media can be either relative or absolute. If a path
426-starts with '/', 'http://' or 'https://', it will be interpreted as an absolute
427-path, and left as-is. All other paths will be prepended with the value of
428-the appropriate prefix.
429+starts with ``/``, ``http://`` or ``https://``, it will be interpreted as an
430+absolute path, and left as-is. All other paths will be prepended with the value
431+of the appropriate prefix.
432 
433 As part of the introduction of the
434 :doc:`staticfiles app </ref/contrib/staticfiles>` two new settings were added