diff options
| author | Russell Keith-Magee <russell@keith-magee.com> | 2007-05-12 14:42:46 +0000 |
|---|---|---|
| committer | Russell Keith-Magee <russell@keith-magee.com> | 2007-05-12 14:42:46 +0000 |
| commit | 6aa5091d58d4f9ad18601b56d39d0de5af094f52 (patch) | |
| tree | 13418e959b6cc0a651cf09240faf2ea0f4e7e395 /docs | |
| parent | ca5e12b4eef9969ea19ded25d970fa0b300a0519 (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.txt | 155 |
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 ================ |
