Django

Code

root/django/trunk/docs/form_for_model.txt

Revision 7294, 17.0 kB (checked in by mtredinnick, 4 months ago)

Added "svn:eol-style native" to every text file in the tree (*.txt, *.html,
*.py, *.xml and AUTHORS, etc). Added "svn:ignore *.pyc" to some directories in
tests/regressiontests/ that were previously missing it.

Fixed #6545, #6801.

  • Property svn:eol-style set to native
Line 
1 Generating forms for models
2 ===========================
3
4 .. admonition:: Note
5
6     The APIs described in this document have been deprecated. If you're
7     developing new code, use `ModelForms`_ instead.
8
9 .. _ModelForms: ../modelforms/
10
11 If you're building a database-driven app, chances are you'll have forms that
12 map closely to Django models. For instance, you might have a ``BlogComment``
13 model, and you want to create a form that lets people submit comments. In this
14 case, it would be redundant to define the field types in your form, because
15 you've already defined the fields in your model.
16
17 For this reason, Django provides a few helper functions that let you create a
18 ``Form`` class from a Django model.
19
20 ``form_for_model()``
21 --------------------
22
23 The method ``django.newforms.form_for_model()`` creates a form based on the
24 definition of a specific model. Pass it the model class, and it will return a
25 ``Form`` class that contains a form field for each model field.
26
27 For example::
28
29     >>> from django.newforms import form_for_model
30
31     # Create the form class.
32     >>> ArticleForm = form_for_model(Article)
33
34     # Create an empty form instance.
35     >>> f = ArticleForm()
36
37 It bears repeating that ``form_for_model()`` takes the model *class*, not a
38 model instance, and it returns a ``Form`` *class*, not a ``Form`` instance.
39
40 Field types
41 ~~~~~~~~~~~
42
43 The generated ``Form`` class will have a form field for every model field. Each
44 model field has a corresponding default form field. For example, a
45 ``CharField`` on a model is represented as a ``CharField`` on a form. A
46 model ``ManyToManyField`` is represented as a ``MultipleChoiceField``. Here is
47 the full list of conversions:
48
49     ===============================  ========================================
50     Model field                      Form field
51     ===============================  ========================================
52     ``AutoField``                    Not represented in the form
53     ``BooleanField``                 ``BooleanField``
54     ``CharField``                    ``CharField`` with ``max_length`` set to
55                                      the model field's ``max_length``
56     ``CommaSeparatedIntegerField``   ``CharField``
57     ``DateField``                    ``DateField``
58     ``DateTimeField``                ``DateTimeField``
59     ``DecimalField``                 ``DecimalField``
60     ``EmailField``                   ``EmailField``
61     ``FileField``                    ``FileField``
62     ``FilePathField``                ``CharField``
63     ``FloatField``                   ``FloatField``
64     ``ForeignKey``                   ``ModelChoiceField`` (see below)
65     ``ImageField``                   ``ImageField``
66     ``IntegerField``                 ``IntegerField``
67     ``IPAddressField``               ``IPAddressField``
68     ``ManyToManyField``              ``ModelMultipleChoiceField`` (see
69                                      below)
70     ``NullBooleanField``             ``CharField``
71     ``PhoneNumberField``             ``USPhoneNumberField``
72                                      (from ``django.contrib.localflavor.us``)
73     ``PositiveIntegerField``         ``IntegerField``
74     ``PositiveSmallIntegerField``    ``IntegerField``
75     ``SlugField``                    ``CharField``
76     ``SmallIntegerField``            ``IntegerField``
77     ``TextField``                    ``CharField`` with ``widget=Textarea``
78     ``TimeField``                    ``TimeField``
79     ``URLField``                     ``URLField`` with ``verify_exists`` set
80                                      to the model field's ``verify_exists``
81     ``USStateField``                 ``CharField`` with
82                                      ``widget=USStateSelect``
83                                      (``USStateSelect`` is from
84                                      ``django.contrib.localflavor.us``)
85     ``XMLField``                     ``CharField`` with ``widget=Textarea``
86     ===============================  ========================================
87
88
89 .. note::
90     The ``FloatField`` form field and ``DecimalField`` model and form fields
91     are new in the development version.
92
93 As you might expect, the ``ForeignKey`` and ``ManyToManyField`` model field
94 types are special cases:
95
96     * ``ForeignKey`` is represented by ``django.newforms.ModelChoiceField``,
97       which is a ``ChoiceField`` whose choices are a model ``QuerySet``.
98
99     * ``ManyToManyField`` is represented by
100       ``django.newforms.ModelMultipleChoiceField``, which is a
101       ``MultipleChoiceField`` whose choices are a model ``QuerySet``.
102
103 In addition, each generated form field has attributes set as follows:
104
105     * If the model field has ``blank=True``, then ``required`` is set to
106       ``False`` on the form field. Otherwise, ``required=True``.
107
108     * The form field's ``label`` is set to the ``verbose_name`` of the model
109       field, with the first character capitalized.
110
111     * The form field's ``help_text`` is set to the ``help_text`` of the model
112       field.
113
114     * If the model field has ``choices`` set, then the form field's ``widget``
115       will be set to ``Select``, with choices coming from the model field's
116       ``choices``. The choices will normally include the blank choice which is
117       selected by default. If the field is required, this forces the user to
118       make a selection. The blank choice will not be included if the model
119       field has ``blank=False`` and an explicit ``default`` value (the
120       ``default`` value will be initially selected instead).
121
122 Finally, note that you can override the form field used for a given model
123 field. See "Overriding the default field types" below.
124
125 A full example
126 ~~~~~~~~~~~~~~
127
128 Consider this set of models::
129
130     from django.db import models
131
132     TITLE_CHOICES = (
133         ('MR', 'Mr.'),
134         ('MRS', 'Mrs.'),
135         ('MS', 'Ms.'),
136     )
137
138     class Author(models.Model):
139         name = models.CharField(max_length=100)
140         title = models.CharField(max_length=3, choices=TITLE_CHOICES)
141         birth_date = models.DateField(blank=True, null=True)
142
143         def __unicode__(self):
144             return self.name
145
146     class Book(models.Model):
147         name = models.CharField(max_length=100)
148         authors = models.ManyToManyField(Author)
149
150 With these models, a call to ``form_for_model(Author)`` would return a ``Form``
151 class equivalent to this::
152
153     class AuthorForm(forms.Form):
154         name = forms.CharField(max_length=100)
155         title = forms.CharField(max_length=3,
156                     widget=forms.Select(choices=TITLE_CHOICES))
157         birth_date = forms.DateField(required=False)
158
159 A call to ``form_for_model(Book)`` would return a ``Form`` class equivalent to
160 this::
161
162     class BookForm(forms.Form):
163         name = forms.CharField(max_length=100)
164         authors = forms.ModelMultipleChoiceField(queryset=Author.objects.all())
165
166 The ``save()`` method
167 ~~~~~~~~~~~~~~~~~~~~~
168
169 Every form produced by ``form_for_model()`` also has a ``save()`` method. This
170 method creates and saves a database object from the data bound to the form. For
171 example::
172
173     # Create a form instance from POST data.
174     >>> f = ArticleForm(request.POST)
175
176     # Save a new Article object from the form's data.
177     >>> new_article = f.save()
178
179 Note that ``save()`` will raise a ``ValueError`` if the data in the form
180 doesn't validate -- i.e., ``if form.errors``.
181
182 This ``save()`` method accepts an optional ``commit`` keyword argument, which
183 accepts either ``True`` or ``False``. If you call ``save()`` with
184 ``commit=False``, then it will return an object that hasn't yet been saved to
185 the database. In this case, it's up to you to call ``save()`` on the resulting
186 model instance. This is useful if you want to do custom processing on the
187 object before saving it. ``commit`` is ``True`` by default.
188
189 Another side effect of using ``commit=False`` is seen when your model has
190 a many-to-many relation with another model. If your model has a many-to-many
191 relation and you specify ``commit=False`` when you save a form, Django cannot
192 immediately save the form data for the many-to-many relation. This is because
193 it isn't possible to save many-to-many data for an instance until the instance
194 exists in the database.
195
196 To work around this problem, every time you save a form using ``commit=False``,
197 Django adds a ``save_m2m()`` method to the form created by ``form_for_model``.
198 After you've manually saved the instance produced by the form, you can invoke
199 ``save_m2m()`` to save the many-to-many form data. For example::
200
201     # Create a form instance with POST data.
202     >>> f = AuthorForm(request.POST)
203
204     # Create, but don't save the new author instance.
205     >>> new_author = f.save(commit=False)
206
207     # Modify the author in some way.
208     >>> new_author.some_field = 'some_value'
209
210     # Save the new instance.
211     >>> new_author.save()
212
213     # Now, save the many-to-many data for the form.
214     >>> f.save_m2m()
215
216 Calling ``save_m2m()`` is only required if you use ``save(commit=False)``.
217 When you use a simple ``save()`` on a form, all data -- including
218 many-to-many data -- is saved without the need for any additional method calls.
219 For example::
220
221     # Create a form instance with POST data.
222     >>> f = AuthorForm(request.POST)
223
224     # Create and save the new author instance. There's no need to do anything else.
225     >>> new_author = f.save()
226
227 Using an alternate base class
228 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
229
230 If you want to add custom methods to the form generated by
231 ``form_for_model()``, write a class that extends ``django.newforms.BaseForm``
232 and contains your custom methods. Then, use the ``form`` argument to
233 ``form_for_model()`` to tell it to use your custom form as its base class.
234 For example::
235
236     # Create the new base class.
237     >>> class MyBase(BaseForm):
238     ...     def my_method(self):
239     ...         # Do whatever the method does
240
241     # Create the form class with a different base class.
242     >>> ArticleForm = form_for_model(Article, form=MyBase)
243
244     # Instantiate the form.
245     >>> f = ArticleForm()
246
247     # Use the base class method.
248     >>> f.my_method()
249
250 Using a subset of fields on the form
251 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
252
253 **New in Django development version**
254
255 In some cases, you may not want all the model fields to appear on the generated
256 form. There are two ways of telling ``form_for_model()`` to use only a subset
257 of the model fields:
258
259     1. Set ``editable=False`` on the model field. As a result, *any* form
260        created from the model via ``form_for_model()`` will not include that
261        field.
262
263     2. Use the ``fields`` argument to ``form_for_model()``. This argument, if
264        given, should be a list of field names to include in the form.
265
266        For example, if you want a form for the ``Author`` model (defined above)
267        that includes only the ``name`` and ``title`` fields, you would specify
268        ``fields`` like this::
269
270            PartialArticleForm = form_for_model(Author, fields=('name', 'title'))
271
272 .. note::
273
274     If you specify ``fields`` when creating a form with ``form_for_model()``,
275     then the fields that are *not* specified will not be set by the form's
276     ``save()`` method. Django will prevent any attempt to save an incomplete
277     model, so if the model does not allow the missing fields to be empty, and
278     does not provide a default value for the missing fields, any attempt to
279     ``save()`` a ``form_for_model`` with missing fields will fail. To avoid
280     this failure, you must use ``save(commit=False)`` and manually set any
281     extra required fields::
282
283         instance = form.save(commit=False)
284         instance.required_field = 'new value'
285         instance.save()
286
287     See the `section on saving forms`_ for more details on using
288     ``save(commit=False)``.
289
290 .. _section on saving forms: `The save() method`_
291
292 Overriding the default field types
293 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
294
295 The default field types, as described in the "Field types" table above, are
296 sensible defaults; if you have a ``DateField`` in your model, chances are you'd
297 want that to be represented as a ``DateField`` in your form. But
298 ``form_for_model()`` gives you the flexibility of changing the form field type
299 for a given model field. You do this by specifying a **formfield callback**.
300
301 A formfield callback is a function that, when provided with a model field,
302 returns a form field instance. When constructing a form, ``form_for_model()``
303 asks the formfield callback to provide form field types.
304
305 By default, ``form_for_model()`` calls the ``formfield()`` method on the model
306 field::
307
308     def default_callback(field, **kwargs):
309         return field.formfield(**kwargs)
310
311 The ``kwargs`` are any keyword arguments that might be passed to the form
312 field, such as ``required=True`` or ``label='Foo'``.
313
314 For example, if you wanted to use ``MyDateFormField`` for any ``DateField``
315 field on the model, you could define the callback::
316
317     >>> def my_callback(field, **kwargs):
318     ...     if isinstance(field, models.DateField):
319     ...         return MyDateFormField(**kwargs)
320     ...     else:
321     ...         return field.formfield(**kwargs)
322
323     >>> ArticleForm = form_for_model(Article, formfield_callback=my_callback)
324
325 Note that your callback needs to handle *all* possible model field types, not
326 just the ones that you want to behave differently to the default. That's why
327 this example has an ``else`` clause that implements the default behavior.
328
329 .. warning::
330     The field that is passed into the ``formfield_callback`` function in
331     ``form_for_model()`` and ``form_for_instance`` is the field instance from
332     your model's class. You **must not** alter that object at all; treat it
333     as read-only!
334
335     If you make any alterations to that object, it will affect any future
336     users of the model class, because you will have changed the field object
337     used to construct the class. This is almost certainly what you don't want
338     to have happen.
339
340 Finding the model associated with a form
341 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
342
343 The model class that was used to construct the form is available
344 using the ``_model`` property of the generated form::
345
346     >>> ArticleForm = form_for_model(Article)
347     >>> ArticleForm._model
348     <class 'myapp.models.Article'>
349
350 ``form_for_instance()``
351 -----------------------
352
353 ``form_for_instance()`` is like ``form_for_model()``, but it takes a model
354 instance instead of a model class::
355
356     # Create an Author.
357     >>> a = Author(name='Joe Smith', title='MR', birth_date=None)
358     >>> a.save()
359
360     # Create a form for this particular Author.
361     >>> AuthorForm = form_for_instance(a)
362
363     # Instantiate the form.
364     >>> f = AuthorForm()
365
366 When a form created by ``form_for_instance()`` is created, the initial data
367 values for the form fields are drawn from the instance. However, this data is
368 not bound to the form. You will need to bind data to the form before the form
369 can be saved.
370
371 Unlike ``form_for_model()``, a choice field in form created by
372 ``form_for_instance()`` will not include the blank choice if the respective
373 model field has ``blank=False``. The initial choice is drawn from the instance.
374
375 When you call ``save()`` on a form created by ``form_for_instance()``,
376 the database instance will be updated. As in ``form_for_model()``, ``save()``
377 will raise ``ValueError`` if the data doesn't validate.
378
379 ``form_for_instance()`` has ``form``, ``fields`` and ``formfield_callback``
380 arguments that behave the same way as they do for ``form_for_model()``.
381
382 Let's modify the earlier `contact form`_ view example a little bit. Suppose we
383 have a ``Message`` model that holds each contact submission. Something like::
384
385     class Message(models.Model):
386         subject = models.CharField(max_length=100)
387         message = models.TextField()
388         sender = models.EmailField()
389         cc_myself = models.BooleanField(required=False)
390
391 You could use this model to create a form (using ``form_for_model()``). You
392 could also use existing ``Message`` instances to create a form for editing
393 messages. The `simple example view`_ can be changed slightly to accept the ``id`` value
394 of an existing ``Message`` and present it for editing::
395
396     def contact_edit(request, msg_id):
397         # Create the form from the message id.
398         message = get_object_or_404(Message, id=msg_id)
399         ContactForm = form_for_instance(message)
400
401         if request.method == 'POST':
402             form = ContactForm(request.POST)
403             if form.is_valid():
404                 form.save()
405                 return HttpResponseRedirect('/url/on_success/')
406         else:
407             form = ContactForm()
408         return render_to_response('contact.html', {'form': form})
409
410 Aside from how we create the ``ContactForm`` class here, the main point to
411 note is that the form display in the ``GET`` branch of the function
412 will use the values from the ``message`` instance as initial values for the
413 form field.
414
415 .. _contact form: ../newforms/#simple-view-example
416 .. _`simple example view`: ../newforms/#simple-view-example
417
418 When should you use ``form_for_model()`` and ``form_for_instance()``?
419 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
420
421 The ``form_for_model()`` and ``form_for_instance()`` functions are meant to be
422 shortcuts for the common case. If you want to create a form whose fields map to
423 more than one model, or a form that contains fields that *aren't* on a model,
424 you shouldn't use these shortcuts. Creating a ``Form`` class the "long" way
425 isn't that difficult, after all.
Note: See TracBrowser for help on using the browser.