summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorRussell Keith-Magee <russell@keith-magee.com>2007-05-12 14:42:46 +0000
committerRussell Keith-Magee <russell@keith-magee.com>2007-05-12 14:42:46 +0000
commit6aa5091d58d4f9ad18601b56d39d0de5af094f52 (patch)
tree13418e959b6cc0a651cf09240faf2ea0f4e7e395 /docs
parentca5e12b4eef9969ea19ded25d970fa0b300a0519 (diff)
Added docs for form_for_model and form_for_instance, and added a fields argument so it is easy to create forms from a subset of model fields.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@5202 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'docs')
-rw-r--r--docs/newforms.txt155
1 files changed, 155 insertions, 0 deletions
diff --git a/docs/newforms.txt b/docs/newforms.txt
index ddb850f54c..5d19eeac3a 100644
--- a/docs/newforms.txt
+++ b/docs/newforms.txt
@@ -870,6 +870,161 @@ custom ``Field`` classes. To do this, just create a subclass of
mentioned above (``required``, ``label``, ``initial``, ``widget``,
``help_text``).
+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.
+
+``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 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.
+
+``form_for_model()`` returns a generated class. This class must then be
+instantiated::
+
+ # 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
+ >>> f = ArticleForm(request.POST)
+
+ # Save the new instance
+ >>> new_article = f.save()
+
+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.
+
+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:
+ >>> class MyBase(BaseForm):
+ ... def fiddle(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.fiddle()
+
+Putting 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.
+
+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::
+
+ >>> PartialArticleForm = form_for_model(Article, fields=('title', 'pub_date'))
+
+.. 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
+ 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 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.
+
+For example, if you wanted to use ``MyDateFormField`` for any ``DateField``
+fields on the model, you could define the callback::
+
+ >>> def my_fields(field, **kwargs):
+ ... if isinstance(field, models.DateField):
+ ... return MyDateFormField(**kwargs)
+ ... 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.
+
+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.
+
+``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::
+
+ # Create an article
+ >>> art = Article(... some data ...)
+ >>> art.save()
+
+ # Create a form
+ >>> ArticleForm = form_for_instance(art)
+
+ # Instantiate the form
+ >>> f = ArticleForm()
+
+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.
+
+When you call ``save()`` on a form created by ``form_for_instance()``,
+the database instance will be updated.
+
+``form_for_instance()`` has ``form``, ``fields`` and ``formfield_callback``
+arguments that behave the same way as they do for ``form_for_model()``.
+
More coming soon
================