django / docs / form_for_model.txt

  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
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
Generating forms for models
===========================

.. admonition:: Note

    The APIs described in this document have been deprecated. If you're
    developing new code, use `ModelForms`_ instead.

.. _ModelForms: ../modelforms/

If you're building a database-driven app, chances are you'll have forms that
map closely to Django models. For instance, you might have a ``BlogComment``
model, and you want to create a form that lets people submit comments. In this
case, it would be redundant to define the field types in your form, because
you've already defined the fields in your model.

For this reason, Django provides a few helper functions that let you create a
``Form`` class from a Django model.

``form_for_model()``
--------------------

The method ``django.forms.form_for_model()`` creates a form based on the
definition of a specific model. Pass it the model class, and it will return a
``Form`` class that contains a form field for each model field.

For example::

    >>> from django.forms import form_for_model

    # Create the form class.
    >>> ArticleForm = form_for_model(Article)

    # Create an empty form instance.
    >>> f = ArticleForm()

It bears repeating that ``form_for_model()`` takes the model *class*, not a
model instance, and it returns a ``Form`` *class*, not a ``Form`` instance.

Field types
~~~~~~~~~~~

The generated ``Form`` class will have a form field for every model field. Each
model field has a corresponding default form field. For example, a
``CharField`` on a model is represented as a ``CharField`` on a form. A
model ``ManyToManyField`` is represented as a ``MultipleChoiceField``. Here is
the full list of conversions:

    ===============================  ========================================
    Model field                      Form field
    ===============================  ========================================
    ``AutoField``                    Not represented in the form
    ``BooleanField``                 ``BooleanField``
    ``CharField``                    ``CharField`` with ``max_length`` set to
                                     the model field's ``max_length``
    ``CommaSeparatedIntegerField``   ``CharField``
    ``DateField``                    ``DateField``
    ``DateTimeField``                ``DateTimeField``
    ``DecimalField``                 ``DecimalField``
    ``EmailField``                   ``EmailField``
    ``FileField``                    ``FileField``
    ``FilePathField``                ``CharField``
    ``FloatField``                   ``FloatField``
    ``ForeignKey``                   ``ModelChoiceField`` (see below)
    ``ImageField``                   ``ImageField``
    ``IntegerField``                 ``IntegerField``
    ``IPAddressField``               ``IPAddressField``
    ``ManyToManyField``              ``ModelMultipleChoiceField`` (see
                                     below)
    ``NullBooleanField``             ``CharField``
    ``PhoneNumberField``             ``USPhoneNumberField``
                                     (from ``django.contrib.localflavor.us``)
    ``PositiveIntegerField``         ``IntegerField``
    ``PositiveSmallIntegerField``    ``IntegerField``
    ``SlugField``                    ``CharField``
    ``SmallIntegerField``            ``IntegerField``
    ``TextField``                    ``CharField`` with ``widget=Textarea``
    ``TimeField``                    ``TimeField``
    ``URLField``                     ``URLField`` with ``verify_exists`` set
                                     to the model field's ``verify_exists``
    ``USStateField``                 ``CharField`` with
                                     ``widget=USStateSelect``
                                     (``USStateSelect`` is from
                                     ``django.contrib.localflavor.us``)
    ``XMLField``                     ``CharField`` with ``widget=Textarea``
    ===============================  ========================================


.. note::
    The ``FloatField`` form field and ``DecimalField`` model and form fields
    are new in the development version.

As you might expect, the ``ForeignKey`` and ``ManyToManyField`` model field
types are special cases:

    * ``ForeignKey`` is represented by ``django.forms.ModelChoiceField``,
      which is a ``ChoiceField`` whose choices are a model ``QuerySet``.

    * ``ManyToManyField`` is represented by
      ``django.forms.ModelMultipleChoiceField``, which is a
      ``MultipleChoiceField`` whose choices are a model ``QuerySet``.

In addition, each generated form field has attributes set as follows:

    * If the model field has ``blank=True``, then ``required`` is set to
      ``False`` on the form field. Otherwise, ``required=True``.

    * The form field's ``label`` is set to the ``verbose_name`` of the model
      field, with the first character capitalized.

    * The form field's ``help_text`` is set to the ``help_text`` of the model
      field.

    * If the model field has ``choices`` set, then the form field's ``widget``
      will be set to ``Select``, with choices coming from the model field's
      ``choices``. The choices will normally include the blank choice which is
      selected by default. If the field is required, this forces the user to
      make a selection. The blank choice will not be included if the model
      field has ``blank=False`` and an explicit ``default`` value (the
      ``default`` value will be initially selected instead).

Finally, note that you can override the form field used for a given model
field. See "Overriding the default field types" below.

A full example
~~~~~~~~~~~~~~

