Edited changes to docs/newforms.txt from [5202]
git-svn-id: http://code.djangoproject.com/svn/django/trunk@5212 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
c7d7b6da3c
commit
6500f3fefa
|
@ -873,158 +873,304 @@ mentioned above (``required``, ``label``, ``initial``, ``widget``,
|
|||
Generating forms for models
|
||||
===========================
|
||||
|
||||
Although you can build customized forms by specifying the fields manually,
|
||||
in many cases you won't need to. Django provides helper methods to simplify the
|
||||
common cases of form creation.
|
||||
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()``
|
||||
--------------------
|
||||
|
||||
This method creates a form based upon the definition for a specific model.
|
||||
``form_for_model()`` examines the model definition, and creates a new form
|
||||
class that contains a form field for each model field that is defined.
|
||||
The method ``django.newforms.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.
|
||||
|
||||
The type of fields produced on the generated form is determined by the type
|
||||
of the model fields. For example, a ``CharField`` on a model will be
|
||||
represented with a ``CharField`` on the form. Each ``ManyToManyField``
|
||||
on the model will be represented with a ``MultipleChoiceField`` on the
|
||||
form. Each ``ForeignKey`` will be represented with a ``ChoiceField``.
|
||||
A ``ChoiceField`` is also used for any model field that has a ``choices``
|
||||
attribute specified.
|
||||
For example::
|
||||
|
||||
``form_for_model()`` returns a generated class. This class must then be
|
||||
instantiated::
|
||||
>>> from django.newforms import form_for_model
|
||||
|
||||
# Create the form class
|
||||
# Create the form class.
|
||||
>>> ArticleForm = form_for_model(Article)
|
||||
|
||||
# Create an empty form instance
|
||||
>>> f = ArticleForm()
|
||||
|
||||
The form produced by ``form_for_model`` also has a ``save()`` method. Once the
|
||||
form contains valid data, the ``save()`` method can be used to create a model
|
||||
instance with the attribute values described on the form::
|
||||
|
||||
# Create a form instance populated with POST data
|
||||
# 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 ``maxlength``
|
||||
``CommaSeparatedIntegerField`` ``CharField``
|
||||
``DateField`` ``DateField``
|
||||
``DateTimeField`` ``DateTimeField``
|
||||
``EmailField`` ``EmailField``
|
||||
``FileField`` ``CharField``
|
||||
``FilePathField`` ``CharField``
|
||||
``FloatField`` ``CharField``
|
||||
``ForeignKey`` ``ModelChoiceField`` (see below)
|
||||
``ImageField`` ``CharField``
|
||||
``IntegerField`` ``IntegerField``
|
||||
``IPAddressField`` ``CharField``
|
||||
``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``
|
||||
=============================== ========================================
|
||||
|
||||
As you might expect, the ``ForeignKey`` and ``ManyToManyField`` model field
|
||||
types are special cases:
|
||||
|
||||
* ``ForeignKey`` is represented by ``django.newforms.ModelChoiceField``,
|
||||
which is a ``ChoiceField`` whose choices are a model ``QuerySet``.
|
||||
|
||||
* ``ManyToManyField`` is represented by
|
||||
``django.newforms.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``.
|
||||
|
||||
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(maxlength=100)
|
||||
title = models.CharField(maxlength=3, choices=TITLE_CHOICES)
|
||||
birth_date = models.DateField(blank=True, null=True)
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
class Book(models.Model):
|
||||
name = models.CharField(maxlength=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 the new instance
|
||||
# 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``.
|
||||
|
||||
Using an alternate base class
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
If you want to add other methods to the generated form, you can put those
|
||||
methods onto a base class, and instruct ``form_for_model()`` to use that
|
||||
base class.
|
||||
If you want to add custom methods to the form generated by
|
||||
``form_for_model()``, write a class that extends ``django.newforms.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::
|
||||
|
||||
By default, every form produced by ``form_for_model()`` extends
|
||||
``django.newforms.forms.BaseForm``. However, if you provide a ``forms``
|
||||
argument to ``form_for_model()``, Django will use that class as the base
|
||||
for the form it generates::
|
||||
|
||||
# Create the new base class:
|
||||
# Create the new base class.
|
||||
>>> class MyBase(BaseForm):
|
||||
... def fiddle(self):
|
||||
... def my_method(self):
|
||||
... # Do whatever the method does
|
||||
|
||||
# Create the form class with a different base class
|
||||
# Create the form class with a different base class.
|
||||
>>> ArticleForm = form_for_model(Article, form=MyBase)
|
||||
|
||||
# Instantiate the form
|
||||
# Instantiate the form.
|
||||
>>> f = ArticleForm()
|
||||
|
||||
# Use the base class method
|
||||
>>> f.fiddle()
|
||||
|
||||
Putting a subset of fields on the form
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
# 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 form.
|
||||
One option is to set ``editable=False`` on the model field. ``form_for_model()``
|
||||
will not include any non-editable fields on a generated form instance.
|
||||
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:
|
||||
|
||||
However, if you just want to exclude a field from one specific form, you
|
||||
can use the ``fields`` argument. If you provide a fields argument to
|
||||
``form_for_model()``, only the fields named will be included on the form.
|
||||
For example, if you only want the 'title' and 'pub_date' attributes to be
|
||||
included on the Article form, you would call::
|
||||
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.
|
||||
|
||||
>>> PartialArticleForm = form_for_model(Article, fields=('title', 'pub_date'))
|
||||
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()``
|
||||
make sure that the fields that are *not* specified can provide default
|
||||
values, or are allowed to have a value of ``None``. If a field isn't
|
||||
specified on a form, the object created from the form can't provide
|
||||
a value for that attribute, which will prevent the new instance from
|
||||
|
||||
If you specify ``fields`` when creating a form with ``form_for_model()``,
|
||||
make sure that the fields that are *not* specified can provide default
|
||||
values, or are allowed to have a value of ``None``. If a field isn't
|
||||
specified on a form, the object created from the form can't provide
|
||||
a value for that attribute, which will prevent the new instance from
|
||||
being saved.
|
||||
|
||||
Overriding the default field types
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Although the form field types generated by ``form_for_model()`` are suitable
|
||||
for most general purposes, you may have need to override the default field
|
||||
types on a specific form. In order to do this, ``form_for_model()`` provides
|
||||
access to the *formfield callback*.
|
||||
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*.
|
||||
|
||||
The formfield callback is a function that, when provided with a model field,
|
||||
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. The default
|
||||
implementation asks the model field for an appropriate field type; however,
|
||||
any other strategy may be employed. If you need to use an alternate strategy,
|
||||
you can define your own callback, and provide it to ``form_for_model()`` using
|
||||
the ``formfield_callback`` argument.
|
||||
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``
|
||||
fields on the model, you could define the callback::
|
||||
field on the model, you could define the callback::
|
||||
|
||||
>>> def my_fields(field, **kwargs):
|
||||
>>> def my_callback(field, **kwargs):
|
||||
... if isinstance(field, models.DateField):
|
||||
... return MyDateFormField(**kwargs)
|
||||
... else:
|
||||
... else:
|
||||
... return field.formfield(**kwargs)
|
||||
|
||||
>>> ArticleForm = form_for_model(formfield_callback=my_fields)
|
||||
|
||||
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.
|
||||
>>> ArticleForm = form_for_model(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.
|
||||
|
||||
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.
|
||||
|
||||
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 very similar to ``form_for_model()``. However,
|
||||
rather than using a model class to generate a form, it uses an instance of a
|
||||
model::
|
||||
``form_for_instance()`` is like ``form_for_model()``, but it takes a model
|
||||
instance instead of a model class::
|
||||
|
||||
# Create an article
|
||||
>>> art = Article(... some data ...)
|
||||
>>> art.save()
|
||||
|
||||
# Create a form
|
||||
>>> ArticleForm = form_for_instance(art)
|
||||
|
||||
# Instantiate the form
|
||||
>>> f = ArticleForm()
|
||||
# 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
|
||||
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.
|
||||
|
||||
When you call ``save()`` on a form created by ``form_for_instance()``,
|
||||
the database instance will be updated.
|
||||
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``
|
||||
``form_for_instance()`` has ``form``, ``fields`` and ``formfield_callback``
|
||||
arguments that behave the same way as they do for ``form_for_model()``.
|
||||
|
||||
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.
|
||||
|
||||
More coming soon
|
||||
================
|
||||
|
||||
|
@ -1035,6 +1181,3 @@ what's possible.
|
|||
|
||||
If you're really itching to learn and use this library, please be patient.
|
||||
We're working hard on finishing both the code and documentation.
|
||||
|
||||
Widgets
|
||||
=======
|
||||
|
|
Loading…
Reference in New Issue