summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorMalcolm Tredinnick <malcolm.tredinnick@gmail.com>2007-05-13 06:23:30 +0000
committerMalcolm Tredinnick <malcolm.tredinnick@gmail.com>2007-05-13 06:23:30 +0000
commit28f66bb097799f34a6ead02fe4ecafa493cee06b (patch)
tree1a80e2849772c92b3fc840487848a5222ea4d1d0 /docs
parentbc044651aaed9eedbc195414a71bde4e375a7c73 (diff)
unicode: Merged from trunk up to [5213].
git-svn-id: http://code.djangoproject.com/svn/django/branches/unicode@5214 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'docs')
-rw-r--r--docs/i18n.txt2
-rw-r--r--docs/install.txt16
-rw-r--r--docs/newforms.txt305
-rw-r--r--docs/templates_python.txt6
-rw-r--r--docs/testing.txt19
5 files changed, 324 insertions, 24 deletions
diff --git a/docs/i18n.txt b/docs/i18n.txt
index 1d7a0063b2..27abadacc9 100644
--- a/docs/i18n.txt
+++ b/docs/i18n.txt
@@ -236,7 +236,7 @@ To pluralize, specify both the singular and plural forms with the
``{% plural %}`` tag, which appears within ``{% blocktrans %}`` and
``{% endblocktrans %}``. Example::
- {% blocktrans count list|count as counter %}
+ {% blocktrans count list|length as counter %}
There is only one {{ name }} object.
{% plural %}
There are {{ counter }} {{ name }} objects.
diff --git a/docs/install.txt b/docs/install.txt
index 112a92d2f5..6be52aab0d 100644
--- a/docs/install.txt
+++ b/docs/install.txt
@@ -56,7 +56,7 @@ installed.
either ``postgresql`` [for version 1] or ``postgresql_psycopg2`` [for version 2].)
If you're on Windows, check out the unofficial `compiled Windows version`_.
-
+
* If you're using MySQL, you'll need MySQLdb_, version 1.2.1p2 or higher.
You will also want to read the database-specific notes for the `MySQL backend`_.
@@ -75,16 +75,16 @@ installed.
Remove any old versions of Django
=================================
-If you are upgrading your installation of Django from a previous version,
-you will need to uninstall the old Django version before installing the
-new version.
+If you are upgrading your installation of Django from a previous version,
+you will need to uninstall the old Django version before installing the
+new version.
If you installed Django using ``setup.py install``, uninstalling
-is as simple as deleting the ``django`` directory from your Python
+is as simple as deleting the ``django`` directory from your Python
``site-packages``.
-If you installed Django from a Python Egg, remove the Django ``.egg` file,
-and remove the reference to the egg in the file named ``easy-install.pth``.
+If you installed Django from a Python Egg, remove the Django ``.egg`` file,
+and remove the reference to the egg in the file named ``easy-install.pth``.
This file should also be located in your ``site-packages`` directory.
.. admonition:: Where are my ``site-packages`` stored?
@@ -92,7 +92,7 @@ This file should also be located in your ``site-packages`` directory.
The location of the ``site-packages`` directory depends on the operating
system, and the location in which Python was installed. However, the
following locations are common:
-
+
* If you're using Linux: ``/usr/lib/python2.X/site-packages``
* If you're using Windows: ``C:\Python2.X\lib\site-packages``
diff --git a/docs/newforms.txt b/docs/newforms.txt
index ddb850f54c..123b554bde 100644
--- a/docs/newforms.txt
+++ b/docs/newforms.txt
@@ -870,6 +870,308 @@ custom ``Field`` classes. To do this, just create a subclass of
mentioned above (``required``, ``label``, ``initial``, ``widget``,
``help_text``).
+Generating forms for models
+===========================
+
+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.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.
+
+For example::
+
+ >>> from django.newforms 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 ``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 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 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::
+
+ # 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()``,
+ 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
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+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(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::
+
+ >>> 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.
+
+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()``.
+
+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
================
@@ -880,6 +1182,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
-=======
diff --git a/docs/templates_python.txt b/docs/templates_python.txt
index 853707f58c..08a287f572 100644
--- a/docs/templates_python.txt
+++ b/docs/templates_python.txt
@@ -717,7 +717,7 @@ object::
# split_contents() knows not to split quoted strings.
tag_name, format_string = token.split_contents()
except ValueError:
- raise template.TemplateSyntaxError, "%r tag requires a single argument" % token.contents[0]
+ raise template.TemplateSyntaxError, "%r tag requires a single argument" % token.contents.split()[0]
if not (format_string[0] == format_string[-1] and format_string[0] in ('"', "'")):
raise template.TemplateSyntaxError, "%r tag's argument should be in quotes" % tag_name
return CurrentTimeNode(format_string[1:-1])
@@ -846,7 +846,7 @@ Now your tag should begin to look like this::
# split_contents() knows not to split quoted strings.
tag_name, date_to_be_formatted, format_string = token.split_contents()
except ValueError:
- raise template.TemplateSyntaxError, "%r tag requires exactly two arguments" % token.contents[0]
+ raise template.TemplateSyntaxError, "%r tag requires exactly two arguments" % token.contents.split()[0]
if not (format_string[0] == format_string[-1] and format_string[0] in ('"', "'")):
raise template.TemplateSyntaxError, "%r tag's argument should be in quotes" % tag_name
return FormatTimeNode(date_to_be_formatted, format_string[1:-1])
@@ -1080,7 +1080,7 @@ class, like so::
# Splitting by None == splitting by spaces.
tag_name, arg = token.contents.split(None, 1)
except ValueError:
- raise template.TemplateSyntaxError, "%r tag requires arguments" % token.contents[0]
+ raise template.TemplateSyntaxError, "%r tag requires arguments" % token.contents.split()[0]
m = re.search(r'(.*?) as (\w+)', arg)
if not m:
raise template.TemplateSyntaxError, "%r tag had invalid arguments" % tag_name
diff --git a/docs/testing.txt b/docs/testing.txt
index b44b67c20a..dd4e9e17b2 100644
--- a/docs/testing.txt
+++ b/docs/testing.txt
@@ -177,7 +177,7 @@ tools that can be used to establish tests and test conditions.
* `Test Client`_
* `TestCase`_
-* `Email services`_
+* `E-mail services`_
Test Client
-----------
@@ -459,9 +459,9 @@ Emptying the test outbox
**New in Django development version**
At the start of each test case, in addition to installing fixtures,
-Django clears the contents of the test email outbox.
+Django clears the contents of the test e-mail outbox.
-For more detail on email services during tests, see `Email services`_.
+For more detail on e-mail services during tests, see `E-mail services`_.
Assertions
~~~~~~~~~~
@@ -502,16 +502,17 @@ that can be useful in testing the behavior of web sites.
Assert that the template with the given name was used in rendering the
response.
-Email services
+E-mail services
--------------
+
**New in Django development version**
-If your view makes use of the `Django email services`_, you don't really
-want email to be sent every time you run a test using that view.
+If your view makes use of the `Django e-mail services`_, you don't really
+want e-mail to be sent every time you run a test using that view.
When the Django test framework is initialized, it transparently replaces the
normal `SMTPConnection`_ class with a dummy implementation that redirects all
-email to a dummy outbox. This outbox, stored as ``django.core.mail.outbox``,
+e-mail to a dummy outbox. This outbox, stored as ``django.core.mail.outbox``,
is a simple list of all `EmailMessage`_ instances that have been sent.
For example, during test conditions, it would be possible to run the following
code::
@@ -541,7 +542,7 @@ to mail.outbox::
# Empty the test outbox
mail.outbox = []
-.. _`Django email services`: ../email/
+.. _`Django e-mail services`: ../email/
.. _`SMTPConnection`: ../email/#the-emailmessage-and-smtpconnection-classes
.. _`EmailMessage`: ../email/#the-emailmessage-and-smtpconnection-classes
.. _`previously`: #emptying-the-test-outbox
@@ -669,7 +670,7 @@ a number of utility methods in the ``django.test.utils`` module.
``teardown_test_environment()``
Performs any global post-test teardown, such as removing the instrumentation
- of the template rendering system and restoring normal email services.
+ of the template rendering system and restoring normal e-mail services.
``create_test_db(verbosity=1, autoclobber=False)``
Creates a new test database, and run ``syncdb`` against it.