Consider this set of models::

    from django.db import models

    TITLE_CHOICES = (
        ('MR', 'Mr.'),
        ('MRS', 'Mrs.'),
        ('MS', 'Ms.'),
    )

    class Author(models.Model):
        name = models.CharField(max_length=100)
        title = models.CharField(max_length=3, choices=TITLE_CHOICES)
        birth_date = models.DateField(blank=True, null=True)

        def __unicode__(self):
            return self.name

    class Book(models.Model):
        name = models.CharField(max_length=100)
        authors = models.ManyToManyField(Author)

With these models, a call to ``form_for_model(Author)`` would return a ``Form``
class equivalent to this::

    class AuthorForm(forms.Form):
        name = forms.CharField(max_length=100)
        title = forms.CharField(max_length=3,
                    widget=forms.Select(choices=TITLE_CHOICES))
        birth_date = forms.DateField(required=False)

A call to ``form_for_model(Book)`` would return a ``Form`` class equivalent to
this::

    class BookForm(forms.Form):
        name = forms.CharField(max_length=100)
        authors = forms.ModelMultipleChoiceField(queryset=Author.objects.all())

The ``save()`` method
~~~~~~~~~~~~~~~~~~~~~

Every form produced by ``form_for_model()`` also has a ``save()`` method. This
method creates and saves a database object from the data bound to the form. For
example::

    # Create a form instance from POST data.
    >>> f = ArticleForm(request.POST)

    # Save a new Article object from the form's data.
    >>> new_article = f.save()

Note that ``save()`` will raise a ``ValueError`` if the data in the form
doesn't validate -- i.e., ``if form.errors``.

This ``save()`` method accepts an optional ``commit`` keyword argument, which
accepts either ``True`` or ``False``. If you call ``save()`` with
``commit=False``, then it will return an object that hasn't yet been saved to
the database. In this case, it's up to you to call ``save()`` on the resulting
model instance. This is useful if you want to do custom processing on the
object before saving it. ``commit`` is ``True`` by default.

Another side effect of using ``commit=False`` is seen when your model has
a many-to-many relation with another model. If your model has a many-to-many
relation and you specify ``commit=False`` when you save a form, Django cannot
immediately save the form data for the many-to-many relation. This is because
it isn't possible to save many-to-many data for an instance until the instance
exists in the database.

To work around this problem, every time you save a form using ``commit=False``,
Django adds a ``save_m2m()`` method to the form created by ``form_for_model``.
After you've manually saved the instance produced by the form, you can invoke
``save_m2m()`` to save the many-to-many form data. For example::

    # Create a form instance with POST data.
    >>> f = AuthorForm(request.POST)

    # Create, but don't save the new author instance.
    >>> new_author = f.save(commit=False)

    # Modify the author in some way.
    >>> new_author.some_field = 'some_value'

    # Save the new instance.
    >>> new_author.save()

    # Now, save the many-to-many data for the form.
    >>> f.save_m2m()

Calling ``save_m2m()`` is only required if you use ``save(commit=False)``.
When you use a simple ``save()`` on a form, all data -- including
many-to-many data -- is saved without the need for any additional method calls.
For example::

    # Create a form instance with POST data.
    >>> f = AuthorForm(request.POST)

    # Create and save the new author instance. There's no need to do anything else.
    >>> new_author = f.save()

Using an alternate base class
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

If you want to add custom methods to the form generated by
``form_for_model()``, write a class that extends ``django.forms.BaseForm``
and contains your custom methods. Then, use the ``form`` argument to
``form_for_model()`` to tell it to use your custom form as its base class.
For example::

    # Create the new base class.
    >>> class MyBase(BaseForm):
    ...     def my_method(self):
    ...         # Do whatever the method does

    # Create the form class with a different base class.
    >>> ArticleForm = form_for_model(Article, form=MyBase)

    # Instantiate the form.
    >>> f = ArticleForm()

    # Use the base class method.
    >>> f.my_method()

Using a subset of fields on the form
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

**New in Django development version**

In some cases, you may not want all the model fields to appear on the generated
form. There are two ways of telling ``form_for_model()`` to use only a subset
of the model fields:

    1. Set ``editable=False`` on the model field. As a result, *any* form
       created from the model via ``form_for_model()`` will not include that
       field.

    2. Use the ``fields`` argument to ``form_for_model()``. This argument, if
       given, should be a list of field names to include in the form.

       For example, if you want a form for the ``Author`` model (defined above)
       that includes only the ``name`` and ``title`` fields, you would specify
       ``fields`` like this::

           PartialArticleForm = form_for_model(Author, fields=('name', 'title'))

.. note::

    If you specify ``fields`` when creating a form with ``form_for_model()``,
    then the fields that are *not* specified will not be set by the form's
    ``save()`` method. Django will prevent any attempt to save an incomplete
    model, so if the model does not allow the missing fields to be empty, and
    does not provide a default value for the missing fields, any attempt to
    ``save()`` a ``form_for_model`` with missing fields will fail. To avoid
    this failure, you must use ``save(commit=False)`` and manually set any
    extra required fields::

        instance = form.save(commit=False)
        instance.required_field = 'new value'
        instance.save()

    See the `section on saving forms`_ for more details on using
    ``save(commit=False)``.

