File: differences.rst

package info (click to toggle)
django-floppyforms 1.2.0-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 1,740 kB
  • ctags: 1,008
  • sloc: python: 4,477; makefile: 120
file content (162 lines) | stat: -rw-r--r-- 5,791 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
Differences with django.forms
=============================

So, you have a project already using ``django.forms``, and you're considering
a switch to floppyforms? Here's what you need to know, assuming the only
change you've made to your code is a simple change, from:

.. code-block:: python

    from django import forms


to:

.. code-block:: python

    import floppyforms as forms

.. note:: ``django.forms.*`` modules

    Other modules contained by ``django.forms``, such as ``forms``, ``utils``
    and ``formsets`` have not been aliased.

HTML 5 forms!
-------------

Floppyforms adds a couple of HTML 5 features on top of the standard Django
widgets: HTML syntax, more native widget types, the ``required`` attribute and
client-side validation.

HTML syntax instead of XHTML
````````````````````````````

Floppyforms uses an HTML syntax instead of Django's XHTML syntax. You will see
``<input type="text" ... >`` and not ``<input type="text" />``.

Native widget types
```````````````````

Floppyforms tries to use the native HTML5 widgets whenever it's possible. Thus
some widgets which used to be simple ``TextInputs`` in ``django.forms`` are
now specific input that will render as ``<input type="...">`` with the HTML5
types such as ``url``, ``email``. See :ref:`widgets` for a detailed list of
specific widgets.

For instance, if you have declared a form using django.forms:

.. code-block:: python

    class ThisForm(forms.Form):
        date = forms.DateField()

The ``date`` field will be rendered as an ``<input type="text">``. However, by
just changing the forms library to floppyforms, the input will be an ``<input
type="date">``.

Required attribute
``````````````````

In addition to the various input types, every required field has the
``required`` attribute set to ``True`` on its widget. That means that every
``<input>`` widget for a required field will be rendered as ``<input
type="..." ... required>``. This is used for client-side validation: for
instance, Firefox 4 won't let the user submit the form unless he's filled the
input. This saves HTTP requests but doesn't mean you can stop validating user
input.

Client-side validation
``````````````````````

Like with the ``required`` attribute, the ``pattern`` attribute is especially
interesting for slightly more complex client-side validation. The ``SlugField``
and the ``IPAddressField`` both have a pattern attached to the ``<input>``.

However having these validations backed directly into the HTML and therefore
allowing the browser to validate the user input might not always what you want
to have. Sometimes you just want to have a form where it should be allowed to
submit invalid data. In that case you can use the ``novalidate`` attribute on
the ``<form>`` HTML tag or the ``formnovalidate`` attribute on the submit
button:

.. code-block:: html

    <form action="" novalidate>
        This input will not be validated:
        <input type="text" required />
    </form>

    <form action="">
        Another way to not validate the form in the browser is using the
        formnovalidate attribute on the submit button:
        <input type="submit" value="cancel" formnovalidate>
    </form>

Read the corresponding documentation for `novalidate`_ and `formnovalidate`_ on
the Mozilla Developer Network if you want to know more.

.. _novalidate: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form#attr-novalidate
.. _formnovalidate: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attr-formnovalidate

ModelForms
----------

Prior to version 1.2 of django-floppyforms, you had to take some manual
efforts to make your modelforms work with floppyforms. This is now done
seemlesly, but since this was introduced a backwards incompatible change, it
was necessary to provde a deprecation path.

So if you start out new with django-floppyforms just use ``import
floppyforms.__future__ as forms`` as your import instead of ``import
floppyforms as forms`` when you want to define modelforms.

For more information see the :ref:`section about modelforms in the usage
documentation <usage-modelforms>`.

``TEMPLATE_STRING_IF_INVALID`` caveats
--------------------------------------

The use of a non-empty ``TEMPLATE_STRING_IF_INVALID`` setting can impact
rendering. Missing template variables are rendered using the content of ``TEMPLATE_STRING_IF_INVALID`` but filters used on non-existing variables are not applied (see `django's documentation on how invalid template variables are
handled`__ for more details).

__ https://docs.djangoproject.com/en/dev/ref/templates/api/#invalid-template-variables

django-floppyforms assumes in its predefined form layouts that
all filters are applied. You can work around this by making your
``TEMPLATE_STRING_IF_INVALID`` evaluate to ``False`` but still keep its
string representation. Here is an example how you could achieve this in your
``settings.py``:

.. code-block:: python

    # on Python 2
    class InvalidVariable(unicode):
        def __nonzero__(self):
            return False

    # on Python 3
    class InvalidVariable(str):
        def __bool__(self):
            return False

    TEMPLATE_STRING_IF_INVALID = InvalidVariable(u'INVALID')

Getting back Django's behaviour
-------------------------------

If you need to get the same output as standard Django forms:

* Override ``floppyforms/input.html``, ``floppyforms/radio.html``,
  ``floppyforms/clearable_input.html`` and
  ``floppyforms/checkbox_select.html`` to use an XHTML syntax

* Remove the ``required`` attribute from the templates as well

* Make sure your fields which have HTML5 widgets by default get simple
  ``TextInputs`` instead:

  .. code-block:: python

      class Foo(forms.Form):
          url = forms.URLField(widget=forms.TextInput)