Ticket #11185: widget-evgeny1.diff
File widget-evgeny1.diff, 18.8 KB (added by , 14 years ago) |
---|
-
django/forms/widgets.py
diff --git a/django/forms/widgets.py b/django/forms/widgets.py index dd5868f..701fa79 100644
a b class MediaDefiningClass(type): 136 136 return new_class 137 137 138 138 class Widget(object): 139 """Base class for all :ref:`built-in widgets <builtin-widgets>` 140 """ 139 141 __metaclass__ = MediaDefiningClass 140 142 is_hidden = False # Determines whether this corresponds to an <input type="hidden">. 141 143 needs_multipart_form = False # Determines does this widget need multipart-encrypted form … … class Widget(object): 156 158 157 159 def render(self, name, value, attrs=None): 158 160 """ 159 Returns this Widget rendered as HTML, as a Unicode string.161 Returns HTML for the widget, as a Unicode string. 160 162 161 The 'value' given is not guaranteed to be valid input, so subclass162 implementations should program defensively.163 The 'value' given is not guaranteed to be valid input, 164 therefore subclass implementations should program defensively. 163 165 """ 164 166 raise NotImplementedError 165 167 -
docs/index.txt
diff --git a/docs/index.txt b/docs/index.txt index 0cf066e..ee7ab15 100644
a b Forms 124 124 :doc:`Overview <topics/forms/index>` | 125 125 :doc:`Form API <ref/forms/api>` | 126 126 :doc:`Built-in fields <ref/forms/fields>` | 127 :doc:` Built-in widgets <ref/forms/widgets>`127 :doc:`Widgets <ref/forms/widgets>` 128 128 129 129 * **Advanced:** 130 130 :doc:`Forms for models <topics/forms/modelforms>` | -
docs/ref/forms/fields.txt
diff --git a/docs/ref/forms/fields.txt b/docs/ref/forms/fields.txt index b49864f..20ba4c7 100644
a b as the rendered output. 278 278 See the :ref:`format localization <format-localization>` documentation for 279 279 more information. 280 280 281 .. _builtin-form-fields: 281 282 282 283 Built-in ``Field`` classes 283 284 -------------------------- … … Takes one extra required argument: 797 798 ... 798 799 ValidationError: [u'Ensure this value has at most 20 characters (it has 28).'] 799 800 801 .. _multi-value-field: 802 800 803 ``MultiValueField`` 801 804 ~~~~~~~~~~~~~~~~~~~ 802 805 803 .. class:: MultiValueField(**kwargs) 806 .. class:: MultiValueField(fields = (), **kwargs) 807 808 Aggregates the logic of multiple fields that together 809 produce a single cleaned value. 810 811 This field is abstract and must be subclassed. 812 Also, in contrast with the single-value fields 813 the subclasses of :class:`MultiValueField` 814 must not implement :meth:`~forms.Field.clean` 815 but 816 instead - implement :meth:`~forms.MultiValueField.compress`. 804 817 805 * Default widget: ``TextInput``806 818 * Empty value: ``''`` (an empty string) 807 819 * Normalizes to: the type returned by the ``compress`` method of the subclass. 808 820 * Validates that the given value against each of the fields specified 809 821 as an argument to the ``MultiValueField``. 810 822 * Error message keys: ``required``, ``invalid`` 811 823 812 This abstract field (must be subclassed) aggregates the logic of multiple813 fields. Subclasses should not have to implement clean(). Instead, they must814 implement compress(), which takes a list of valid values and returns a815 "compressed" version of those values -- a single value. For example,816 :class:`SplitDateTimeField` is a subclass which combines a time field and817 a date field into a datetime object.818 819 Takes one extra required argument:820 821 824 .. attribute:: MultiValueField.fields 822 825 823 A list of fields which are cleaned into a single field. Each value in 824 ``clean`` is cleaned by the corresponding field in ``fields`` -- the first 825 value is cleaned by the first field, the second value is cleaned by 826 the second field, etc. Once all fields are cleaned, the list of clean 827 values is "compressed" into a single value. 826 A tuple of fields whose values are cleaned 827 and 828 subsequently combined into a single value. 829 More specifically, each value of the field 830 is cleaned by the corresponding field in ``fields`` 831 -- the first value is cleaned by the first field, 832 the second value is cleaned by the second field, etc. 833 Once all fields are cleaned, 834 the list of clean values is combined into a single value 835 by the :meth:`~forms.MultiValueField.compress`. 836 837 .. attribute:: MultiValueField.widget 838 839 Must be a subclass of 840 :class:`django.forms.MultiWidget`. 841 Default value is :class:`~forms.widgets.TextInput`, 842 which is probably is not very useful in this case. 843 844 .. method:: compress(data_list) 845 846 takes a list of valid values and returns 847 a "compressed" version of those values -- in a single value. 848 For example, :class:`SplitDateTimeField` is a subclass which combines a time field and 849 a date field into a datetime object. 850 851 This method must be implemented in the subclasses. 828 852 829 853 ``SplitDateTimeField`` 830 854 ~~~~~~~~~~~~~~~~~~~~~~ -
docs/ref/forms/widgets.txt
diff --git a/docs/ref/forms/widgets.txt b/docs/ref/forms/widgets.txt index dbdf109..7b452b1 100644
a b 2 2 Widgets 3 3 ======= 4 4 5 The term "widget" for the purposes of this document is narrower 6 than usually assumed elsewhere. 7 8 In Django, widget is a Python object responsible for three things: 9 10 #. generation of a subtree of HTML document 11 where users can enter some data 12 #. extraction of raw data from the request's GET/POST dictionary 13 entered into the element decribed above 14 #. optionally - provide media (e.g. javacript and CSS) for the widget 15 16 Objects of widget classes wrap "native HTML widget" elements: 17 ``input``, 18 ``textarea``, 19 ``select`` and ``option``, 20 but in addition they may include other HTML constructs 21 and 22 may contain more than one "native HTML widget". 23 24 .. tip:: 25 26 Widgets should not be confused with the :doc:`form fields </ref/forms/fields>`. 27 Form fields concern with the logic of input validation, 28 and are directly used in the templates. 29 Widgets purely deal with 30 rendering of the data entry for display on the web page 31 and 32 extraction of raw submitted data. 33 34 However, in order to take effect, widgets do need to be 35 :ref:`assigned <widget-to-field>` 36 to the form fields. 37 38 .. _builtin-widgets: 39 40 Built-in widgets 41 ---------------- 42 43 All built-in widgets are part of the ``django.forms.widgets`` module 44 and 45 handle many common use cases for 46 :ref:`the input of text <text-widgets>`, 47 :ref:`various checkboxes and selectors <selector-widgets>`, 48 :ref:`uploading files <file-upload-widgets>`, 49 and 50 :ref:`handling of multi-valued input <composite-widgets>`. 51 5 52 .. module:: django.forms.widgets 6 53 :synopsis: Django's built-in form widgets. 7 54 8 55 .. currentmodule:: django.forms 9 56 10 A widget is Django's representation of a HTML input element. The widget 11 handles the rendering of the HTML, and the extraction of data from a GET/POST 12 dictionary that corresponds to the widget. 57 .. _text-widgets: 58 59 Widgets handling input of text 60 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 13 61 14 Django provides a representation of all the basic HTML widgets, plus some 15 commonly used groups of widgets: 62 These widgets make use of the HTML elements `input` and `textarea`. 16 63 17 64 .. class:: TextInput 18 65 … … commonly used groups of widgets: 30 77 form is re-displayed after a validation error (default is ``False``). 31 78 32 79 .. versionchanged:: 1.3 33 The default value for 34 :attr:`~PasswordInput.render_value` was 80 The default value for ``render_value`` was 35 81 changed from ``True`` to ``False`` 36 82 37 83 .. class:: HiddenInput 38 84 39 85 Hidden input: ``<input type='hidden' ...>`` 40 41 .. class:: MultipleHiddenInput 42 43 Multiple ``<input type='hidden' ...>`` widgets. 44 45 .. class:: FileInput 46 47 File upload input: ``<input type='file' ...>`` 48 49 .. class:: ClearableFileInput 50 51 .. versionadded:: 1.3 52 53 File upload input: ``<input type='file' ...>``, with an additional checkbox 54 input to clear the field's value, if the field is not required and has 55 initial data. 86 87 Please note that 88 there also is a :ref:`MultipleHiddenInput <multiple-hidden>` widget 89 that encapsulates a set of hidden input elements. 56 90 57 91 .. class:: DateInput 58 92 … … commonly used groups of widgets: 95 129 96 130 Text area: ``<textarea>...</textarea>`` 97 131 132 .. _selector-widgets: 133 134 Selector and checkbox widgets 135 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 136 98 137 .. class:: CheckboxInput 99 138 100 139 Checkbox: ``<input type='checkbox' ...>`` … … commonly used groups of widgets: 148 187 ... 149 188 </ul> 150 189 151 .. class:: MultiWidget 190 .. _file-upload-widgets: 191 192 File upload widgets 193 ^^^^^^^^^^^^^^^^^^^ 194 195 .. class:: FileInput 196 197 File upload input: ``<input type='file' ...>`` 198 199 .. class:: ClearableFileInput 200 201 .. versionadded:: 1.3 152 202 153 Wrapper around multiple other widgets 203 File upload input: ``<input type='file' ...>``, with an additional checkbox 204 input to clear the field's value, if the field is not required and has 205 initial data. 206 207 208 .. _composite-widgets: 209 210 Composite widgets 211 ^^^^^^^^^^^^^^^^^ 154 212 155 213 .. class:: SplitDateTimeWidget 156 214 … … commonly used groups of widgets: 169 227 170 228 Takes one optional argument: 171 229 172 .. attribute:: List.years230 .. attribute:: SelectDateWidget.years 173 231 174 232 An optional list/tuple of years to use in the "year" select box. 175 233 The default is a list containing the current year and the next 9 years. … … commonly used groups of widgets: 180 238 181 239 date = forms.DateField(widget=SelectDateWidget()) 182 240 183 Specifying widgets 184 ------------------ 185 .. currentmodule:: django.forms 241 .. _multiple-hidden: 186 242 187 .. attribute:: Form.widget 243 .. class:: MultipleHiddenInput 244 245 Multiple ``<input type='hidden' ...>`` widgets. 246 247 .. _widget-to-field: 248 249 Assigning widgets to form fields 250 -------------------------------- 251 .. currentmodule:: django.forms 188 252 189 253 Whenever you specify a field on a form, Django will use a default widget 190 254 that is appropriate to the type of data that is to be displayed. To find 191 which widget is used on which field, see the documentation for the 192 built-in Field classes. 255 which widget is used on which field, 256 see the :ref:`documentation for the built-in Field classes 257 <builtin-form-fields>`. 193 258 194 259 However, if you want to use a different widget for a field, you can - 195 just use the 'widget'argument on the field definition. For example::260 just use the ``widget`` argument on the field definition. For example:: 196 261 197 262 from django import forms 198 263 … … just use the 'widget' argument on the field definition. For example:: 201 266 url = forms.URLField() 202 267 comment = forms.CharField(widget=forms.Textarea) 203 268 204 This would specify a form with a comment that uses a larger Textarea widget, 205 rather than the default TextInput widget. 269 This will specify a form with a comment that uses a larger ``Textarea`` widget, 270 rather than the default ``TextInput`` widget. 271 272 Styling and adding behavior to widgets 273 -------------------------------------- 274 275 When Django renders a widget as HTML, 276 it only produces the very minimal markup 277 - Django doesn't add class names 278 or 279 any other widget-specific attributes. 280 This means, for example, that 281 all instances of ``TextInput`` widget 282 will appear the same on your Web pages. 283 284 There are two ways to customize widgets: 285 :ref:`per widget instance <styling-widget-instances>` 286 and 287 :ref:`per widget class <styling-widget-classes>`. 206 288 207 Customizing widget instances 208 ---------------------------- 289 .. _styling-widget-instances: 209 290 210 When Django renders a widget as HTML, it only renders the bare minimum 211 HTML - Django doesn't add a class definition, or any other widget-specific 212 attributes. This means that all 'TextInput' widgets will appear the same 213 on your Web page. 291 Styling widget instances 292 ^^^^^^^^^^^^^^^^^^^^^^^^ 214 293 215 If you want to make one widget look different to another, you need to 216 specify additional attributes for each widget. When you specify a 217 widget, you can provide a list of attributes that will be added to the 218 rendered HTML for the widget. 294 If you want to make one widget instance look different from another, 295 all you will need to do is 296 specify additional attributes 297 - at the time when the widget object is instantiated 298 and assigned to a form field 299 (and perhaps add some rules to your .css files). 219 300 220 301 For example, take the following simple form:: 221 302 … … each widget will be rendered exactly the same:: 234 315 <tr><th>Url:</th><td><input type="text" name="url"/></td></tr> 235 316 <tr><th>Comment:</th><td><input type="text" name="comment" /></td></tr> 236 317 237 238 318 On a real Web page, you probably don't want every widget to look the same. You 239 319 might want a larger input element for the comment, and you might want the 'name' 240 320 widget to have some special CSS class. To do this, you use the ``attrs`` 241 argument when creating the widget: 242 243 .. attribute:: Widget.attrs 244 245 For example:: 321 argument when creating the widget:: 246 322 247 323 class CommentForm(forms.Form): 248 324 name = forms.CharField( … … Django will then include the extra attributes in the rendered output:: 258 334 <tr><th>Name:</th><td><input type="text" name="name" class="special"/></td></tr> 259 335 <tr><th>Url:</th><td><input type="text" name="url"/></td></tr> 260 336 <tr><th>Comment:</th><td><input type="text" name="comment" size="40"/></td></tr> 337 338 .. _styling-widget-classes: 339 340 Styling widget classes 341 ^^^^^^^^^^^^^^^^^^^^^^ 342 343 With widgets, it is possible to add media (``css`` and ``javascript``) 344 and more deeply customise their appearance and behavior. 345 346 In a nutshell, you will need to subclass the widget 347 and either 348 :ref:`define a class "Media" <media-as-a-static-definition>` 349 as a member of the subclass, 350 or 351 :ref:`create a property "media" <dynamic-property>`, 352 returning an instance of that class. 353 354 These methods involve somewhat advanced Python programming and are 355 described in detail in the 356 :doc:`Form Media </topics/forms/media>` tutorial. 357 358 .. _base-widget-classes: 359 360 Base Widget classes 361 ------------------- 362 363 Base widget classes 364 :class:`~django.forms.widgets.Widget` 365 and 366 :class:`~django.forms.widgets.MultiWidget` 367 are subclassed by 368 all the :ref:`built-in widgets <builtin-widgets>` 369 and may serve as a foundation for the custom ones 370 (but, please see the warning below). 371 372 .. warning:: 373 374 Interfaces of classes 375 :class:`~django.forms.widgets.Widget` 376 and 377 :class:`~django.forms.widgets.MultiWidget` 378 are still in flux, 379 therefore - 380 please take care to test all of your custom widgets 381 when upgrading django. 382 It is a particularly good idea to create 383 :doc:`automated test suite </topics/testing>` 384 for any of your custom widgets. 385 386 .. currentmodule:: django.forms 387 388 .. class:: Widget(attrs=None) 389 390 .. method:: render(name, value, attrs=None) 391 392 Returns HTML for the widget, as a Unicode string. 393 This method must be implemented by the subclass, 394 otherwise ``NotImplementedError`` will be raised. 395 396 The 'value' given is not guaranteed to be valid input, 397 therefore subclass implementations should program defensively. 398 399 .. class:: MultiWidget(widgets, attrs=None) 400 401 A widget that is composed of multiple widgets. 402 :class:`~django.forms.widgets.MultiWidget` works hand in hand 403 with the :class:`~django.forms.MultiValueField`. 404 405 .. method:: render(name, value, attrs=None) 406 407 Argument `value` is handled differently in this method 408 from the subclasses of :meth:`~django.forms.widgets.Widget`. 409 410 If `value` is a list, output of 411 :meth:`~django.forms.widgets.MultiWidget.render` 412 will be a concatenation of rendered child widgets. 413 If `value` is not a list, it will be first processed 414 by the method :meth:`~django.forms.widgets.MultiWidget.decompress()` 415 to create the list, and then processed as above. 416 417 Unlike in the single value widgets, 418 method :meth:`~django.forms.widgets.MultiWidget.render` 419 should not be implemented in the subclasses 420 of :class:`~django.forms.widgets.MultiWidget`. 421 422 .. method:: decompress(value) 423 424 Returns a list of "decompressed" values 425 for the given value of the multi-value field 426 that makes use of the widget. 427 The input value can be assumed as valid, 428 but not necessarily non-empty. 429 430 This method **must be implemented** by the subclass, 431 and since the value may be empty, 432 the implementation must be defensive. 433 434 The rationale behind "decompression" is that 435 it is necessary to "split" the combined value 436 of the form field into the values of the individual fields 437 encapsulated within the multi-value field 438 (e.g. when displaying the partially or fully filled-out form). 439 440 .. tip:: 441 442 Please, note that :class:`~django.forms.MultiValueField` has 443 a complementary method :meth:`~django.forms.MultiValueField.compress` 444 with the opposite responsibility - combine cleaned values of 445 all memeber fields into one. 446 447 .. custom-widgets: 448 449 Custom Widgets 450 -------------- 451 452 Those who wish to create their own custom widgets 453 can use the APIs of classes 454 :class:`~django.forms.widgets.Widget` 455 and 456 :class:`~django.forms.widgets.MultiWidget`. 457 458 However, please do notice that those APIs 459 are subject to the future changes. 460 461 Since there are two :ref:`widget base classes <base-widget-classes>`, 462 two types of custom widgets are possible: 463 single-value widgets 464 and 465 multi-value composite widgets. 466 The patterns of their creation are somewhat different. -
docs/topics/forms/media.txt
diff --git a/docs/topics/forms/media.txt b/docs/topics/forms/media.txt index 0eb3e91..2f6b3ec 100644
a b in a form suitable for easy inclusion on your Web page. 38 38 whichever toolkit suits your requirements. Django is able to integrate 39 39 with any JavaScript toolkit. 40 40 41 .. _media-as-a-static-definition: 42 41 43 Media as a static definition 42 44 ---------------------------- 43 45 … … declaration to the media declaration:: 164 166 <script type="text/javascript" src="http://media.example.com/whizbang.js"></script> 165 167 166 168 If you require even more control over media inheritance, define your media 167 using a `dynamic property`_. Dynamic properties give you complete control over 169 using a :ref:`dynamic property <dynamic-property>` technique. 170 Dynamic properties give you complete control over 168 171 which media files are inherited, and which are not. 169 172 170 .. _dynamic property: `Media as a dynamic property`_173 .. _dynamic-property: 171 174 172 175 Media as a dynamic property 173 176 --------------------------- … … Paths in media definitions 198 201 .. versionchanged:: 1.3 199 202 200 203 Paths used to specify media can be either relative or absolute. If a path 201 starts with '/', 'http://' or 'https://', it will be interpreted as an absolute204 starts with ``/``, ``http://`` or ``https://``, it will be interpreted as an absolute 202 205 path, and left as-is. All other paths will be prepended with the value of 203 206 the appropriate prefix. 204 207