.. _section on saving forms: `The save() method`_

Overriding the default field types
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The default field types, as described in the "Field types" table above, are
sensible defaults; if you have a ``DateField`` in your model, chances are you'd
want that to be represented as a ``DateField`` in your form. But
``form_for_model()`` gives you the flexibility of changing the form field type
for a given model field. You do this by specifying a **formfield callback**.

A formfield callback is a function that, when provided with a model field,
returns a form field instance. When constructing a form, ``form_for_model()``
asks the formfield callback to provide form field types.

By default, ``form_for_model()`` calls the ``formfield()`` method on the model
field::

    def default_callback(field, **kwargs):
        return field.formfield(**kwargs)

The ``kwargs`` are any keyword arguments that might be passed to the form
field, such as ``required=True`` or ``label='Foo'``.

For example, if you wanted to use ``MyDateFormField`` for any ``DateField``
field on the model, you could define the callback::

    >>> def my_callback(field, **kwargs):
    ...     if isinstance(field, models.DateField):
    ...         return MyDateFormField(**kwargs)
    ...     else:
    ...         return field.formfield(**kwargs)

    >>> ArticleForm = form_for_model(Article, formfield_callback=my_callback)

Note that your callback needs to handle *all* possible model field types, not
just the ones that you want to behave differently to the default. That's why
this example has an ``else`` clause that implements the default behavior.

.. warning::
    The field that is passed into the ``formfield_callback`` function in
    ``form_for_model()`` and ``form_for_instance`` is the field instance from
    your model's class. You **must not** alter that object at all; treat it
    as read-only!

    If you make any alterations to that object, it will affect any future
    users of the model class, because you will have changed the field object
    used to construct the class. This is almost certainly what you don't want
    to have happen.

Finding the model associated with a form
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The model class that was used to construct the form is available
using the ``_model`` property of the generated form::

    >>> ArticleForm = form_for_model(Article)
    >>> ArticleForm._model
    <class 'myapp.models.Article'>

``form_for_instance()``
-----------------------

``form_for_instance()`` is like ``form_for_model()``, but it takes a model
instance instead of a model class::

    # Create an Author.
    >>> a = Author(name='Joe Smith', title='MR', birth_date=None)
    >>> a.save()

    # Create a form for this particular Author.
    >>> AuthorForm = form_for_instance(a)

    # Instantiate the form.
    >>> f = AuthorForm()

When a form created by ``form_for_instance()`` is created, the initial data
values for the form fields are drawn from the instance. However, this data is
not bound to the form. You will need to bind data to the form before the form
can be saved.

Unlike ``form_for_model()``, a choice field in form created by
``form_for_instance()`` will not include the blank choice if the respective
model field has ``blank=False``. The initial choice is drawn from the instance.

When you call ``save()`` on a form created by ``form_for_instance()``,
the database instance will be updated. As in ``form_for_model()``, ``save()``
will raise ``ValueError`` if the data doesn't validate.

``form_for_instance()`` has ``form``, ``fields`` and ``formfield_callback``
arguments that behave the same way as they do for ``form_for_model()``.

Let's modify the earlier `contact form`_ view example a little bit. Suppose we
have a ``Message`` model that holds each contact submission. Something like::

    class Message(models.Model):
        subject = models.CharField(max_length=100)
        message = models.TextField()
        sender = models.EmailField()
        cc_myself = models.BooleanField(required=False)

You could use this model to create a form (using ``form_for_model()``). You
could also use existing ``Message`` instances to create a form for editing
messages. The `simple example view`_ can be changed slightly to accept the ``id`` value
of an existing ``Message`` and present it for editing::

    def contact_edit(request, msg_id):
        # Create the form from the message id.
        message = get_object_or_404(Message, id=msg_id)
        ContactForm = form_for_instance(message)

        if request.method == 'POST':
            form = ContactForm(request.POST)
            if form.is_valid():
                form.save()
                return HttpResponseRedirect('/url/on_success/')
        else:
            form = ContactForm()
        return render_to_response('contact.html', {'form': form})

Aside from how we create the ``ContactForm`` class here, the main point to
note is that the form display in the ``GET`` branch of the function
will use the values from the ``message`` instance as initial values for the
form field.

.. _contact form: ../forms/#simple-view-example
.. _`simple example view`: ../forms/#simple-view-example

When should you use ``form_for_model()`` and ``form_for_instance()``?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

The ``form_for_model()`` and ``form_for_instance()`` functions are meant to be
shortcuts for the common case. If you want to create a form whose fields map to
more than one model, or a form that contains fields that *aren't* on a model,
you shouldn't use these shortcuts. Creating a ``Form`` class the "long" way
isn't that difficult, after all.
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.