mirror of
https://github.com/django/django.git
synced 2025-10-24 06:06:09 +00:00
newforms-admin: Merged changes from trunk up to [6863].
git-svn-id: http://code.djangoproject.com/svn/django/branches/newforms-admin@6864 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
@@ -58,6 +58,17 @@ See the `csrf documentation`_.
|
||||
|
||||
.. _csrf documentation: ../csrf/
|
||||
|
||||
flatpages
|
||||
=========
|
||||
|
||||
A framework for managing simple "flat" HTML content in a database.
|
||||
|
||||
See the `flatpages documentation`_.
|
||||
|
||||
.. _flatpages documentation: ../flatpages/
|
||||
|
||||
Requires the sites_ contrib package to be installed as well.
|
||||
|
||||
formtools
|
||||
=========
|
||||
|
||||
@@ -162,17 +173,6 @@ Examples (when 'today' is 17 Feb 2007):
|
||||
|
||||
.. _DATE_FORMAT: ../settings/#date_format
|
||||
|
||||
flatpages
|
||||
=========
|
||||
|
||||
A framework for managing simple "flat" HTML content in a database.
|
||||
|
||||
See the `flatpages documentation`_.
|
||||
|
||||
.. _flatpages documentation: ../flatpages/
|
||||
|
||||
Requires the sites_ contrib package to be installed as well.
|
||||
|
||||
localflavor
|
||||
===========
|
||||
|
||||
@@ -211,6 +211,15 @@ See the `redirects documentation`_.
|
||||
|
||||
.. _redirects documentation: ../redirects/
|
||||
|
||||
sessions
|
||||
========
|
||||
|
||||
A framework for storing data in anonymous sessions.
|
||||
|
||||
See the `sessions documentation`_.
|
||||
|
||||
.. _sessions documentation: ../sessions/
|
||||
|
||||
sites
|
||||
=====
|
||||
|
||||
@@ -240,6 +249,16 @@ See the `syndication documentation`_.
|
||||
|
||||
.. _syndication documentation: ../syndication_feeds/
|
||||
|
||||
webdesign
|
||||
=========
|
||||
|
||||
Helpers and utilties targeted primarily at web designers rather than
|
||||
web developers.
|
||||
|
||||
See the `web design helpers documentation`_.
|
||||
|
||||
.. _web design helpers documentation: ../webdesign/
|
||||
|
||||
Other add-ons
|
||||
=============
|
||||
|
||||
|
||||
@@ -154,10 +154,13 @@ custom methods:
|
||||
|
||||
* ``get_profile()`` -- Returns a site-specific profile for this user.
|
||||
Raises ``django.contrib.auth.models.SiteProfileNotAvailable`` if the current site
|
||||
doesn't allow profiles.
|
||||
doesn't allow profiles. For information on how to define a
|
||||
site-specific user profile, see the section on `storing additional
|
||||
user information`_ below.
|
||||
|
||||
.. _Django model: ../model-api/
|
||||
.. _DEFAULT_FROM_EMAIL: ../settings/#default-from-email
|
||||
.. _storing additional user information: #storing-additional-information-about-users
|
||||
|
||||
Manager functions
|
||||
~~~~~~~~~~~~~~~~~
|
||||
@@ -269,6 +272,45 @@ you need to create a superuser after that via the command line, you can use the
|
||||
Make sure to substitute ``/path/to/`` with the path to the Django codebase on
|
||||
your filesystem.
|
||||
|
||||
Storing additional information about users
|
||||
------------------------------------------
|
||||
|
||||
If you'd like to store additional information related to your users,
|
||||
Django provides a method to specify a site-specific related model --
|
||||
termed a "user profile" -- for this purpose.
|
||||
|
||||
To make use of this feature, define a model with fields for the
|
||||
additional information you'd like to store, or additional methods
|
||||
you'd like to have available, and also add a ``ForeignKey`` from your
|
||||
model to the ``User`` model, specified with ``unique=True`` to ensure
|
||||
only one instance of your model can be created for each ``User``.
|
||||
|
||||
To indicate that this model is the user profile model for a given
|
||||
site, fill in the setting ``AUTH_PROFILE_MODULE`` with a string
|
||||
consisting of the following items, separated by a dot:
|
||||
|
||||
1. The (normalized to lower-case) name of the application in which the
|
||||
user profile model is defined (in other words, an all-lowercase
|
||||
version of the name which was passed to ``manage.py startapp`` to
|
||||
create the application).
|
||||
|
||||
2. The (normalized to lower-case) name of the model class.
|
||||
|
||||
For example, if the profile model was a class named ``UserProfile``
|
||||
and was defined inside an application named ``accounts``, the
|
||||
appropriate setting would be::
|
||||
|
||||
AUTH_PROFILE_MODULE = 'accounts.userprofile'
|
||||
|
||||
When a user profile model has been defined and specified in this
|
||||
manner, each ``User`` object will have a method -- ``get_profile()``
|
||||
-- which returns the instance of the user profile model associated
|
||||
with that ``User``.
|
||||
|
||||
For more information, see `Chapter 12 of the Django book`_.
|
||||
|
||||
.. _Chapter 12 of the Django book: http://www.djangobook.com/en/beta/chapter12/#cn226
|
||||
|
||||
Authentication in Web requests
|
||||
==============================
|
||||
|
||||
@@ -337,6 +379,17 @@ This example shows how you might use both ``authenticate()`` and ``login()``::
|
||||
else:
|
||||
# Return an 'invalid login' error message.
|
||||
|
||||
.. admonition:: Calling ``authenticate()`` first
|
||||
|
||||
When you're manually logging a user in, you *must* call
|
||||
``authenticate()`` before you call ``login()``; ``authenticate()``
|
||||
sets an attribute on the ``User`` noting which authentication
|
||||
backend successfully authenticated that user (see the `backends
|
||||
documentation`_ for details), and this information is needed later
|
||||
during the login process.
|
||||
|
||||
.. _backends documentation: #other-authentication-sources
|
||||
|
||||
Manually checking a user's password
|
||||
-----------------------------------
|
||||
|
||||
|
||||
@@ -168,6 +168,10 @@ development or testing environments. For example::
|
||||
|
||||
CACHE_BACKEND = 'simple:///'
|
||||
|
||||
**New in Django development version:** This cache backend is deprecated and
|
||||
will be removed in a future release. New code should use the ``locmem`` backend
|
||||
instead.
|
||||
|
||||
Dummy caching (for development)
|
||||
-------------------------------
|
||||
|
||||
|
||||
@@ -242,7 +242,7 @@ We've got two roles here:
|
||||
* Ticket triagers: community members who keep track of tickets, making
|
||||
sure the tickets are always categorized correctly.
|
||||
|
||||
Second, note the four triage stages:
|
||||
Second, note the five triage stages:
|
||||
|
||||
1. A ticket starts as "Unreviewed", meaning that a triager has yet to
|
||||
examine the ticket and move it along.
|
||||
@@ -254,9 +254,14 @@ Second, note the four triage stages:
|
||||
3. Once a ticket is ruled to be approved for fixing, it's moved into the
|
||||
"Accepted" stage. This stage is where all the real work gets done.
|
||||
|
||||
4. If a ticket has an associated patch (see below), a triager will review the
|
||||
patch. If the patch is complete, it'll be marked as "ready for checkin" so
|
||||
that a core developer knows to review and check in the patches.
|
||||
4. A ticket might be moved to the "Someday/Maybe" state if it's an
|
||||
enhancement request we are willing to consider if a good patch is
|
||||
written. Such tickets are not high priority.
|
||||
|
||||
5. If a ticket has an associated patch (see below), a triager will review
|
||||
the patch. If the patch is complete, it'll be marked as "ready for
|
||||
checkin" so that a core developer knows to review and check in the
|
||||
patches.
|
||||
|
||||
The second part of this workflow involves a set of flags the describe what the
|
||||
ticket has or needs in order to be "ready for checkin":
|
||||
@@ -654,9 +659,8 @@ To run the tests, ``cd`` to the ``tests/`` directory and type::
|
||||
./runtests.py --settings=path.to.django.settings
|
||||
|
||||
Yes, the unit tests need a settings module, but only for database connection
|
||||
info, with the ``DATABASE_ENGINE`` setting. You will also need a ``ROOT_URLCONF``
|
||||
setting (its value is ignored; it just needs to be present) and a ``SITE_ID``
|
||||
setting (any non-zero integer value will do) in order for all the tests to pass.
|
||||
info, with the ``DATABASE_ENGINE`` setting. You'll also need a ``ROOT_URLCONF``
|
||||
setting (its value is ignored; it just needs to be present).
|
||||
|
||||
If you're using the ``sqlite3`` database backend, no further settings are
|
||||
needed. A temporary database will be created in memory when running the tests.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
===================
|
||||
Custom Model Fields
|
||||
Custom model fields
|
||||
===================
|
||||
|
||||
**New in Django development version**
|
||||
@@ -8,9 +8,10 @@ Introduction
|
||||
============
|
||||
|
||||
The `model reference`_ documentation explains how to use Django's standard
|
||||
field classes. For many purposes, those classes are all you'll need. Sometimes,
|
||||
though, the Django version won't meet your precise requirements, or you'll want
|
||||
to use a field that is entirely different from those shipped with Django.
|
||||
field classes -- ``CharField``, ``DateField``, etc. For many purposes, those
|
||||
classes are all you'll need. Sometimes, though, the Django version won't meet
|
||||
your precise requirements, or you'll want to use a field that is entirely
|
||||
different from those shipped with Django.
|
||||
|
||||
Django's built-in field types don't cover every possible database column type --
|
||||
only the common types, such as ``VARCHAR`` and ``INTEGER``. For more obscure
|
||||
@@ -27,10 +28,10 @@ Our example object
|
||||
Creating custom fields requires a bit of attention to detail. To make things
|
||||
easier to follow, we'll use a consistent example throughout this document.
|
||||
Suppose you have a Python object representing the deal of cards in a hand of
|
||||
Bridge_. It doesn't matter if you don't know how to play Bridge. You only need
|
||||
to know that 52 cards are dealt out equally to four players, who are
|
||||
traditionally called *north*, *east*, *south* and *west*. Our class looks
|
||||
something like this::
|
||||
Bridge_. (Don't worry, you don't know how to play Bridge to follow this
|
||||
example. You only need to know that 52 cards are dealt out equally to four
|
||||
players, who are traditionally called *north*, *east*, *south* and *west*.)
|
||||
Our class looks something like this::
|
||||
|
||||
class Hand(object):
|
||||
def __init__(self, north, east, south, west):
|
||||
@@ -42,10 +43,9 @@ something like this::
|
||||
|
||||
# ... (other possibly useful methods omitted) ...
|
||||
|
||||
This is just an ordinary Python class, nothing Django-specific about it. We
|
||||
would like to be able to things like this in our models (we assume the
|
||||
``hand`` attribute on the model is an instance of ``Hand``)::
|
||||
|
||||
This is just an ordinary Python class, with nothing Django-specific about it.
|
||||
We'd like to be able to things like this in our models (we assume the ``hand``
|
||||
attribute on the model is an instance of ``Hand``)::
|
||||
|
||||
example = MyModel.objects.get(pk=1)
|
||||
print example.hand.north
|
||||
@@ -72,7 +72,7 @@ model support for existing classes where you cannot change the source code.
|
||||
.. _PostgreSQL custom types: http://www.postgresql.org/docs/8.2/interactive/sql-createtype.html
|
||||
.. _Bridge: http://en.wikipedia.org/wiki/Contract_bridge
|
||||
|
||||
Background Theory
|
||||
Background theory
|
||||
=================
|
||||
|
||||
Database storage
|
||||
@@ -87,7 +87,7 @@ that falls out fairly naturally once you have the database side under control).
|
||||
Fields in a model must somehow be converted to fit into an existing database
|
||||
column type. Different databases provide different sets of valid column types,
|
||||
but the rule is still the same: those are the only types you have to work
|
||||
with. Anything you want to store in the database must fit into one of
|
||||
with. Anything you want to store in the database must fit into one of
|
||||
those types.
|
||||
|
||||
Normally, you're either writing a Django field to match a particular database
|
||||
@@ -95,10 +95,9 @@ column type, or there's a fairly straightforward way to convert your data to,
|
||||
say, a string.
|
||||
|
||||
For our ``Hand`` example, we could convert the card data to a string of 104
|
||||
characters by concatenating all the cards together in a pre-determined order.
|
||||
Say, all the *north* cards first, then the *east*, *south* and *west* cards, in
|
||||
that order. So ``Hand`` objects can be saved to text or character columns in
|
||||
the database.
|
||||
characters by concatenating all the cards together in a pre-determined order --
|
||||
say, all the *north* cards first, then the *east*, *south* and *west* cards. So
|
||||
``Hand`` objects can be saved to text or character columns in the database.
|
||||
|
||||
What does a field class do?
|
||||
---------------------------
|
||||
@@ -109,12 +108,12 @@ mean model fields and not `form fields`_) are subclasses of
|
||||
field is common to all fields -- name, help text, validator lists, uniqueness
|
||||
and so forth. Storing all that information is handled by ``Field``. We'll get
|
||||
into the precise details of what ``Field`` can do later on; for now, suffice it
|
||||
to say that everything descends from ``Field`` and then customises key pieces
|
||||
of the class behaviour.
|
||||
to say that everything descends from ``Field`` and then customizes key pieces
|
||||
of the class behavior.
|
||||
|
||||
.. _form fields: ../newforms/#fields
|
||||
|
||||
It's important to realise that a Django field class is not what is stored in
|
||||
It's important to realize that a Django field class is not what is stored in
|
||||
your model attributes. The model attributes contain normal Python objects. The
|
||||
field classes you define in a model are actually stored in the ``Meta`` class
|
||||
when the model class is created (the precise details of how this is done are
|
||||
@@ -127,31 +126,35 @@ Keep this in mind when creating your own custom fields. The Django ``Field``
|
||||
subclass you write provides the machinery for converting between your Python
|
||||
instances and the database/serializer values in various ways (there are
|
||||
differences between storing a value and using a value for lookups, for
|
||||
example). If this sounds a bit tricky, don't worry. It will hopefully become
|
||||
clearer in the examples below. Just remember that you will often end up
|
||||
creating two classes when you want a custom field. The first class is the
|
||||
Python object that your users will manipulate. They will assign it to the model
|
||||
attribute, they will read from it for displaying purposes, things like that.
|
||||
This is the ``Hand`` class in our example. The second class is the ``Field``
|
||||
subclass. This is the class that knows how to convert your first class back and
|
||||
forth between its permanent storage form and the Python form.
|
||||
example). If this sounds a bit tricky, don't worry -- it will become clearer in
|
||||
the examples below. Just remember that you will often end up creating two
|
||||
classes when you want a custom field:
|
||||
|
||||
* The first class is the Python object that your users will manipulate.
|
||||
They will assign it to the model attribute, they will read from it for
|
||||
displaying purposes, things like that. This is the ``Hand`` class in our
|
||||
example.
|
||||
|
||||
* The second class is the ``Field`` subclass. This is the class that knows
|
||||
how to convert your first class back and forth between its permanent
|
||||
storage form and the Python form.
|
||||
|
||||
Writing a ``Field`` subclass
|
||||
=============================
|
||||
|
||||
When you are planning your ``Field`` subclass, first give some thought to
|
||||
which existing field your new field is most similar to. Can you subclass an
|
||||
existing Django field and save yourself some work? If not, you should subclass the ``Field`` class, from which everything is descended.
|
||||
When planning your ``Field`` subclass, first give some thought to which
|
||||
existing ``Field`` class your new field is most similar to. Can you subclass an
|
||||
existing Django field and save yourself some work? If not, you should subclass
|
||||
the ``Field`` class, from which everything is descended.
|
||||
|
||||
Initialising your new field is a matter of separating out any arguments that
|
||||
Initializing your new field is a matter of separating out any arguments that
|
||||
are specific to your case from the common arguments and passing the latter to
|
||||
the ``__init__()`` method of ``Field`` (or your parent class).
|
||||
|
||||
In our example, the Django field we create is going to be called
|
||||
``HandField``. It's not a bad idea to use a similar naming scheme to Django's
|
||||
fields so that our new class is identifiable and yet clearly related to the
|
||||
``Hand`` class it is wrapping. It doesn't behave like any existing field, so
|
||||
we'll subclass directly from ``Field``::
|
||||
In our example, we'll call our field ``HandField``. (It's a good idea to call
|
||||
your ``Field`` subclass ``(Something)Field``, so it's easily identifiable as a
|
||||
``Field`` subclass.) It doesn't behave like any existing field, so we'll
|
||||
subclass directly from ``Field``::
|
||||
|
||||
from django.db import models
|
||||
|
||||
@@ -160,7 +163,7 @@ we'll subclass directly from ``Field``::
|
||||
kwargs['max_length'] = 104
|
||||
super(HandField, self).__init__(*args, **kwargs)
|
||||
|
||||
Our ``HandField`` will accept most of the standard field options (see the list
|
||||
Our ``HandField`` accept most of the standard field options (see the list
|
||||
below), but we ensure it has a fixed length, since it only needs to hold 52
|
||||
card values plus their suits; 104 characters in total.
|
||||
|
||||
@@ -171,40 +174,40 @@ card values plus their suits; 104 characters in total.
|
||||
(``auto_now`` being set implies ``editable=False``). No error is raised in
|
||||
this case.
|
||||
|
||||
This behaviour simplifies the field classes, because they don't need to
|
||||
This behavior simplifies the field classes, because they don't need to
|
||||
check for options that aren't necessary. They just pass all the options to
|
||||
the parent class and then don't use them later on. It is up to you whether
|
||||
the parent class and then don't use them later on. It's up to you whether
|
||||
you want your fields to be more strict about the options they select, or
|
||||
to use the simpler, more permissive behaviour of the current fields.
|
||||
to use the simpler, more permissive behavior of the current fields.
|
||||
|
||||
The ``Field.__init__()`` method takes the following parameters, in this
|
||||
order:
|
||||
|
||||
- ``verbose_name``
|
||||
- ``name``
|
||||
- ``primary_key``
|
||||
- ``max_length``
|
||||
- ``unique``
|
||||
- ``blank``
|
||||
- ``null``
|
||||
- ``db_index``
|
||||
- ``core``
|
||||
- ``rel``: Used for related fields (like ``ForeignKey``). For advanced use
|
||||
* ``verbose_name``
|
||||
* ``name``
|
||||
* ``primary_key``
|
||||
* ``max_length``
|
||||
* ``unique``
|
||||
* ``blank``
|
||||
* ``null``
|
||||
* ``db_index``
|
||||
* ``core``
|
||||
* ``rel``: Used for related fields (like ``ForeignKey``). For advanced use
|
||||
only.
|
||||
- ``default``
|
||||
- ``editable``
|
||||
- ``serialize``: If ``False``, the field will not be serialized when the
|
||||
* ``default``
|
||||
* ``editable``
|
||||
* ``serialize``: If ``False``, the field will not be serialized when the
|
||||
model is passed to Django's serializers_. Defaults to ``True``.
|
||||
- ``prepopulate_from``
|
||||
- ``unique_for_date``
|
||||
- ``unique_for_month``
|
||||
- ``unique_for_year``
|
||||
- ``validator_list``
|
||||
- ``choices``
|
||||
- ``radio_admin``
|
||||
- ``help_text``
|
||||
- ``db_column``
|
||||
- ``db_tablespace``: Currently only used with the Oracle backend and only
|
||||
* ``prepopulate_from``
|
||||
* ``unique_for_date``
|
||||
* ``unique_for_month``
|
||||
* ``unique_for_year``
|
||||
* ``validator_list``
|
||||
* ``choices``
|
||||
* ``radio_admin``
|
||||
* ``help_text``
|
||||
* ``db_column``
|
||||
* ``db_tablespace``: Currently only used with the Oracle backend and only
|
||||
for index creation. You can usually ignore this option.
|
||||
|
||||
All of the options without an explanation in the above list have the same
|
||||
@@ -218,22 +221,19 @@ The ``SubfieldBase`` metaclass
|
||||
------------------------------
|
||||
|
||||
As we indicated in the introduction_, field subclasses are often needed for
|
||||
two reasons. Either to take advantage of a custom database column type, or to
|
||||
handle complex Python types. A combination of the two is obviously also
|
||||
possible. If you are only working with custom database column types and your
|
||||
two reasons: either to take advantage of a custom database column type, or to
|
||||
handle complex Python types. Obviously, a combination of the two is also
|
||||
possible. If you're only working with custom database column types and your
|
||||
model fields appear in Python as standard Python types direct from the
|
||||
database backend, you don't need to worry about this section.
|
||||
|
||||
If you are handling custom Python types, such as our ``Hand`` class, we need
|
||||
to make sure that when Django initialises an instance of our model and assigns
|
||||
a database value to our custom field attribute we convert that value into the
|
||||
If you're handling custom Python types, such as our ``Hand`` class, we need
|
||||
to make sure that when Django initializes an instance of our model and assigns
|
||||
a database value to our custom field attribute, we convert that value into the
|
||||
appropriate Python object. The details of how this happens internally are a
|
||||
little complex. For the field writer, though, things are fairly simple. Make
|
||||
sure your field subclass uses ``django.db.models.SubfieldBase`` as its
|
||||
metaclass. This ensures that the ``to_python()`` method, documented below_,
|
||||
will always be called when the attribute is initialised.
|
||||
|
||||
Our ``HandField`` class now looks like this::
|
||||
little complex, but the code you need to write in your ``Field`` class is
|
||||
simple: make sure your field subclass uses ``django.db.models.SubfieldBase`` as
|
||||
its metaclass::
|
||||
|
||||
class HandField(models.Field):
|
||||
__metaclass__ = models.SubfieldBase
|
||||
@@ -241,16 +241,18 @@ Our ``HandField`` class now looks like this::
|
||||
def __init__(self, *args, **kwargs):
|
||||
# ...
|
||||
|
||||
This ensures that the ``to_python()`` method, documented below_, will always be
|
||||
called when the attribute is initialized.
|
||||
|
||||
.. _below: #to-python-self-value
|
||||
|
||||
Useful methods
|
||||
--------------
|
||||
|
||||
Once you've created your ``Field`` subclass and setup up the
|
||||
``__metaclass__``, if necessary, there are a few standard methods you need to
|
||||
consider overriding. Which of these you need to implement will depend on you
|
||||
particular field behaviour. The list below is in approximately decreasing
|
||||
order of importance, so start from the top.
|
||||
Once you've created your ``Field`` subclass and set up up the
|
||||
``__metaclass__``, you might consider overriding a few standard methods,
|
||||
depending on your field's behavior. The list of methods below is in
|
||||
approximately decreasing order of importance, so start from the top.
|
||||
|
||||
``db_type(self)``
|
||||
~~~~~~~~~~~~~~~~~
|
||||
@@ -337,23 +339,32 @@ field. You are then responsible for creating the column in the right table in
|
||||
some other way, of course, but this gives you a way to tell Django to get out
|
||||
of the way.
|
||||
|
||||
|
||||
``to_python(self, value)``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Converts between all the ways your field can receive its initial value and the
|
||||
Python object you want to end up with. The default version just returns
|
||||
``value``, so is useful is the database backend returns the data already in
|
||||
the correct form (a Python string, for example).
|
||||
Converts a value as returned by your database (or a serializer) to a Python
|
||||
object.
|
||||
|
||||
Normally, you will need to override this method. As a general rule, be
|
||||
prepared to accept an instance of the right type (e.g. ``Hand`` in our ongoing
|
||||
example), a string (from a deserializer, for example), and whatever the
|
||||
database wrapper returns for the column type you are using.
|
||||
The default implementation simply returns ``value``, for the common case in
|
||||
which the database backend already returns data in the correct format (as a
|
||||
Python string, for example).
|
||||
|
||||
In our ``HandField`` class, we are storing the data in a character field in
|
||||
the database, so we need to be able to process strings and ``Hand`` instances
|
||||
in ``to_python()``::
|
||||
If your custom ``Field`` class deals with data structures that are more complex
|
||||
than strings, dates, integers or floats, then you'll need to override this
|
||||
method. As a general rule, the method should deal gracefully with any of the
|
||||
following arguments:
|
||||
|
||||
* An instance of the correct type (e.g., ``Hand`` in our ongoing example).
|
||||
|
||||
* A string (e.g., from a deserializer).
|
||||
|
||||
* Whatever the database returns for the column type you're using.
|
||||
|
||||
In our ``HandField`` class, we're storing the data as a VARCHAR field in the
|
||||
database, so we need to be able to process strings and ``Hand`` instances in
|
||||
``to_python()``::
|
||||
|
||||
import re
|
||||
|
||||
class HandField(models.Field):
|
||||
# ...
|
||||
@@ -362,14 +373,14 @@ in ``to_python()``::
|
||||
if isinstance(value, Hand):
|
||||
return value
|
||||
|
||||
# The string case
|
||||
# The string case.
|
||||
p1 = re.compile('.{26}')
|
||||
p2 = re.compile('..')
|
||||
args = [p2.findall(x) for x in p1.findall(value)]
|
||||
return Hand(*args)
|
||||
|
||||
Notice that we always return a ``Hand`` instance from this method. That is the
|
||||
Python object we want to store in the model's attribute.
|
||||
Notice that we always return a ``Hand`` instance from this method. That's the
|
||||
Python object type we want to store in the model's attribute.
|
||||
|
||||
``get_db_prep_save(self, value)``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
@@ -377,7 +388,7 @@ Python object we want to store in the model's attribute.
|
||||
This is the reverse of ``to_python()`` when working with the database backends
|
||||
(as opposed to serialization). The ``value`` parameter is the current value of
|
||||
the model's attribute (a field has no reference to its containing model, so it
|
||||
cannot retrieve the value itself) and the method should return data in a
|
||||
cannot retrieve the value itself), and the method should return data in a
|
||||
format that can be used as a parameter in a query for the database backend.
|
||||
|
||||
For example::
|
||||
@@ -389,7 +400,6 @@ For example::
|
||||
return ''.join([''.join(l) for l in (self.north,
|
||||
self.east, self.south, self.west)])
|
||||
|
||||
|
||||
``pre_save(self, model_instance, add)``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@@ -399,10 +409,10 @@ The attribute name is in ``self.attname`` (this is set up by ``Field``). If
|
||||
the model is being saved to the database for the first time, the ``add``
|
||||
parameter will be ``True``, otherwise it will be ``False``.
|
||||
|
||||
Often you won't need to override this method. However, at times it can be very
|
||||
useful. For example, the Django ``DateTimeField`` uses this method to set the
|
||||
attribute to the correct value before returning it in the cases when
|
||||
``auto_now`` or ``auto_now_add`` are set on the field.
|
||||
You only need to override this method if you want to preprocess the value
|
||||
somehow, just before saving. For example, Django's ``DateTimeField`` uses this
|
||||
method to set the attribute correctly in the case of ``auto_now`` or
|
||||
``auto_now_add``.
|
||||
|
||||
If you do override this method, you must return the value of the attribute at
|
||||
the end. You should also update the model's attribute if you make any changes
|
||||
@@ -460,9 +470,9 @@ All of the ``kwargs`` dictionary is passed directly to the form field's
|
||||
``__init__()`` method. Normally, all you need to do is set up a good default
|
||||
for the ``form_class`` argument and then delegate further handling to the
|
||||
parent class. This might require you to write a custom form field (and even a
|
||||
form widget). See the `forms documentation`_ for information about this. Also
|
||||
have a look at ``django.contrib.localflavor`` for some examples of custom
|
||||
widgets.
|
||||
form widget). See the `forms documentation`_ for information about this, and
|
||||
take a look at the code in ``django.contrib.localflavor`` for some examples of
|
||||
custom widgets.
|
||||
|
||||
Continuing our ongoing example, we can write the ``formfield()`` method as::
|
||||
|
||||
@@ -471,14 +481,14 @@ Continuing our ongoing example, we can write the ``formfield()`` method as::
|
||||
|
||||
def formfield(self, **kwargs):
|
||||
# This is a fairly standard way to set up some defaults
|
||||
# whilst letting the caller override them.
|
||||
# while letting the caller override them.
|
||||
defaults = {'form_class': MyFormField}
|
||||
defaults.update(kwargs)
|
||||
return super(HandField, self).formfield(**defaults)
|
||||
|
||||
This assumes we have some ``MyFormField`` field class (which has its own
|
||||
default widget) imported. This document doesn't cover the details of writing
|
||||
custom form fields.
|
||||
This assumes we're imported a ``MyFormField`` field class (which has its own
|
||||
default widget). This document doesn't cover the details of writing custom form
|
||||
fields.
|
||||
|
||||
.. _helper functions: ../newforms/#generating-forms-for-models
|
||||
.. _forms documentation: ../newforms/
|
||||
@@ -490,7 +500,7 @@ Returns a string giving the name of the ``Field`` subclass we are emulating at
|
||||
the database level. This is used to determine the type of database column for
|
||||
simple cases.
|
||||
|
||||
If you have created a ``db_type()`` method, you do not need to worry about
|
||||
If you have created a ``db_type()`` method, you don't need to worry about
|
||||
``get_internal_type()`` -- it won't be used much. Sometimes, though, your
|
||||
database storage is similar in type to some other field, so you can use that
|
||||
other field's logic to create the right column.
|
||||
@@ -512,7 +522,7 @@ the database backend you are using -- that is, it doesn't appear in
|
||||
be used by the serializer, but the default ``db_type()`` method will return
|
||||
``None``. See the documentation of ``db_type()`` above_ for reasons why this
|
||||
might be useful. Putting a descriptive string in as the type of the field for
|
||||
the serializer is a useful idea if you are ever going to be using the
|
||||
the serializer is a useful idea if you're ever going to be using the
|
||||
serializer output in some other place, outside of Django.
|
||||
|
||||
.. _above: #db-type-self
|
||||
@@ -528,7 +538,7 @@ serializer output in some other place, outside of Django.
|
||||
Returns a dictionary, mapping the field's attribute name to a flattened string
|
||||
version of the data. This method has some internal uses that aren't of
|
||||
interest to use here (mostly having to do with manipulators). For our
|
||||
purposes, it is sufficient to return a one item dictionary that maps the
|
||||
purposes, it's sufficient to return a one item dictionary that maps the
|
||||
attribute name to a string.
|
||||
|
||||
This method is used by the serializers to convert the field into a string for
|
||||
@@ -549,19 +559,20 @@ we can reuse some existing conversion code::
|
||||
Some general advice
|
||||
--------------------
|
||||
|
||||
Writing a custom field can be a tricky process sometimes, particularly if you
|
||||
are doing complex conversions between your Python types and your database and
|
||||
serialization formats. A couple of tips to make things go more smoothly:
|
||||
Writing a custom field can be a tricky process, particularly if you're doing
|
||||
complex conversions between your Python types and your database and
|
||||
serialization formats. Here are a couple of tips to make things go more
|
||||
smoothly:
|
||||
|
||||
1. Look at the existing Django fields (in
|
||||
``django/db/models/fields/__init__.py``) for inspiration. Try to find a field
|
||||
that is already close to what you want and extend it a little bit, in
|
||||
preference to creating an entirely new field from scratch.
|
||||
|
||||
2. Put a ``__str__()`` or ``__unicode__()`` method on the class you are
|
||||
wrapping up as a field. There are a lot of places where the default behaviour
|
||||
of the field code is to call ``force_unicode()`` on the value (in our
|
||||
examples in this document, ``value`` would be a ``Hand`` instance, not a
|
||||
``HandField``). So if your ``__unicode__()`` method automatically converts to
|
||||
the string form of your Python object, you can save yourself a lot of work.
|
||||
1. Look at the existing Django fields (in
|
||||
``django/db/models/fields/__init__.py``) for inspiration. Try to find a
|
||||
field that's similar to what you want and extend it a little bit,
|
||||
instead of creating an entirely new field from scratch.
|
||||
|
||||
2. Put a ``__str__()`` or ``__unicode__()`` method on the class you're
|
||||
wrapping up as a field. There are a lot of places where the default
|
||||
behavior of the field code is to call ``force_unicode()`` on the value.
|
||||
(In our examples in this document, ``value`` would be a ``Hand``
|
||||
instance, not a ``HandField``). So if your ``__unicode__()`` method
|
||||
automatically converts to the string form of your Python object, you can
|
||||
save yourself a lot of work.
|
||||
|
||||
@@ -258,6 +258,12 @@ many-to-many table would be stored in the ``indexes`` tablespace. The ``data``
|
||||
field would also generate an index, but no tablespace for it is specified, so
|
||||
it would be stored in the model tablespace ``tables`` by default.
|
||||
|
||||
The settings.py file supports two additional options to specify
|
||||
default values for the db_tablespace options. This is useful for
|
||||
setting a tablespace for the Django internal apps and other
|
||||
contributed applications. These options are ``DEFAULT_TABLESPACE``
|
||||
and ``DEFAULT_INDEX_TABLESPACE``.
|
||||
|
||||
Django does not create the tablespaces for you. Please refer to `Oracle's
|
||||
documentation`_ for details on creating and managing tablespaces.
|
||||
|
||||
|
||||
@@ -253,9 +253,11 @@ For example::
|
||||
|
||||
The class has the following methods:
|
||||
|
||||
* ``send()`` sends the message, using either the connection that is
|
||||
specified in the ``connection`` attribute, or creating a new connection
|
||||
if none already exists.
|
||||
* ``send(fail_silently=False)`` sends the message, using either
|
||||
the connection that is specified in the ``connection``
|
||||
attribute, or creating a new connection if none already
|
||||
exists. If the keyword argument ``fail_silently`` is ``True``,
|
||||
exceptions raised while sending the message will be quashed.
|
||||
|
||||
* ``message()`` constructs a ``django.core.mail.SafeMIMEText`` object (a
|
||||
subclass of Python's ``email.MIMEText.MIMEText`` class) or a
|
||||
|
||||
418
docs/form_for_model.txt
Normal file
418
docs/form_for_model.txt
Normal file
@@ -0,0 +1,418 @@
|
||||
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 ``max_length``
|
||||
``CommaSeparatedIntegerField`` ``CharField``
|
||||
``DateField`` ``DateField``
|
||||
``DateTimeField`` ``DateTimeField``
|
||||
``DecimalField`` ``DecimalField``
|
||||
``EmailField`` ``EmailField``
|
||||
``FileField`` ``FileField``
|
||||
``FilePathField`` ``CharField``
|
||||
``FloatField`` ``FloatField``
|
||||
``ForeignKey`` ``ModelChoiceField`` (see below)
|
||||
``ImageField`` ``ImageField``
|
||||
``IntegerField`` ``IntegerField``
|
||||
``IPAddressField`` ``IPAddressField``
|
||||
``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``
|
||||
=============================== ========================================
|
||||
|
||||
|
||||
.. note::
|
||||
The ``FloatField`` form field and ``DecimalField`` model and form fields
|
||||
are new in the development version.
|
||||
|
||||
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``. The choices will normally include the blank choice which is
|
||||
selected by default. If the field is required, this forces the user to
|
||||
make a selection. The blank choice will not be included if the model
|
||||
field has ``blank=False`` and an explicit ``default`` value (the
|
||||
``default`` value will be initially selected instead).
|
||||
|
||||
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(max_length=100)
|
||||
title = models.CharField(max_length=3, choices=TITLE_CHOICES)
|
||||
birth_date = models.DateField(blank=True, null=True)
|
||||
|
||||
def __unicode__(self):
|
||||
return self.name
|
||||
|
||||
class Book(models.Model):
|
||||
name = models.CharField(max_length=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``.
|
||||
|
||||
This ``save()`` method accepts an optional ``commit`` keyword argument, which
|
||||
accepts either ``True`` or ``False``. If you call ``save()`` with
|
||||
``commit=False``, then it will return an object that hasn't yet been saved to
|
||||
the database. In this case, it's up to you to call ``save()`` on the resulting
|
||||
model instance. This is useful if you want to do custom processing on the
|
||||
object before saving it. ``commit`` is ``True`` by default.
|
||||
|
||||
Another side effect of using ``commit=False`` is seen when your model has
|
||||
a many-to-many relation with another model. If your model has a many-to-many
|
||||
relation and you specify ``commit=False`` when you save a form, Django cannot
|
||||
immediately save the form data for the many-to-many relation. This is because
|
||||
it isn't possible to save many-to-many data for an instance until the instance
|
||||
exists in the database.
|
||||
|
||||
To work around this problem, every time you save a form using ``commit=False``,
|
||||
Django adds a ``save_m2m()`` method to the form created by ``form_for_model``.
|
||||
After you've manually saved the instance produced by the form, you can invoke
|
||||
``save_m2m()`` to save the many-to-many form data. For example::
|
||||
|
||||
# Create a form instance with POST data.
|
||||
>>> f = AuthorForm(request.POST)
|
||||
|
||||
# Create, but don't save the new author instance.
|
||||
>>> new_author = f.save(commit=False)
|
||||
|
||||
# Modify the author in some way.
|
||||
>>> new_author.some_field = 'some_value'
|
||||
|
||||
# Save the new instance.
|
||||
>>> new_author.save()
|
||||
|
||||
# Now, save the many-to-many data for the form.
|
||||
>>> f.save_m2m()
|
||||
|
||||
Calling ``save_m2m()`` is only required if you use ``save(commit=False)``.
|
||||
When you use a simple ``save()`` on a form, all data -- including
|
||||
many-to-many data -- is saved without the need for any additional method calls.
|
||||
For example::
|
||||
|
||||
# Create a form instance with POST data.
|
||||
>>> f = AuthorForm(request.POST)
|
||||
|
||||
# Create and save the new author instance. There's no need to do anything else.
|
||||
>>> new_author = f.save()
|
||||
|
||||
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()``,
|
||||
then the fields that are *not* specified will not be set by the form's
|
||||
``save()`` method. Django will prevent any attempt to save an incomplete
|
||||
model, so if the model does not allow the missing fields to be empty, and
|
||||
does not provide a default value for the missing fields, any attempt to
|
||||
``save()`` a ``form_for_model`` with missing fields will fail. To avoid
|
||||
this failure, you must use ``save(commit=False)`` and manually set any
|
||||
extra required fields::
|
||||
|
||||
instance = form.save(commit=False)
|
||||
instance.required_field = 'new value'
|
||||
instance.save()
|
||||
|
||||
See the `section on saving forms`_ for more details on using
|
||||
``save(commit=False)``.
|
||||
|
||||
.. _section on saving forms: `The save() method`_
|
||||
|
||||
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(Article, 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.
|
||||
|
||||
.. warning::
|
||||
The field that is passed into the ``formfield_callback`` function in
|
||||
``form_for_model()`` and ``form_for_instance`` is the field instance from
|
||||
your model's class. You **must not** alter that object at all; treat it
|
||||
as read-only!
|
||||
|
||||
If you make any alterations to that object, it will affect any future
|
||||
users of the model class, because you will have changed the field object
|
||||
used to construct the class. This is almost certainly what you don't want
|
||||
to have happen.
|
||||
|
||||
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.
|
||||
|
||||
Unlike ``form_for_model()``, a choice field in form created by
|
||||
``form_for_instance()`` will not include the blank choice if the respective
|
||||
model field has ``blank=False``. The initial choice is drawn from the instance.
|
||||
|
||||
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()``.
|
||||
|
||||
Let's modify the earlier `contact form`_ view example a little bit. Suppose we
|
||||
have a ``Message`` model that holds each contact submission. Something like::
|
||||
|
||||
class Message(models.Model):
|
||||
subject = models.CharField(max_length=100)
|
||||
message = models.TextField()
|
||||
sender = models.EmailField()
|
||||
cc_myself = models.BooleanField(required=False)
|
||||
|
||||
You could use this model to create a form (using ``form_for_model()``). You
|
||||
could also use existing ``Message`` instances to create a form for editing
|
||||
messages. The `simple example view`_ can be changed slightly to accept the ``id`` value
|
||||
of an existing ``Message`` and present it for editing::
|
||||
|
||||
def contact_edit(request, msg_id):
|
||||
# Create the form from the message id.
|
||||
message = get_object_or_404(Message, id=msg_id)
|
||||
ContactForm = form_for_instance(message)
|
||||
|
||||
if request.method == 'POST':
|
||||
form = ContactForm(request.POST)
|
||||
if form.is_valid():
|
||||
form.save()
|
||||
return HttpResponseRedirect('/url/on_success/')
|
||||
else:
|
||||
form = ContactForm()
|
||||
return render_to_response('contact.html', {'form': form})
|
||||
|
||||
Aside from how we create the ``ContactForm`` class here, the main point to
|
||||
note is that the form display in the ``GET`` branch of the function
|
||||
will use the values from the ``message`` instance as initial values for the
|
||||
form field.
|
||||
|
||||
.. _contact form: ../newforms/#simple-view-example
|
||||
.. _`simple example view`: ../newforms/#simple-view-example
|
||||
|
||||
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.
|
||||
@@ -188,7 +188,7 @@ a date in the *future* are not included unless you set ``allow_future`` to
|
||||
* ``allow_empty``: A boolean specifying whether to display the page if no
|
||||
objects are available. If this is ``False`` and no objects are available,
|
||||
the view will raise a 404 instead of displaying an empty page. By
|
||||
default, this is ``False``.
|
||||
default, this is ``True``.
|
||||
|
||||
* ``context_processors``: A list of template-context processors to apply to
|
||||
the view's template. See the `RequestContext docs`_.
|
||||
@@ -718,7 +718,7 @@ A page representing a list of objects.
|
||||
* ``allow_empty``: A boolean specifying whether to display the page if no
|
||||
objects are available. If this is ``False`` and no objects are available,
|
||||
the view will raise a 404 instead of displaying an empty page. By
|
||||
default, this is ``False``.
|
||||
default, this is ``True``.
|
||||
|
||||
* ``context_processors``: A list of template-context processors to apply to
|
||||
the view's template. See the `RequestContext docs`_.
|
||||
|
||||
@@ -73,13 +73,17 @@ installed.
|
||||
|
||||
If you plan to use Django's ``manage.py syncdb`` command to
|
||||
automatically create database tables for your models, you'll need to
|
||||
ensure that Django has permission to create tables in the database
|
||||
you're using; if you plan to manually create the tables, you can
|
||||
simply grant Django ``SELECT``, ``INSERT``, ``UPDATE`` and ``DELETE``
|
||||
permissions. Django does not issue ``ALTER TABLE`` statements, and so
|
||||
will not require permission to do so. If you will be using Django's
|
||||
`testing framework`_ with data fixtures, Django will need permission
|
||||
to create a temporary test database.
|
||||
ensure that Django has permission to create and alter tables in the
|
||||
database you're using; if you plan to manually create the tables, you
|
||||
can simply grant Django ``SELECT``, ``INSERT``, ``UPDATE`` and
|
||||
``DELETE`` permissions. On some databases, Django will need to have
|
||||
``ALTER TABLE`` privileges during ``syncdb`` (in order to create
|
||||
foreign key constraints properly on databases which do not allow them
|
||||
to be deferred), but will not issue ``ALTER TABLE`` statements on a
|
||||
table once ``syncdb`` has finished setting it up.
|
||||
|
||||
If you will be using Django's `testing framework`_ with data fixtures,
|
||||
Django will need permission to create a temporary test database.
|
||||
|
||||
.. _PostgreSQL: http://www.postgresql.org/
|
||||
.. _MySQL: http://www.mysql.com/
|
||||
|
||||
654
docs/localflavor.txt
Normal file
654
docs/localflavor.txt
Normal file
@@ -0,0 +1,654 @@
|
||||
==========================
|
||||
The "local flavor" add-ons
|
||||
==========================
|
||||
|
||||
Django comes with assorted pieces of code that are useful only for a particular
|
||||
country or culture. These pieces of code are organized as a set of
|
||||
subpackages, named using `ISO 3166 country codes`_.
|
||||
|
||||
.. _ISO 3166 country codes: http://www.iso.org/iso/country_codes/iso_3166_code_lists/english_country_names_and_code_elements.htm
|
||||
|
||||
Most of the ``localflavor`` add-ons are localized form components deriving from
|
||||
the newforms_ framework. To use one of these localized components, just import
|
||||
the relevant subpackage. For example, a form with a field for French telephone
|
||||
numbers is created like so::
|
||||
|
||||
from django import newforms as forms
|
||||
from django.contrib.localflavor import fr
|
||||
|
||||
class MyForm(forms.Form):
|
||||
my_french_phone_no = fr.forms.FRPhoneNumberField()
|
||||
|
||||
Countries currently supported by ``localflavor`` are:
|
||||
|
||||
* Argentina_
|
||||
* Australia_
|
||||
* Brazil_
|
||||
* Canada_
|
||||
* Chile_
|
||||
* Finland_
|
||||
* France_
|
||||
* Germany_
|
||||
* Holland_
|
||||
* Iceland_
|
||||
* India_
|
||||
* Italy_
|
||||
* Japan_
|
||||
* Mexico_
|
||||
* Norway_
|
||||
* Peru_
|
||||
* Poland_
|
||||
* Slovakia_
|
||||
* `South Africa`_
|
||||
* Spain_
|
||||
* Switzerland_
|
||||
* `United Kingdom`_
|
||||
* `United States of America`_
|
||||
|
||||
.. _Argentina: `Argentina (django.contrib.localflavor.ar)`_
|
||||
.. _Australia: `Australia (django.contrib.localflavor.au)`_
|
||||
.. _Brazil: `Brazil (django.contrib.localflavor.br)`_
|
||||
.. _Canada: `Canada (django.contrib.localflavor.ca)`_
|
||||
.. _Chile: `Chile (django.contrib.localflavor.cl)`_
|
||||
.. _Finland: `Finland (django.contrib.localflavor.fi)`_
|
||||
.. _France: `France (django.contrib.localflavor.fr)`_
|
||||
.. _Germany: `Germany (django.contrib.localflavor.de)`_
|
||||
.. _Holland: `Holland (django.contrib.localflavor.nl)`_
|
||||
.. _Iceland: `Iceland (django.contrib.localflavor.is\_)`_
|
||||
.. _India: `India (django.contrib.localflavor.in\_)`_
|
||||
.. _Italy: `Italy (django.contrib.localflavor.it)`_
|
||||
.. _Japan: `Japan (django.contrib.localflavor.jp)`_
|
||||
.. _Mexico: `Mexico (django.contrib.localflavor.mx)`_
|
||||
.. _Norway: `Norway (django.contrib.localflavor.no)`_
|
||||
.. _Peru: `Peru (django.contrib.localflavor.pe)`_
|
||||
.. _Poland: `Poland (django.contrib.localflavor.pl)`_
|
||||
.. _Slovakia: `Slovakia (django.contrib.localflavor.sk)`_
|
||||
.. _South Africa: `South Africa (django.contrib.localflavor.za)`_
|
||||
.. _Spain: `Spain (django.contrib.localflavor.es)`_
|
||||
.. _Switzerland: `Switzerland (django.contrib.localflavor.ch)`_
|
||||
.. _United Kingdom: `United Kingdom (django.contrib.localflavor.uk)`_
|
||||
.. _United States of America: `United States of America (django.contrib.localflavor.us)`_
|
||||
|
||||
The ``localflavor`` add-on also includes the ``generic`` subpackage, containing
|
||||
useful code that is not specific to one particular country or culture.
|
||||
Currently, it defines date and date & time input fields based on those from
|
||||
newforms_, but with non-US default formats. Here's an example of how to use
|
||||
them::
|
||||
|
||||
from django import newforms as forms
|
||||
from django.contrib.localflavor import generic
|
||||
|
||||
class MyForm(forms.Form):
|
||||
my_date_field = generic.forms.DateField()
|
||||
|
||||
.. _newforms: ../newforms/
|
||||
|
||||
|
||||
.. admonition:: Adding a Flavor
|
||||
|
||||
We'd love to add more of these to Django, so please create a ticket for
|
||||
anything that you've found useful. Please use unicode objects
|
||||
(``u'mystring'``) for strings, rather than setting the encoding in the file
|
||||
(see any of the existing flavors for examples).
|
||||
|
||||
|
||||
Argentina (``django.contrib.localflavor.ar``)
|
||||
=============================================
|
||||
|
||||
ARPostalCodeField
|
||||
-----------------
|
||||
|
||||
A form field that validates input as either a classic four-digit Argentinian
|
||||
postal code or a CPA_.
|
||||
|
||||
.. _CPA: http://www.correoargentino.com.ar/consulta_cpa/home.php
|
||||
|
||||
ARProvinceSelect
|
||||
----------------
|
||||
|
||||
A ``Select`` widget that uses a list of Argentina's provinces as its choices.
|
||||
|
||||
|
||||
Australia (``django.contrib.localflavor.au``)
|
||||
=============================================
|
||||
|
||||
AUPostCodeField
|
||||
---------------
|
||||
|
||||
A form field that validates input as an Australian postcode.
|
||||
|
||||
AUPhoneNumberField
|
||||
------------------
|
||||
|
||||
A form field that validates input as an Australian phone number. Valid numbers
|
||||
have ten digits.
|
||||
|
||||
AUStateSelect
|
||||
-------------
|
||||
|
||||
A ``Select`` widget that uses a list of Australian states/territories as its
|
||||
choices.
|
||||
|
||||
|
||||
Brazil (``django.contrib.localflavor.br``)
|
||||
==========================================
|
||||
|
||||
BRPhoneNumberField
|
||||
------------------
|
||||
|
||||
A form field that validates input as a Brazilian phone number, with the format
|
||||
XX-XXXX-XXXX.
|
||||
|
||||
BRZipCodeField
|
||||
--------------
|
||||
|
||||
A form field that validates input as a Brazilian zip code, with the format
|
||||
XXXXX-XXX.
|
||||
|
||||
BRStateSelect
|
||||
-------------
|
||||
|
||||
A ``Select`` widget that uses a list of Brazilian states/territories as its
|
||||
choices.
|
||||
|
||||
|
||||
Canada (``django.contrib.localflavor.ca``)
|
||||
==========================================
|
||||
|
||||
CAPhoneNumberField
|
||||
------------------
|
||||
|
||||
A form field that validates input as a Canadian phone number, with the format
|
||||
XXX-XXX-XXXX.
|
||||
|
||||
CAPostalCodeField
|
||||
-----------------
|
||||
|
||||
A form field that validates input as a Canadian postal code, with the format
|
||||
XXX XXX.
|
||||
|
||||
CAProvinceField
|
||||
---------------
|
||||
|
||||
A form field that validates input as a Canadian province name or abbreviation.
|
||||
|
||||
CASocialInsuranceNumberField
|
||||
----------------------------
|
||||
|
||||
A form field that validates input as a Canadian Social Insurance Number (SIN).
|
||||
A valid number must have the format XXX-XXX-XXXX and pass a `Luhn mod-10
|
||||
checksum`_.
|
||||
|
||||
.. _Luhn mod-10 checksum: http://en.wikipedia.org/wiki/Luhn_algorithm
|
||||
|
||||
CAProvinceSelect
|
||||
----------------
|
||||
|
||||
A ``Select`` widget that uses a list of Canadian provinces and territories as
|
||||
its choices.
|
||||
|
||||
|
||||
Chile (``django.contrib.localflavor.cl``)
|
||||
=========================================
|
||||
|
||||
CLRutField
|
||||
----------
|
||||
|
||||
A form field that validates input as a Chilean national identification number
|
||||
('Rol Unico Tributario' or RUT). The valid format is XX.XXX.XXX-X.
|
||||
|
||||
CLRegionSelect
|
||||
--------------
|
||||
|
||||
A ``Select`` widget that uses a list of Chilean regions (Regiones) as its
|
||||
choices.
|
||||
|
||||
|
||||
Finland (``django.contrib.localflavor.fi``)
|
||||
===========================================
|
||||
|
||||
FISocialSecurityNumber
|
||||
----------------------
|
||||
|
||||
A form field that validates input as a Finnish social security number.
|
||||
|
||||
FIZipCodeField
|
||||
--------------
|
||||
|
||||
A form field that validates input as a Finnish zip code. Valid codes
|
||||
consist of five digits.
|
||||
|
||||
FIMunicipalitySelect
|
||||
--------------------
|
||||
|
||||
A ``Select`` widget that uses a list of Finnish municipalities as its
|
||||
choices.
|
||||
|
||||
|
||||
France (``django.contrib.localflavor.fr``)
|
||||
==========================================
|
||||
|
||||
FRPhoneNumberField
|
||||
------------------
|
||||
|
||||
A form field that validates input as a French local phone number. The
|
||||
correct format is 0X XX XX XX XX. 0X.XX.XX.XX.XX and 0XXXXXXXXX validate
|
||||
but are corrected to 0X XX XX XX XX.
|
||||
|
||||
FRZipCodeField
|
||||
--------------
|
||||
|
||||
A form field that validates input as a French zip code. Valid codes
|
||||
consist of five digits.
|
||||
|
||||
FRDepartmentSelect
|
||||
------------------
|
||||
|
||||
A ``Select`` widget that uses a list of French departments as its choices.
|
||||
|
||||
|
||||
Germany (``django.contrib.localflavor.de``)
|
||||
===========================================
|
||||
|
||||
DEIdentityCardNumberField
|
||||
-------------------------
|
||||
|
||||
A form field that validates input as a German identity card number
|
||||
(Personalausweis_). Valid numbers have the format
|
||||
XXXXXXXXXXX-XXXXXXX-XXXXXXX-X, with no group consisting entirely of zeroes.
|
||||
|
||||
.. _Personalausweis: http://de.wikipedia.org/wiki/Personalausweis
|
||||
|
||||
DEZipCodeField
|
||||
--------------
|
||||
|
||||
A form field that validates input as a German zip code. Valid codes
|
||||
consist of five digits.
|
||||
|
||||
DEStateSelect
|
||||
-------------
|
||||
|
||||
A ``Select`` widget that uses a list of German states as its choices.
|
||||
|
||||
|
||||
Holland (``django.contrib.localflavor.nl``)
|
||||
===========================================
|
||||
|
||||
NLPhoneNumberField
|
||||
------------------
|
||||
|
||||
A form field that validates input as a Dutch telephone number.
|
||||
|
||||
NLSofiNumberField
|
||||
-----------------
|
||||
|
||||
A form field that validates input as a Dutch social security number
|
||||
(SoFI/BSN).
|
||||
|
||||
NLZipCodeField
|
||||
--------------
|
||||
|
||||
A form field that validates input as a Dutch zip code.
|
||||
|
||||
NLProvinceSelect
|
||||
----------------
|
||||
|
||||
A ``Select`` widget that uses a list of Dutch provinces as its list of
|
||||
choices.
|
||||
|
||||
|
||||
Iceland (``django.contrib.localflavor.is_``)
|
||||
============================================
|
||||
|
||||
ISIdNumberField
|
||||
---------------
|
||||
|
||||
A form field that validates input as an Icelandic identification number
|
||||
(kennitala). The format is XXXXXX-XXXX.
|
||||
|
||||
ISPhoneNumberField
|
||||
------------------
|
||||
|
||||
A form field that validates input as an Icelandtic phone number (seven
|
||||
digits with an optional hyphen or space after the first three digits).
|
||||
|
||||
ISPostalCodeSelect
|
||||
------------------
|
||||
|
||||
A ``Select`` widget that uses a list of Icelandic postal codes as its
|
||||
choices.
|
||||
|
||||
|
||||
India (``django.contrib.localflavor.in_``)
|
||||
==========================================
|
||||
|
||||
INStateField
|
||||
------------
|
||||
|
||||
A form field that validates input as an Indian state/territory name or
|
||||
abbreviation. Input is normalized to the standard two-letter vehicle
|
||||
registration abbreviation for the given state or territory.
|
||||
|
||||
INZipCodeField
|
||||
--------------
|
||||
|
||||
A form field that validates input as an Indian zip code, with the
|
||||
format XXXXXXX.
|
||||
|
||||
INStateSelect
|
||||
-------------
|
||||
|
||||
A ``Select`` widget that uses a list of Indian states/territories as its
|
||||
choices.
|
||||
|
||||
|
||||
Italy (``django.contrib.localflavor.it``)
|
||||
=========================================
|
||||
|
||||
ITSocialSecurityNumberField
|
||||
---------------------------
|
||||
|
||||
A form field that validates input as an Italian social security number
|
||||
(`codice fiscale`_).
|
||||
|
||||
.. _codice fiscale: http://www.agenziaentrate.it/ilwwcm/connect/Nsi/Servizi/Codice+fiscale+-+tessera+sanitaria/Codice+fiscale/NSI+Informazioni+sulla+codificazione+delle+persone+fisiche
|
||||
|
||||
ITVatNumberField
|
||||
----------------
|
||||
|
||||
A form field that validates Italian VAT numbers (partita IVA).
|
||||
|
||||
ITZipCodeField
|
||||
--------------
|
||||
|
||||
A form field that validates input as an Italian zip code. Valid codes
|
||||
must have five digits.
|
||||
|
||||
ITProvinceSelect
|
||||
----------------
|
||||
|
||||
A ``Select`` widget that uses a list of Italian provinces as its choices.
|
||||
|
||||
ITRegionSelect
|
||||
--------------
|
||||
|
||||
A ``Select`` widget that uses a list of Italian regions as its choices.
|
||||
|
||||
|
||||
Japan (``django.contrib.localflavor.jp``)
|
||||
=========================================
|
||||
|
||||
JPPostalCodeField
|
||||
-----------------
|
||||
|
||||
A form field that validates input as a Japanese postcode.
|
||||
It accepts seven digits, with or without a hyphen.
|
||||
|
||||
JPPrefectureSelect
|
||||
------------------
|
||||
|
||||
A ``Select`` widget that uses a list of Japanese prefectures as its choices.
|
||||
|
||||
|
||||
Mexico (``django.contrib.localflavor.mx``)
|
||||
==========================================
|
||||
|
||||
MXStateSelect
|
||||
-------------
|
||||
|
||||
A ``Select`` widget that uses a list of Mexican states as its choices.
|
||||
|
||||
|
||||
Norway (``django.contrib.localflavor.no``)
|
||||
==========================================
|
||||
|
||||
NOSocialSecurityNumber
|
||||
----------------------
|
||||
|
||||
A form field that validates input as a Norwegian social security number
|
||||
(personnummer_).
|
||||
|
||||
.. _personnummer: http://no.wikipedia.org/wiki/Personnummer
|
||||
|
||||
NOZipCodeField
|
||||
--------------
|
||||
|
||||
A form field that validates input as a Norwegian zip code. Valid codes
|
||||
have four digits.
|
||||
|
||||
NOMunicipalitySelect
|
||||
--------------------
|
||||
|
||||
A ``Select`` widget that uses a list of Norwegian municipalities (fylker) as
|
||||
its choices.
|
||||
|
||||
|
||||
Peru (``django.contrib.localflavor.pe``)
|
||||
========================================
|
||||
|
||||
PEDNIField
|
||||
----------
|
||||
|
||||
A form field that validates input as a DNI (Peruvian national identity)
|
||||
number.
|
||||
|
||||
PERUCField
|
||||
----------
|
||||
|
||||
A form field that validates input as an RUC (Registro Unico de
|
||||
Contribuyentes) number. Valid RUC numbers have eleven digits.
|
||||
|
||||
PEDepartmentSelect
|
||||
------------------
|
||||
|
||||
A ``Select`` widget that uses a list of Peruvian Departments as its choices.
|
||||
|
||||
|
||||
Poland (``django.contrib.localflavor.pl``)
|
||||
==========================================
|
||||
|
||||
PLNationalIdentificationNumberField
|
||||
-----------------------------------
|
||||
|
||||
A form field that validates input as a Polish national identification number
|
||||
(PESEL_).
|
||||
|
||||
.. _PESEL: http://en.wikipedia.org/wiki/PESEL
|
||||
|
||||
PLNationalBusinessRegisterField
|
||||
-------------------------------
|
||||
|
||||
A form field that validates input as a Polish National Official Business
|
||||
Register Number (REGON_), having either seven or nine digits. The checksum
|
||||
algorithm used for REGONs is documented at
|
||||
http://wipos.p.lodz.pl/zylla/ut/nip-rego.html.
|
||||
|
||||
.. _REGON: http://www.stat.gov.pl/bip/regon_ENG_HTML.htm
|
||||
|
||||
PLPostalCodeField
|
||||
-----------------
|
||||
|
||||
A form field that validates input as a Polish postal code. The valid format
|
||||
is XX-XXX, where X is a digit.
|
||||
|
||||
PLTaxNumberField
|
||||
----------------
|
||||
|
||||
A form field that validates input as a Polish Tax Number (NIP). Valid
|
||||
formats are XXX-XXX-XX-XX or XX-XX-XXX-XXX. The checksum algorithm used
|
||||
for NIPs is documented at http://wipos.p.lodz.pl/zylla/ut/nip-rego.html.
|
||||
|
||||
PLAdministrativeUnitSelect
|
||||
--------------------------
|
||||
|
||||
A ``Select`` widget that uses a list of Polish administrative units as its
|
||||
choices.
|
||||
|
||||
PLVoivodeshipSelect
|
||||
-------------------
|
||||
|
||||
A ``Select`` widget that uses a list of Polish voivodeships (administrative
|
||||
provinces) as its choices.
|
||||
|
||||
|
||||
Slovakia (``django.contrib.localflavor.sk``)
|
||||
============================================
|
||||
|
||||
SKPostalCodeField
|
||||
-----------------
|
||||
|
||||
A form field that validates input as a Slovak postal code. Valid formats
|
||||
are XXXXX or XXX XX, where X is a digit.
|
||||
|
||||
SKDistrictSelect
|
||||
----------------
|
||||
|
||||
A ``Select`` widget that uses a list of Slovak districts as its choices.
|
||||
|
||||
SKRegionSelect
|
||||
--------------
|
||||
|
||||
A ``Select`` widget that uses a list of Slovak regions as its choices.
|
||||
|
||||
|
||||
South Africa (``django.contrib.localflavor.za``)
|
||||
================================================
|
||||
|
||||
ZAIDField
|
||||
---------
|
||||
|
||||
A form field that validates input as a South African ID number. Validation
|
||||
uses the Luhn checksum and a simplistic (i.e., not entirely accurate) check
|
||||
for birth date.
|
||||
|
||||
ZAPostCodeField
|
||||
---------------
|
||||
|
||||
A form field that validates input as a South African postcode. Valid
|
||||
postcodes must have four digits.
|
||||
|
||||
|
||||
Spain (``django.contrib.localflavor.es``)
|
||||
=========================================
|
||||
|
||||
ESIdentityCardNumberField
|
||||
-------------------------
|
||||
|
||||
A form field that validates input as a Spanish NIF/NIE/CIF (Fiscal
|
||||
Identification Number) code.
|
||||
|
||||
ESCCCField
|
||||
----------
|
||||
|
||||
A form field that validates input as a Spanish bank account number (Codigo
|
||||
Cuenta Cliente or CCC). A valid CCC number has the format
|
||||
EEEE-OOOO-CC-AAAAAAAAAA, where the E, O, C and A digits denote the entity,
|
||||
office, checksum and account, respectively. The first checksum digit
|
||||
validates the entity and office. The second checksum digit validates the
|
||||
account. It is also valid to use a space as a delimiter, or to use no
|
||||
delimiter.
|
||||
|
||||
ESPhoneNumberField
|
||||
------------------
|
||||
|
||||
A form field that validates input as a Spanish phone number. Valid numbers
|
||||
have nine digits, the first of which is 6, 8 or 9.
|
||||
|
||||
ESPostalCodeField
|
||||
-----------------
|
||||
|
||||
A form field that validates input as a Spanish postal code. Valid codes
|
||||
have five digits, the first two being in the range 01 to 52, representing
|
||||
the province.
|
||||
|
||||
ESProvinceSelect
|
||||
----------------
|
||||
|
||||
A ``Select`` widget that uses a list of Spanish provinces as its choices.
|
||||
|
||||
ESRegionSelect
|
||||
--------------
|
||||
|
||||
A ``Select`` widget that uses a list of Spanish regions as its choices.
|
||||
|
||||
|
||||
Switzerland (``django.contrib.localflavor.ch``)
|
||||
===============================================
|
||||
|
||||
CHIdentityCardNumberField
|
||||
-------------------------
|
||||
|
||||
A form field that validates input as a Swiss identity card number.
|
||||
A valid number must confirm to the X1234567<0 or 1234567890 format and
|
||||
have the correct checksums -- see http://adi.kousz.ch/artikel/IDCHE.htm.
|
||||
|
||||
CHPhoneNumberField
|
||||
------------------
|
||||
|
||||
A form field that validates input as a Swiss phone number. The correct
|
||||
format is 0XX XXX XX XX. 0XX.XXX.XX.XX and 0XXXXXXXXX validate but are
|
||||
corrected to 0XX XXX XX XX.
|
||||
|
||||
CHZipCodeField
|
||||
--------------
|
||||
|
||||
A form field that validates input as a Swiss zip code. Valid codes
|
||||
consist of four digits.
|
||||
|
||||
CHStateSelect
|
||||
-------------
|
||||
|
||||
A ``Select`` widget that uses a list of Swiss states as its choices.
|
||||
|
||||
|
||||
United Kingdom (``django.contrib.localflavor.uk``)
|
||||
==================================================
|
||||
|
||||
UKPostcodeField
|
||||
---------------
|
||||
|
||||
A form field that validates input as a UK postcode. The regular
|
||||
expression used is sourced from the schema for British Standard BS7666
|
||||
address types at http://www.govtalk.gov.uk/gdsc/schemas/bs7666-v2-0.xsd.
|
||||
|
||||
|
||||
United States of America (``django.contrib.localflavor.us``)
|
||||
============================================================
|
||||
|
||||
USPhoneNumberField
|
||||
------------------
|
||||
|
||||
A form field that validates input as a U.S. phone number.
|
||||
|
||||
USSocialSecurityNumberField
|
||||
---------------------------
|
||||
|
||||
A form field that validates input as a U.S. Social Security Number (SSN).
|
||||
A valid SSN must obey the following rules:
|
||||
|
||||
* Format of XXX-XX-XXXX
|
||||
* No group of digits consisting entirely of zeroes
|
||||
* Leading group of digits cannot be 666
|
||||
* Number not in promotional block 987-65-4320 through 987-65-4329
|
||||
* Number not one known to be invalid due to widespread promotional
|
||||
use or distribution (e.g., the Woolworth's number or the 1962
|
||||
promotional number)
|
||||
|
||||
USStateField
|
||||
------------
|
||||
|
||||
A form field that validates input as a U.S. state name or abbreviation. It
|
||||
normalizes the input to the standard two-letter postal service abbreviation
|
||||
for the given state.
|
||||
|
||||
USZipCodeField
|
||||
--------------
|
||||
|
||||
A form field that validates input as a U.S. zip code. Valid formats are
|
||||
XXXXX or XXXXX-XXXX.
|
||||
|
||||
USStateSelect
|
||||
-------------
|
||||
|
||||
A form Select widget that uses a list of U.S. states/territories as its
|
||||
choices.
|
||||
@@ -58,11 +58,20 @@ Adds a few conveniences for perfectionists:
|
||||
which should be a list of strings.
|
||||
|
||||
* Performs URL rewriting based on the ``APPEND_SLASH`` and ``PREPEND_WWW``
|
||||
settings. If ``APPEND_SLASH`` is ``True``, URLs that lack a trailing
|
||||
slash will be redirected to the same URL with a trailing slash, unless the
|
||||
last component in the path contains a period. So ``foo.com/bar`` is
|
||||
redirected to ``foo.com/bar/``, but ``foo.com/bar/file.txt`` is passed
|
||||
through unchanged.
|
||||
settings.
|
||||
|
||||
If ``APPEND_SLASH`` is ``True`` and the initial URL doesn't end with a slash,
|
||||
and it is not found in urlpatterns, a new URL is formed by appending a slash
|
||||
at the end. If this new URL is found in urlpatterns, then an HTTP-redirect is
|
||||
returned to this new URL; otherwise the initial URL is processed as usual.
|
||||
|
||||
So ``foo.com/bar`` will be redirected to ``foo.com/bar/`` if you do not
|
||||
have a valid urlpattern for ``foo.com/bar``, and do have a valid urlpattern
|
||||
for ``foo.com/bar/``.
|
||||
|
||||
**New in Django development version:** The behaviour of ``APPEND_SLASH`` has
|
||||
changed slightly in the development version (it didn't used to check to see
|
||||
if the pattern was matched in the URL patterns).
|
||||
|
||||
If ``PREPEND_WWW`` is ``True``, URLs that lack a leading "www." will be
|
||||
redirected to the same URL with a leading "www."
|
||||
|
||||
@@ -618,8 +618,9 @@ statement for this field.
|
||||
**New in Django development version**
|
||||
|
||||
The name of the database tablespace to use for this field's index, if
|
||||
indeed this field is indexed. The default is the ``db_tablespace`` of
|
||||
the model, if any. If the backend doesn't support tablespaces, this
|
||||
indeed this field is indexed. The default is the project's
|
||||
``DEFAULT_INDEX_TABLESPACE`` setting, if set, or the ``db_tablespace``
|
||||
of the model, if any. If the backend doesn't support tablespaces, this
|
||||
option is ignored.
|
||||
|
||||
``default``
|
||||
|
||||
310
docs/modelforms.txt
Normal file
310
docs/modelforms.txt
Normal file
@@ -0,0 +1,310 @@
|
||||
==========================
|
||||
Using newforms with models
|
||||
==========================
|
||||
|
||||
``ModelForm``
|
||||
=============
|
||||
|
||||
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 helper class that let you create a ``Form``
|
||||
class from a Django model.
|
||||
|
||||
For example::
|
||||
|
||||
>>> from django.newforms import ModelForm
|
||||
|
||||
# Create the form class.
|
||||
>>> class ArticleForm(ModelForm):
|
||||
... class Meta:
|
||||
... model = Article
|
||||
|
||||
# Creating a form to add an article.
|
||||
>>> article = Article()
|
||||
>>> form = ArticleForm(article)
|
||||
|
||||
# Creating a form to change an existing article.
|
||||
>>> article = Article.objects.get(pk=1)
|
||||
>>> form = ArticleForm(article)
|
||||
|
||||
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 ``max_length``
|
||||
``CommaSeparatedIntegerField`` ``CharField``
|
||||
``DateField`` ``DateField``
|
||||
``DateTimeField`` ``DateTimeField``
|
||||
``DecimalField`` ``DecimalField``
|
||||
``EmailField`` ``EmailField``
|
||||
``FileField`` ``FileField``
|
||||
``FilePathField`` ``CharField``
|
||||
``FloatField`` ``FloatField``
|
||||
``ForeignKey`` ``ModelChoiceField`` (see below)
|
||||
``ImageField`` ``ImageField``
|
||||
``IntegerField`` ``IntegerField``
|
||||
``IPAddressField`` ``IPAddressField``
|
||||
``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``
|
||||
=============================== ========================================
|
||||
|
||||
|
||||
.. note::
|
||||
The ``FloatField`` form field and ``DecimalField`` model and form fields
|
||||
are new in the development version.
|
||||
|
||||
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``. The choices will normally include the blank choice which is
|
||||
selected by default. If the field is required, this forces the user to
|
||||
make a selection. The blank choice will not be included if the model
|
||||
field has ``blank=False`` and an explicit ``default`` value (the
|
||||
``default`` value will be initially selected instead).
|
||||
|
||||
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(max_length=100)
|
||||
title = models.CharField(max_length=3, choices=TITLE_CHOICES)
|
||||
birth_date = models.DateField(blank=True, null=True)
|
||||
|
||||
def __unicode__(self):
|
||||
return self.name
|
||||
|
||||
class Book(models.Model):
|
||||
name = models.CharField(max_length=100)
|
||||
authors = models.ManyToManyField(Author)
|
||||
|
||||
class AuthorForm(ModelForm):
|
||||
class Meta:
|
||||
model = Author
|
||||
|
||||
class BookForm(ModelForm):
|
||||
class Meta:
|
||||
model = Book
|
||||
|
||||
With these models, the ``ModelForm`` subclasses above would be roughly
|
||||
equivalent to this (the only difference being the ``save()`` method, which
|
||||
we'll discuss in a moment.)::
|
||||
|
||||
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)
|
||||
|
||||
class BookForm(forms.Form):
|
||||
name = forms.CharField(max_length=100)
|
||||
authors = forms.ModelMultipleChoiceField(queryset=Author.objects.all())
|
||||
|
||||
The ``save()`` method
|
||||
---------------------
|
||||
|
||||
Every form produced by ``ModelForm`` also has a ``save()`` method. This
|
||||
method creates and saves a database object from the data bound to the form.
|
||||
A subclass of ``ModelForm`` also requires a model instance as the first
|
||||
arument to its constructor. For example::
|
||||
|
||||
# Create a form instance from POST data.
|
||||
>>> a = Article()
|
||||
>>> f = ArticleForm(a, 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``.
|
||||
|
||||
This ``save()`` method accepts an optional ``commit`` keyword argument, which
|
||||
accepts either ``True`` or ``False``. If you call ``save()`` with
|
||||
``commit=False``, then it will return an object that hasn't yet been saved to
|
||||
the database. In this case, it's up to you to call ``save()`` on the resulting
|
||||
model instance. This is useful if you want to do custom processing on the
|
||||
object before saving it. ``commit`` is ``True`` by default.
|
||||
|
||||
Another side effect of using ``commit=False`` is seen when your model has
|
||||
a many-to-many relation with another model. If your model has a many-to-many
|
||||
relation and you specify ``commit=False`` when you save a form, Django cannot
|
||||
immediately save the form data for the many-to-many relation. This is because
|
||||
it isn't possible to save many-to-many data for an instance until the instance
|
||||
exists in the database.
|
||||
|
||||
To work around this problem, every time you save a form using ``commit=False``,
|
||||
Django adds a ``save_m2m()`` method to your ``ModelForm`` subclass. After
|
||||
you've manually saved the instance produced by the form, you can invoke
|
||||
``save_m2m()`` to save the many-to-many form data. For example::
|
||||
|
||||
# Create a form instance with POST data.
|
||||
>>> a = Author()
|
||||
>>> f = AuthorForm(a, request.POST)
|
||||
|
||||
# Create, but don't save the new author instance.
|
||||
>>> new_author = f.save(commit=False)
|
||||
|
||||
# Modify the author in some way.
|
||||
>>> new_author.some_field = 'some_value'
|
||||
|
||||
# Save the new instance.
|
||||
>>> new_author.save()
|
||||
|
||||
# Now, save the many-to-many data for the form.
|
||||
>>> f.save_m2m()
|
||||
|
||||
Calling ``save_m2m()`` is only required if you use ``save(commit=False)``.
|
||||
When you use a simple ``save()`` on a form, all data -- including
|
||||
many-to-many data -- is saved without the need for any additional method calls.
|
||||
For example::
|
||||
|
||||
# Create a form instance with POST data.
|
||||
>>> a = Author()
|
||||
>>> f = AuthorForm(a, request.POST)
|
||||
|
||||
# Create and save the new author instance. There's no need to do anything else.
|
||||
>>> new_author = f.save()
|
||||
|
||||
Using a subset of fields on the form
|
||||
------------------------------------
|
||||
|
||||
In some cases, you may not want all the model fields to appear on the generated
|
||||
form. There are three ways of telling ``ModelForm`` 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 ``ModelForm`` will not include that
|
||||
field.
|
||||
|
||||
2. Use the ``fields`` attribute of the ``ModelForm``'s inner ``Meta`` class.
|
||||
This attribute, if given, should be a list of field names to include in
|
||||
the form.
|
||||
|
||||
3. Use the ``exclude`` attribute of the ``ModelForm``'s inner ``Meta`` class.
|
||||
This attribute, if given, should be a list of field names to exclude
|
||||
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`` or ``exclude`` like this::
|
||||
|
||||
class PartialAuthorForm(ModelForm):
|
||||
class Meta:
|
||||
model = Author
|
||||
fields = ('name', 'title')
|
||||
|
||||
class PartialAuthorForm(ModelForm):
|
||||
class Meta:
|
||||
model = Author
|
||||
exclude = ('birth_date',)
|
||||
|
||||
Since the Author model has only 3 fields, 'name', 'title', and
|
||||
'birth_date', the forms above will contain exactly the same fields.
|
||||
|
||||
.. note::
|
||||
|
||||
If you specify ``fields`` or ``exclude`` when creating a form with
|
||||
``ModelForm``, then the fields that are not in the resulting form will not
|
||||
be set by the form's ``save()`` method. Django will prevent any attempt to
|
||||
save an incomplete model, so if the model does not allow the missing fields
|
||||
to be empty, and does not provide a default value for the missing fields,
|
||||
any attempt to ``save()`` a ``ModelForm`` with missing fields will fail.
|
||||
To avoid this failure, you must instantiate your model with initial values
|
||||
for the missing, but required fields, or use ``save(commit=False)`` and
|
||||
manually set anyextra required fields::
|
||||
|
||||
instance = Instance(required_field='value')
|
||||
form = InstanceForm(instance, request.POST)
|
||||
new_instance = form.save()
|
||||
|
||||
instance = form.save(commit=False)
|
||||
instance.required_field = 'new value'
|
||||
new_instance = instance.save()
|
||||
|
||||
See the `section on saving forms`_ for more details on using
|
||||
``save(commit=False)``.
|
||||
|
||||
.. _section on saving forms: `The save() method`_
|
||||
|
||||
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
|
||||
``ModelForm`` gives you the flexibility of changing the form field type
|
||||
for a given model field. You do this by declaratively specifying fields like
|
||||
you would in a regular ``Form``. Declared fields will override the default
|
||||
ones generated by using the ``model`` attribute.
|
||||
|
||||
For example, if you wanted to use ``MyDateFormField`` for the ``pub_date``
|
||||
field, you could do the following::
|
||||
|
||||
>>> class ArticleForm(ModelForm):
|
||||
... pub_date = MyDateFormField()
|
||||
...
|
||||
... class Meta:
|
||||
... model = Article
|
||||
@@ -759,8 +759,9 @@ For example::
|
||||
Highlighting required fields in templates
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
You may wish to show a visitor which fields are required. Here is the above
|
||||
example modified to insert an asterix after the label of each required field::
|
||||
It's common to show a user which fields are required. Here's an example of how
|
||||
to do that, using the above example modified to insert an asterisk after the
|
||||
label of each required field::
|
||||
|
||||
<form method="post" action="">
|
||||
<dl>
|
||||
@@ -775,10 +776,11 @@ example modified to insert an asterix after the label of each required field::
|
||||
</form>
|
||||
|
||||
The ``{% if field.field.required %}*{% endif %}`` fragment is the relevant
|
||||
addition here. It adds the asterix only if the field is required. Note that we
|
||||
check ``field.field.required`` and not ``field.required``. In the template,
|
||||
``field`` is a ``newforms.forms.BoundField`` instance, which holds the actual
|
||||
``Field`` instance in its ``field`` attribute.
|
||||
addition here. It adds the asterisk only if the field is required.
|
||||
|
||||
Note that we check ``field.field.required`` and not ``field.required``. In the
|
||||
template, ``field`` is a ``newforms.forms.BoundField`` instance, which holds
|
||||
the actual ``Field`` instance in its ``field`` attribute.
|
||||
|
||||
Binding uploaded files to a form
|
||||
--------------------------------
|
||||
@@ -1108,9 +1110,9 @@ fields. We've specified ``auto_id=False`` to simplify the output::
|
||||
|
||||
**New in Django development version**
|
||||
|
||||
The ``error_messages`` argument lets you override the default messages which the
|
||||
The ``error_messages`` argument lets you override the default messages that the
|
||||
field will raise. Pass in a dictionary with keys matching the error messages you
|
||||
want to override. For example::
|
||||
want to override. For example, here is the default error message::
|
||||
|
||||
>>> generic = forms.CharField()
|
||||
>>> generic.clean('')
|
||||
@@ -1118,14 +1120,16 @@ want to override. For example::
|
||||
...
|
||||
ValidationError: [u'This field is required.']
|
||||
|
||||
And here is a custom error message::
|
||||
|
||||
>>> name = forms.CharField(error_messages={'required': 'Please enter your name'})
|
||||
>>> name.clean('')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValidationError: [u'Please enter your name']
|
||||
|
||||
In the `built-in Field classes`_ section below, each Field defines the error
|
||||
message keys it uses.
|
||||
In the `built-in Field classes`_ section below, each ``Field`` defines the
|
||||
error message keys it uses.
|
||||
|
||||
Dynamic initial values
|
||||
----------------------
|
||||
@@ -1435,7 +1439,7 @@ Also takes the following optional arguments:
|
||||
The optional argument ``error_message`` is also accepted for backwards
|
||||
compatibility. The preferred way to provide an error message is to use the
|
||||
``error_messages`` argument, passing a dictionary with ``'invalid'`` as a key
|
||||
and the error message as the value.
|
||||
and the error message as the value.
|
||||
|
||||
``TimeField``
|
||||
~~~~~~~~~~~~~
|
||||
@@ -1769,421 +1773,14 @@ You can then use this field whenever you have a form that requires a comment::
|
||||
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.
|
||||
The prefered way of generating forms that work with models is explained in the
|
||||
`ModelForms documentation`_.
|
||||
|
||||
For this reason, Django provides a few helper functions that let you create a
|
||||
``Form`` class from a Django model.
|
||||
Looking for the ``form_for_model`` and ``form_for_instance`` documentation?
|
||||
They've been deprecated, but you can still `view the documentation`_.
|
||||
|
||||
``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 ``max_length``
|
||||
``CommaSeparatedIntegerField`` ``CharField``
|
||||
``DateField`` ``DateField``
|
||||
``DateTimeField`` ``DateTimeField``
|
||||
``DecimalField`` ``DecimalField``
|
||||
``EmailField`` ``EmailField``
|
||||
``FileField`` ``FileField``
|
||||
``FilePathField`` ``CharField``
|
||||
``FloatField`` ``FloatField``
|
||||
``ForeignKey`` ``ModelChoiceField`` (see below)
|
||||
``ImageField`` ``ImageField``
|
||||
``IntegerField`` ``IntegerField``
|
||||
``IPAddressField`` ``IPAddressField``
|
||||
``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``
|
||||
=============================== ========================================
|
||||
|
||||
|
||||
.. note::
|
||||
The ``FloatField`` form field and ``DecimalField`` model and form fields
|
||||
are new in the development version.
|
||||
|
||||
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``. The choices will normally include the blank choice which is
|
||||
selected by default. If the field is required, this forces the user to
|
||||
make a selection. The blank choice will not be included if the model
|
||||
field has ``blank=False`` and an explicit ``default`` value (the
|
||||
``default`` value will be initially selected instead).
|
||||
|
||||
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(max_length=100)
|
||||
title = models.CharField(max_length=3, choices=TITLE_CHOICES)
|
||||
birth_date = models.DateField(blank=True, null=True)
|
||||
|
||||
def __unicode__(self):
|
||||
return self.name
|
||||
|
||||
class Book(models.Model):
|
||||
name = models.CharField(max_length=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``.
|
||||
|
||||
This ``save()`` method accepts an optional ``commit`` keyword argument, which
|
||||
accepts either ``True`` or ``False``. If you call ``save()`` with
|
||||
``commit=False``, then it will return an object that hasn't yet been saved to
|
||||
the database. In this case, it's up to you to call ``save()`` on the resulting
|
||||
model instance. This is useful if you want to do custom processing on the
|
||||
object before saving it. ``commit`` is ``True`` by default.
|
||||
|
||||
Another side effect of using ``commit=False`` is seen when your model has
|
||||
a many-to-many relation with another model. If your model has a many-to-many
|
||||
relation and you specify ``commit=False`` when you save a form, Django cannot
|
||||
immediately save the form data for the many-to-many relation. This is because
|
||||
it isn't possible to save many-to-many data for an instance until the instance
|
||||
exists in the database.
|
||||
|
||||
To work around this problem, every time you save a form using ``commit=False``,
|
||||
Django adds a ``save_m2m()`` method to the form created by ``form_for_model``.
|
||||
After you've manually saved the instance produced by the form, you can invoke
|
||||
``save_m2m()`` to save the many-to-many form data. For example::
|
||||
|
||||
# Create a form instance with POST data.
|
||||
>>> f = AuthorForm(request.POST)
|
||||
|
||||
# Create, but don't save the new author instance.
|
||||
>>> new_author = f.save(commit=False)
|
||||
|
||||
# Modify the author in some way.
|
||||
>>> new_author.some_field = 'some_value'
|
||||
|
||||
# Save the new instance.
|
||||
>>> new_author.save()
|
||||
|
||||
# Now, save the many-to-many data for the form.
|
||||
>>> f.save_m2m()
|
||||
|
||||
Calling ``save_m2m()`` is only required if you use ``save(commit=False)``.
|
||||
When you use a simple ``save()`` on a form, all data -- including
|
||||
many-to-many data -- is saved without the need for any additional method calls.
|
||||
For example::
|
||||
|
||||
# Create a form instance with POST data.
|
||||
>>> f = AuthorForm(request.POST)
|
||||
|
||||
# Create and save the new author instance. There's no need to do anything else.
|
||||
>>> new_author = f.save()
|
||||
|
||||
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()``,
|
||||
then the fields that are *not* specified will not be set by the form's
|
||||
``save()`` method. Django will prevent any attempt to save an incomplete
|
||||
model, so if the model does not allow the missing fields to be empty, and
|
||||
does not provide a default value for the missing fields, any attempt to
|
||||
``save()`` a ``form_for_model`` with missing fields will fail. To avoid
|
||||
this failure, you must use ``save(commit=False)`` and manually set any
|
||||
extra required fields::
|
||||
|
||||
instance = form.save(commit=False)
|
||||
instance.required_field = 'new value'
|
||||
instance.save()
|
||||
|
||||
See the `section on saving forms`_ for more details on using
|
||||
``save(commit=False)``.
|
||||
|
||||
.. _section on saving forms: `The save() method`_
|
||||
|
||||
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(Article, 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.
|
||||
|
||||
.. warning::
|
||||
The field that is passed into the ``formfield_callback`` function in
|
||||
``form_for_model()`` and ``form_for_instance`` is the field instance from
|
||||
your model's class. You **must not** alter that object at all; treat it
|
||||
as read-only!
|
||||
|
||||
If you make any alterations to that object, it will affect any future
|
||||
users of the model class, because you will have changed the field object
|
||||
used to construct the class. This is almost certainly what you don't want
|
||||
to have happen.
|
||||
|
||||
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.
|
||||
|
||||
Unlike ``form_for_model()``, a choice field in form created by
|
||||
``form_for_instance()`` will not include the blank choice if the respective
|
||||
model field has ``blank=False``. The initial choice is drawn from the instance.
|
||||
|
||||
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()``.
|
||||
|
||||
Let's modify the earlier `contact form`_ view example a little bit. Suppose we
|
||||
have a ``Message`` model that holds each contact submission. Something like::
|
||||
|
||||
class Message(models.Model):
|
||||
subject = models.CharField(max_length=100)
|
||||
message = models.TextField()
|
||||
sender = models.EmailField()
|
||||
cc_myself = models.BooleanField(required=False)
|
||||
|
||||
You could use this model to create a form (using ``form_for_model()``). You
|
||||
could also use existing ``Message`` instances to create a form for editing
|
||||
messages. The earlier_ view can be changed slightly to accept the ``id`` value
|
||||
of an existing ``Message`` and present it for editing::
|
||||
|
||||
def contact_edit(request, msg_id):
|
||||
# Create the form from the message id.
|
||||
message = get_object_or_404(Message, id=msg_id)
|
||||
ContactForm = form_for_instance(message)
|
||||
|
||||
if request.method == 'POST':
|
||||
form = ContactForm(request.POST)
|
||||
if form.is_valid():
|
||||
form.save()
|
||||
return HttpResponseRedirect('/url/on_success/')
|
||||
else:
|
||||
form = ContactForm()
|
||||
return render_to_response('contact.html', {'form': form})
|
||||
|
||||
Aside from how we create the ``ContactForm`` class here, the main point to
|
||||
note is that the form display in the ``GET`` branch of the function
|
||||
will use the values from the ``message`` instance as initial values for the
|
||||
form field.
|
||||
|
||||
.. _contact form: `Simple view example`_
|
||||
.. _earlier: `Simple view example`_
|
||||
|
||||
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.
|
||||
.. _ModelForms documentation: ../modelforms/
|
||||
.. _view the documentation: ../form_for_model/
|
||||
|
||||
Media
|
||||
=====
|
||||
|
||||
@@ -555,10 +555,13 @@ Three things to note about 404 views:
|
||||
* The 404 view is also called if Django doesn't find a match after checking
|
||||
every regular expression in the URLconf.
|
||||
|
||||
* If you don't define your own 404 view -- and simply use the default,
|
||||
which is recommended -- you still have one obligation: To create a
|
||||
``404.html`` template in the root of your template directory. The default
|
||||
404 view will use that template for all 404 errors.
|
||||
* If you don't define your own 404 view -- and simply use the
|
||||
default, which is recommended -- you still have one obligation:
|
||||
you must create a ``404.html`` template in the root of your
|
||||
template directory. The default 404 view will use that template
|
||||
for all 404 errors. The default 404 view will pass one variable
|
||||
to the template: ``request_path``, which is the URL which
|
||||
resulted in the 404.
|
||||
|
||||
* If ``DEBUG`` is set to ``True`` (in your settings module) then your 404
|
||||
view will never be used, and the traceback will be displayed instead.
|
||||
@@ -572,7 +575,8 @@ the view ``django.views.defaults.server_error``, which loads and renders the
|
||||
template ``500.html``.
|
||||
|
||||
This means you need to define a ``500.html`` template in your root template
|
||||
directory. This template will be used for all server errors.
|
||||
directory. This template will be used for all server errors. The
|
||||
default 500 view passes no variables to this template.
|
||||
|
||||
This ``server_error`` view should suffice for 99% of Web applications, but if
|
||||
you want to override the view, you can specify ``handler500`` in your
|
||||
|
||||
@@ -135,8 +135,8 @@ For example::
|
||||
json_serializer = serializers.get_serializer("json")()
|
||||
json_serializer.serialize(queryset, ensure_ascii=False, stream=response)
|
||||
|
||||
Django ships with a copy of simplejson_ in the source. Be aware, that if
|
||||
you're using that for serializing directly that not all Django output can be
|
||||
The Django source code includes the simplejson_ module. Be aware that if
|
||||
you're serializing using that module directly, not all Django output can be
|
||||
passed unmodified to simplejson. In particular, `lazy translation objects`_
|
||||
need a `special encoder`_ written for them. Something like this will work::
|
||||
|
||||
@@ -151,8 +151,3 @@ need a `special encoder`_ written for them. Something like this will work::
|
||||
|
||||
.. _lazy translation objects: ../i18n/#lazy-translation
|
||||
.. _special encoder: http://svn.red-bean.com/bob/simplejson/tags/simplejson-1.7/docs/index.html
|
||||
|
||||
Writing custom serializers
|
||||
``````````````````````````
|
||||
|
||||
XXX ...
|
||||
|
||||
@@ -99,6 +99,8 @@ It implements the following standard dictionary methods:
|
||||
|
||||
* ``items()``
|
||||
|
||||
* ``setdefault()``
|
||||
|
||||
It also has these three methods:
|
||||
|
||||
* ``set_test_cookie()``
|
||||
|
||||
@@ -225,6 +225,27 @@ Whether to append trailing slashes to URLs. This is only used if
|
||||
``CommonMiddleware`` is installed (see the `middleware docs`_). See also
|
||||
``PREPEND_WWW``.
|
||||
|
||||
AUTHENTICATION_BACKENDS
|
||||
-----------------------
|
||||
|
||||
Default: ``('django.contrib.auth.backends.ModelBackend',)``
|
||||
|
||||
A tuple of authentication backend classes (as strings) to use when
|
||||
attempting to authenticate a user. See the `authentication backends
|
||||
documentation`_ for details.
|
||||
|
||||
.. _authentication backends documentation: ../authentication/#other-authentication-sources
|
||||
|
||||
AUTH_PROFILE_MODULE
|
||||
-------------------
|
||||
|
||||
Default: Not defined
|
||||
|
||||
The site-specific user profile model used by this site. See the
|
||||
`documentation on user profile models`_ for details.
|
||||
|
||||
.. _documentation on user profile models: ../authentication/#storing-additional-information-about-users
|
||||
|
||||
CACHE_BACKEND
|
||||
-------------
|
||||
|
||||
@@ -393,6 +414,22 @@ Default: ``'webmaster@localhost'``
|
||||
Default e-mail address to use for various automated correspondence from the
|
||||
site manager(s).
|
||||
|
||||
DEFAULT_TABLESPACE
|
||||
------------------
|
||||
|
||||
Default: ``''`` (Empty string)
|
||||
|
||||
Default tablespace to use for models that do not specify one, if the
|
||||
backend supports it.
|
||||
|
||||
DEFAULT_INDEX_TABLESPACE
|
||||
------------------------
|
||||
|
||||
Default: ``''`` (Empty string)
|
||||
|
||||
Default tablespace to use for indexes on fields that do not specify
|
||||
one, if the backend supports it.
|
||||
|
||||
DISALLOWED_USER_AGENTS
|
||||
----------------------
|
||||
|
||||
@@ -1129,12 +1166,12 @@ If you're not setting the ``DJANGO_SETTINGS_MODULE`` environment variable, you
|
||||
settings.
|
||||
|
||||
If you don't set ``DJANGO_SETTINGS_MODULE`` and don't call ``configure()``,
|
||||
Django will raise an ``EnvironmentError`` exception the first time a setting
|
||||
Django will raise an ``ImportError`` exception the first time a setting
|
||||
is accessed.
|
||||
|
||||
If you set ``DJANGO_SETTINGS_MODULE``, access settings values somehow, *then*
|
||||
call ``configure()``, Django will raise an ``EnvironmentError`` saying settings
|
||||
have already been configured.
|
||||
call ``configure()``, Django will raise a ``RuntimeError`` indicating
|
||||
that settings have already been configured.
|
||||
|
||||
Also, it's an error to call ``configure()`` more than once, or to call
|
||||
``configure()`` after any setting has been accessed.
|
||||
|
||||
@@ -98,8 +98,8 @@ This example is equivalent to::
|
||||
except MyModel.DoesNotExist:
|
||||
raise Http404
|
||||
|
||||
Note: As with ``get()``, an ``AssertionError`` will be raised if more than
|
||||
one object is found.
|
||||
Note: As with ``get()``, an ``MultipleObjectsReturned`` exception will be
|
||||
raised if more than one object is found.
|
||||
|
||||
.. _get(): ../db-api/#get-kwargs
|
||||
|
||||
|
||||
@@ -603,8 +603,9 @@ This example illustrates all possible attributes and methods for a ``Feed`` clas
|
||||
# ITEM LINK -- One of these three is required. The framework looks for
|
||||
# them in this order.
|
||||
|
||||
# First, the framework tries the get_absolute_url() method on each item
|
||||
# returned by items(). Failing that, it tries these two methods:
|
||||
# First, the framework tries the two methods below, in
|
||||
# order. Failing that, it falls back to the get_absolute_url()
|
||||
# method on each item returned by items().
|
||||
|
||||
def item_link(self, item):
|
||||
"""
|
||||
|
||||
@@ -310,58 +310,106 @@ Automatic HTML escaping
|
||||
|
||||
**New in Django development version**
|
||||
|
||||
A very real problem when creating HTML (and other) output using templates and
|
||||
variable substitution is the possibility of accidently inserting some variable
|
||||
value that affects the resulting HTML. For example, a template fragment such as
|
||||
::
|
||||
When generating HTML from templates, there's always a risk that a variable will
|
||||
include characters that affect the resulting HTML. For example, consider this
|
||||
template fragment::
|
||||
|
||||
Hello, {{ name }}.
|
||||
|
||||
seems like a harmless way to display the user's name. However, if you are
|
||||
displaying data that the user entered directly and they had entered their name as ::
|
||||
At first, this seems like a harmless way to display a user's name, but consider
|
||||
what would happen if the user entered his name as this::
|
||||
|
||||
<script>alert('hello')</script>
|
||||
|
||||
this would always display a Javascript alert box when the page was loaded.
|
||||
Similarly, if you were displaying some data generated by another process and it
|
||||
contained a '<' symbol, you couldn't just dump this straight into your HTML,
|
||||
because it would be treated as the start of an element. The effects of these
|
||||
sorts of problems can vary from merely annoying to allowing exploits via `Cross
|
||||
Site Scripting`_ (XSS) attacks.
|
||||
With this name value, the template would be rendered as::
|
||||
|
||||
Hello, <script>alert('hello')</script>
|
||||
|
||||
...which means the browser would pop-up a JavaScript alert box!
|
||||
|
||||
Similarly, what if the name contained a ``'<'`` symbol, like this?
|
||||
|
||||
<b>username
|
||||
|
||||
That would result in a rendered template like this::
|
||||
|
||||
Hello, <b>username
|
||||
|
||||
...which, in turn, would result in the remainder of the Web page being bolded!
|
||||
|
||||
Clearly, user-submitted data shouldn't be trusted blindly and inserted directly
|
||||
into your Web pages, because a malicious user could use this kind of hole to
|
||||
do potentially bad things. This type of security exploit is called a
|
||||
`Cross Site Scripting`_ (XSS) attack.
|
||||
|
||||
To avoid this problem, you have two options:
|
||||
|
||||
* One, you can make sure to run each untrusted variable through the
|
||||
``escape`` filter (documented below), which converts potentially harmful
|
||||
HTML characters to unharmful ones. This was default the default solution
|
||||
in Django for its first few years, but the problem is that it puts the
|
||||
onus on *you*, the developer / template author, to ensure you're escaping
|
||||
everything. It's easy to forget to escape data.
|
||||
|
||||
* Two, you can take advantage of Django's automatic HTML escaping. The
|
||||
remainder of this section describes how auto-escaping works.
|
||||
|
||||
By default in the Django development version, every template automatically
|
||||
escapes the output of every variable tag. Specifically, these five characters
|
||||
are escaped:
|
||||
|
||||
* ``<`` is converted to ``<``
|
||||
* ``>`` is converted to ``>``
|
||||
* ``'`` (single quote) is converted to ``'``
|
||||
* ``"`` (double quote) is converted to ``"``
|
||||
* ``&`` is converted to ``&``
|
||||
|
||||
Again, we stress that this behavior is on by default. If you're using Django's
|
||||
template system, you're protected.
|
||||
|
||||
.. _Cross Site Scripting: http://en.wikipedia.org/wiki/Cross-site_scripting
|
||||
|
||||
In order to provide some protection against these problems, Django
|
||||
provides automatic (but controllable) HTML escaping for data coming from
|
||||
tempate variables. Inside this tag, any data that comes from template
|
||||
variables is examined to see if it contains one of the five HTML characters
|
||||
(<, >, ', " and &) that often need escaping and those characters are converted
|
||||
to their respective HTML entities. It causes no harm if a character is
|
||||
converted to an entity when it doesn't need to be, so all five characters are
|
||||
always converted.
|
||||
How to turn it off
|
||||
------------------
|
||||
|
||||
Since some variables will contain data that is *intended* to be rendered
|
||||
as HTML, template tag and filter writers can mark their output strings as
|
||||
requiring no further escaping. For example, the ``unordered_list`` filter is
|
||||
designed to return raw HTML and we want the template processor to simply
|
||||
display the results as returned, without applying any escaping. That is taken
|
||||
care of by the filter. The template author need do nothing special in that
|
||||
case.
|
||||
If you don't want data to be auto-escaped, on a per-site, per-template level or
|
||||
per-variable level, you can turn it off in several ways.
|
||||
|
||||
By default, automatic HTML escaping is always applied. However, sometimes you
|
||||
will not want this to occur (for example, if you're using the templating
|
||||
system to create an email). To control automatic escaping inside your template,
|
||||
wrap the affected content in the ``autoescape`` tag, like so::
|
||||
Why would you want to turn it off? Because sometimes, template variables
|
||||
contain data that you *intend* to be rendered as raw HTML, in which case you
|
||||
don't want their contents to be escaped. For example, you might store a blob of
|
||||
HTML in your database and want to embed that directly into your template. Or,
|
||||
you might be using Django's template system to produce text that is *not* HTML
|
||||
-- like an e-mail message, for instance.
|
||||
|
||||
For individual variables
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
To disable auto-escaping for an individual variable, use the ``safe`` filter::
|
||||
|
||||
This will be escaped: {{ data }}
|
||||
This will not be escaped: {{ data|safe }}
|
||||
|
||||
Think of *safe* as shorthand for *safe from further escaping* or *can be
|
||||
safely interpreted as HTML*. In this example, if ``data`` contains ``'<b>'``,
|
||||
the output will be::
|
||||
|
||||
This will be escaped: <b>
|
||||
This will not be escaped: <b>
|
||||
|
||||
For template blocks
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
To control auto-escaping for a template, wrap the template (or just a
|
||||
particular section of the template) in the ``autoescape`` tag, like so::
|
||||
|
||||
{% autoescape off %}
|
||||
Hello {{ name }}
|
||||
{% endautoescape %}
|
||||
|
||||
The auto-escaping tag passes its effect onto templates that extend the
|
||||
current one as well as templates included via the ``include`` tag, just like
|
||||
all block tags.
|
||||
|
||||
The ``autoescape`` tag takes either ``on`` or ``off`` as its argument. At times, you might want to force auto-escaping when it would otherwise be disabled. For example::
|
||||
The ``autoescape`` tag takes either ``on`` or ``off`` as its argument. At
|
||||
times, you might want to force auto-escaping when it would otherwise be
|
||||
disabled. Here is an example template::
|
||||
|
||||
Auto-escaping is on by default. Hello {{ name }}
|
||||
|
||||
@@ -370,52 +418,60 @@ The ``autoescape`` tag takes either ``on`` or ``off`` as its argument. At times,
|
||||
|
||||
Nor this: {{ other_data }}
|
||||
{% autoescape on %}
|
||||
Auto-escaping applies again, {{ name }}
|
||||
Auto-escaping applies again: {{ name }}
|
||||
{% endautoescape %}
|
||||
{% endautoescape %}
|
||||
|
||||
For individual variables, the ``safe`` filter can also be used to indicate
|
||||
that the contents should not be automatically escaped::
|
||||
The auto-escaping tag passes its effect onto templates that extend the
|
||||
current one as well as templates included via the ``include`` tag, just like
|
||||
all block tags. For example::
|
||||
|
||||
This will be escaped: {{ data }}
|
||||
This will not be escaped: {{ data|safe }}
|
||||
# base.html
|
||||
|
||||
Think of *safe* as shorthand for *safe from further escaping* or *can be
|
||||
safely interpreted as HTML*. In this example, if ``data`` contains ``'<a>'``,
|
||||
the output will be::
|
||||
{% autoescape off %}
|
||||
<h1>{% block title %}</h1>
|
||||
{% block content %}
|
||||
{% endautoescape %}
|
||||
|
||||
This will be escaped: <a>
|
||||
This will not be escaped: <a>
|
||||
|
||||
Generally, you won't need to worry about auto-escaping very much. View
|
||||
developers and custom filter authors need to think about when their data
|
||||
shouldn't be escaped and mark it appropriately. They are in a better position
|
||||
to know when that should happen than the template author, so it is their
|
||||
responsibility. By default, all output is escaped unless the template
|
||||
processor is explicitly told otherwise.
|
||||
# child.html
|
||||
|
||||
You should also note that if you are trying to write a template that might be
|
||||
used in situations where automatic escaping is enabled or disabled and you
|
||||
don't know which (such as when your template is included in other templates),
|
||||
you can safely write as if you were in an ``{% autoescape off %}`` situation.
|
||||
Scatter ``escape`` filters around for any variables that need escaping. When
|
||||
auto-escaping is on, these extra filters won't change the output -- any
|
||||
variables that use the ``escape`` filter do not have further automatic
|
||||
escaping applied to them.
|
||||
{% extends "base.html" %}
|
||||
{% block title %}This & that{% endblock %}
|
||||
{% block content %}<b>Hello!</b>{% endblock %}
|
||||
|
||||
Because auto-escaping is turned off in the base template, it will also be
|
||||
turned off in the child template, resulting in the following rendered HTML::
|
||||
|
||||
<h1>This & that</h1>
|
||||
<b>Hello!</b>
|
||||
|
||||
Notes
|
||||
-----
|
||||
|
||||
Generally, template authors don't need to worry about auto-escaping very much.
|
||||
Developers on the Python side (people writing views and custom filters) need to
|
||||
think about the cases in which data shouldn't be escaped, and mark data
|
||||
appropriately, so things Just Work in the template.
|
||||
|
||||
If you're creating a template that might be used in situations where you're
|
||||
not sure whether auto-escaping is enabled, then add an ``escape`` filter to any
|
||||
variable that needs escaping. When auto-escaping is on, there's no danger of
|
||||
the ``escape`` filter *double-escaping* data -- the ``escape`` filter does not
|
||||
affect auto-escaped variables.
|
||||
|
||||
String literals and automatic escaping
|
||||
--------------------------------------
|
||||
|
||||
Sometimes you will pass a string literal as an argument to a filter. For
|
||||
example::
|
||||
As we mentioned earlier, filter arguments can be strings::
|
||||
|
||||
{{ data|default:"This is a string literal." }}
|
||||
|
||||
All string literals are inserted **without** any automatic escaping into the
|
||||
template, if they are used (it's as if they were all passed through the
|
||||
``safe`` filter). The reasoning behind this is that the template author is in
|
||||
control of what goes into the string literal, so they can make sure the text
|
||||
is correctly escaped when the template is written.
|
||||
template -- they act as if they were all passed through the ``safe`` filter.
|
||||
The reasoning behind this is that the template author is in control of what
|
||||
goes into the string literal, so they can make sure the text is correctly
|
||||
escaped when the template is written.
|
||||
|
||||
This means you would write ::
|
||||
|
||||
@@ -426,7 +482,7 @@ This means you would write ::
|
||||
{{ data|default:"3 > 2" }} <-- Bad! Don't do this.
|
||||
|
||||
This doesn't affect what happens to data coming from the variable itself.
|
||||
The variable's contents are still automatically escaped, if necessary, since
|
||||
The variable's contents are still automatically escaped, if necessary, because
|
||||
they're beyond the control of the template author.
|
||||
|
||||
Using the built-in reference
|
||||
@@ -1230,11 +1286,11 @@ once, after all other filters).
|
||||
|
||||
Escapes a string's HTML. Specifically, it makes these replacements:
|
||||
|
||||
* ``"&"`` to ``"&"``
|
||||
* ``<`` to ``"<"``
|
||||
* ``>`` to ``">"``
|
||||
* ``'"'`` (double quote) to ``'"'``
|
||||
* ``"'"`` (single quote) to ``'''``
|
||||
* ``<`` is converted to ``<``
|
||||
* ``>`` is converted to ``>``
|
||||
* ``'`` (single quote) is converted to ``'``
|
||||
* ``"`` (double quote) is converted to ``"``
|
||||
* ``&`` is converted to ``&``
|
||||
|
||||
The escaping is only applied when the string is output, so it does not matter
|
||||
where in a chained sequence of filters you put ``escape``: it will always be
|
||||
@@ -1277,7 +1333,7 @@ value Template Output
|
||||
======== ======================= ======
|
||||
|
||||
If used with a numeric integer argument, ``floatformat`` rounds a number to
|
||||
that many decimal places. For example:
|
||||
that many decimal places. For example:
|
||||
|
||||
======== ========================= ======
|
||||
value Template Output
|
||||
|
||||
@@ -727,134 +727,144 @@ Filters and auto-escaping
|
||||
|
||||
**New in Django development version**
|
||||
|
||||
When you are writing a custom filter, you need to give some thought to how
|
||||
this filter will interact with Django's auto-escaping behaviour. Firstly, you
|
||||
should realise that there are three types of strings that can be passed around
|
||||
inside the template code:
|
||||
When writing a custom filter, give some thought to how the filter will interact
|
||||
with Django's auto-escaping behavior. Note that three types of strings can be
|
||||
passed around inside the template code:
|
||||
|
||||
* raw strings are the native Python ``str`` or ``unicode`` types. On
|
||||
output, they are escaped if auto-escaping is in effect and presented
|
||||
unchanged, otherwise.
|
||||
* **Raw strings** are the native Python ``str`` or ``unicode`` types. On
|
||||
output, they're escaped if auto-escaping is in effect and presented
|
||||
unchanged, otherwise.
|
||||
|
||||
* "safe" strings are strings that are safe from further escaping at output
|
||||
time. Any necessary escaping has already been done. They are commonly used
|
||||
for output that contains raw HTML that is intended to be intrepreted on the
|
||||
client side.
|
||||
* **Safe strings** are strings that have been marked safe from further
|
||||
escaping at output time. Any necessary escaping has already been done.
|
||||
They're commonly used for output that contains raw HTML that is intended
|
||||
to be interpreted as-is on the client side.
|
||||
|
||||
Internally, these strings are of type ``SafeString`` or ``SafeUnicode``,
|
||||
although they share a common base class in ``SafeData``, so you can test
|
||||
for them using code like::
|
||||
Internally, these strings are of type ``SafeString`` or ``SafeUnicode``.
|
||||
They share a common base class of ``SafeData``, so you can test
|
||||
for them using code like::
|
||||
|
||||
if isinstance(value, SafeData):
|
||||
# Do something with the "safe" string.
|
||||
if isinstance(value, SafeData):
|
||||
# Do something with the "safe" string.
|
||||
|
||||
* strings which are marked as "needing escaping" are *always* escaped on
|
||||
output, regardless of whether they are in an ``autoescape`` block or not.
|
||||
These strings are only escaped once, however, even if auto-escaping
|
||||
applies. This type of string is internally represented by the types
|
||||
``EscapeString`` and ``EscapeUnicode``. You will not normally need to worry
|
||||
about these; they exist for the implementation of the ``escape`` filter.
|
||||
* **Strings marked as "needing escaping"** are *always* escaped on
|
||||
output, regardless of whether they are in an ``autoescape`` block or not.
|
||||
These strings are only escaped once, however, even if auto-escaping
|
||||
applies.
|
||||
|
||||
When you are writing a filter, your code will typically fall into one of two
|
||||
situations:
|
||||
Internally, these strings are of type ``EscapeString`` or
|
||||
``EscapeUnicode``. Generally you don't have to worry about these; they
|
||||
exist for the implementation of the ``escape`` filter.
|
||||
|
||||
1. Your filter does not introduce any HTML-unsafe characters (``<``, ``>``,
|
||||
``'``, ``"`` or ``&``) into the result that were not already present. In
|
||||
this case, you can let Django take care of all the auto-escaping handling
|
||||
for you. All you need to do is put the ``is_safe`` attribute on your
|
||||
filter function and set it to ``True``. This attribute tells Django that
|
||||
is a "safe" string is passed into your filter, the result will still be
|
||||
"safe" and if a non-safe string is passed in, Django will automatically
|
||||
escape it, if necessary. The reason ``is_safe`` is necessary is because
|
||||
there are plenty of normal string operations that will turn a ``SafeData``
|
||||
object back into a normal ``str`` or ``unicode`` object and, rather than
|
||||
try to catch them all, which would be very difficult, Django repairs the
|
||||
damage after the filter has completed.
|
||||
Template filter code falls into one of two situations:
|
||||
|
||||
For example, suppose you have a filter that adds the string ``xx`` to the
|
||||
end of any input. Since this introduces no dangerous HTML characters into
|
||||
the result (aside from any that were already present), you should mark
|
||||
your filter with ``is_safe``::
|
||||
1. Your filter does not introduce any HTML-unsafe characters (``<``, ``>``,
|
||||
``'``, ``"`` or ``&``) into the result that were not already present. In
|
||||
this case, you can let Django take care of all the auto-escaping
|
||||
handling for you. All you need to do is put the ``is_safe`` attribute on
|
||||
your filter function and set it to ``True``, like so::
|
||||
|
||||
@register.filter
|
||||
def myfilter(value):
|
||||
return value
|
||||
myfilter.is_safe = True
|
||||
|
||||
This attribute tells Django that if a "safe" string is passed into your
|
||||
filter, the result will still be "safe" and if a non-safe string is
|
||||
passed in, Django will automatically escape it, if necessary.
|
||||
|
||||
You can think of this as meaning "this filter is safe -- it doesn't
|
||||
introduce any possibility of unsafe HTML."
|
||||
|
||||
The reason ``is_safe`` is necessary is because there are plenty of
|
||||
normal string operations that will turn a ``SafeData`` object back into
|
||||
a normal ``str`` or ``unicode`` object and, rather than try to catch
|
||||
them all, which would be very difficult, Django repairs the damage after
|
||||
the filter has completed.
|
||||
|
||||
For example, suppose you have a filter that adds the string ``xx`` to the
|
||||
end of any input. Since this introduces no dangerous HTML characters to
|
||||
the result (aside from any that were already present), you should mark
|
||||
your filter with ``is_safe``::
|
||||
|
||||
@register.filter
|
||||
def add_xx(value):
|
||||
return '%sxx' % value
|
||||
add_xx.is_safe = True
|
||||
|
||||
When this filter is used in a template where auto-escaping is enabled,
|
||||
Django will escape the output whenever the input is not already marked as
|
||||
"safe".
|
||||
When this filter is used in a template where auto-escaping is enabled,
|
||||
Django will escape the output whenever the input is not already marked as
|
||||
"safe".
|
||||
|
||||
By default, ``is_safe`` defaults to ``False`` and you can omit it from
|
||||
any filters where it isn't required.
|
||||
By default, ``is_safe`` defaults to ``False``, and you can omit it from
|
||||
any filters where it isn't required.
|
||||
|
||||
Be careful when deciding if your filter really does leave safe strings
|
||||
as safe. Sometimes if you are *removing* characters, you can
|
||||
inadvertently leave unbalanced HTML tags or entities in the result.
|
||||
For example, removing a ``>`` from the input might turn ``<a>`` into
|
||||
``<a``, which would need to be escaped on output to avoid causing
|
||||
problems. Similarly, removing a semicolon (``;``) can turn ``&``
|
||||
into ``&``, which is no longer a valid entity and thus needs
|
||||
further escaping. Most cases won't be nearly this tricky, but keep an
|
||||
eye out for any problems like that when reviewing your code.
|
||||
Be careful when deciding if your filter really does leave safe strings
|
||||
as safe. If you're *removing* characters, you might inadvertently leave
|
||||
unbalanced HTML tags or entities in the result. For example, removing a
|
||||
``>`` from the input might turn ``<a>`` into ``<a``, which would need to
|
||||
be escaped on output to avoid causing problems. Similarly, removing a
|
||||
semicolon (``;``) can turn ``&`` into ``&``, which is no longer a
|
||||
valid entity and thus needs further escaping. Most cases won't be nearly
|
||||
this tricky, but keep an eye out for any problems like that when
|
||||
reviewing your code.
|
||||
|
||||
2. Alternatively, your filter code can manually take care of any necessary
|
||||
escaping. This is usually necessary when you are introducing new HTML
|
||||
markup into the result. You want to mark the output as safe from further
|
||||
escaping so that your HTML markup isn't escaped further, so you'll need to
|
||||
handle the input yourself.
|
||||
2. Alternatively, your filter code can manually take care of any necessary
|
||||
escaping. This is necessary when you're introducing new HTML markup into
|
||||
the result. You want to mark the output as safe from further
|
||||
escaping so that your HTML markup isn't escaped further, so you'll need
|
||||
to handle the input yourself.
|
||||
|
||||
To mark the output as a safe string, use
|
||||
``django.utils.safestring.mark_safe()``.
|
||||
To mark the output as a safe string, use ``django.utils.safestring.mark_safe()``.
|
||||
|
||||
Be careful, though. You need to do more than just mark the output as
|
||||
safe. You need to ensure it really *is* safe and what you do will often
|
||||
depend upon whether or not auto-escaping is in effect. The idea is to
|
||||
write filters than can operate in templates where auto-escaping is either
|
||||
on or off in order to make things easier for your template authors.
|
||||
Be careful, though. You need to do more than just mark the output as
|
||||
safe. You need to ensure it really *is* safe, and what you do depends on
|
||||
whether auto-escaping is in effect. The idea is to write filters than
|
||||
can operate in templates where auto-escaping is either on or off in
|
||||
order to make things easier for your template authors.
|
||||
|
||||
In order for you filter to know the current auto-escaping state, set the
|
||||
``needs_autoescape`` attribute to ``True`` on your function (if you don't
|
||||
specify this attribute, it defaults to ``False``). This attribute tells
|
||||
Django that your filter function wants to be passed an extra keyword
|
||||
argument, called ``autoescape`` that is ``True`` is auto-escaping is in
|
||||
effect and ``False`` otherwise.
|
||||
In order for you filter to know the current auto-escaping state, set the
|
||||
``needs_autoescape`` attribute to ``True`` on your function. (If you
|
||||
don't specify this attribute, it defaults to ``False``). This attribute
|
||||
tells Django that your filter function wants to be passed an extra
|
||||
keyword argument, called ``autoescape``, that is ``True`` is
|
||||
auto-escaping is in effect and ``False`` otherwise.
|
||||
|
||||
An example might make this clearer. Let's write a filter that emphasizes
|
||||
the first character of a string::
|
||||
For example, let's write a filter that emphasizes the first character of
|
||||
a string::
|
||||
|
||||
from django.utils.html import conditional_escape
|
||||
from django.utils.safestring import mark_safe
|
||||
from django.utils.html import conditional_escape
|
||||
from django.utils.safestring import mark_safe
|
||||
|
||||
def initial_letter_filter(text, autoescape=None):
|
||||
first, other = text[0] ,text[1:]
|
||||
if autoescape:
|
||||
esc = conditional_escape
|
||||
else:
|
||||
esc = lambda x: x
|
||||
result = '<strong>%s</strong>%s' % (esc(first), esc(other))
|
||||
return mark_safe(result)
|
||||
initial_letter_filter.needs_autoescape = True
|
||||
def initial_letter_filter(text, autoescape=None):
|
||||
first, other = text[0], text[1:]
|
||||
if autoescape:
|
||||
esc = conditional_escape
|
||||
else:
|
||||
esc = lambda x: x
|
||||
result = '<strong>%s</strong>%s' % (esc(first), esc(other))
|
||||
return mark_safe(result)
|
||||
initial_letter_filter.needs_autoescape = True
|
||||
|
||||
The ``needs_autoescape`` attribute on the filter function and the
|
||||
``autoescape`` keyword argument mean that our function will know whether
|
||||
or not automatic escaping is in effect when the filter is called. We use
|
||||
``autoescape`` to decide whether the input data needs to be passed through
|
||||
``django.utils.html.conditional_escape`` or not (in the latter case, we
|
||||
just use the identity function as the "escape" function). The
|
||||
``conditional_escape()`` function is like ``escape()`` except it only
|
||||
escapes input that is **not** a ``SafeData`` instance. If a ``SafeData``
|
||||
instance is passed to ``conditional_escape()``, the data is returned
|
||||
unchanged.
|
||||
The ``needs_autoescape`` attribute on the filter function and the
|
||||
``autoescape`` keyword argument mean that our function will know whether
|
||||
automatic escaping is in effect when the filter is called. We use
|
||||
``autoescape`` to decide whether the input data needs to be passed through
|
||||
``django.utils.html.conditional_escape`` or not. (In the latter case, we
|
||||
just use the identity function as the "escape" function.) The
|
||||
``conditional_escape()`` function is like ``escape()`` except it only
|
||||
escapes input that is **not** a ``SafeData`` instance. If a ``SafeData``
|
||||
instance is passed to ``conditional_escape()``, the data is returned
|
||||
unchanged.
|
||||
|
||||
Finally, in the above example, we remember to mark the result as safe
|
||||
so that our HTML is inserted directly into the template without further
|
||||
escaping.
|
||||
Finally, in the above example, we remember to mark the result as safe
|
||||
so that our HTML is inserted directly into the template without further
|
||||
escaping.
|
||||
|
||||
There is no need to worry about the ``is_safe`` attribute in this case
|
||||
(although including it wouldn't hurt anything). Whenever you are manually
|
||||
handling the auto-escaping issues and returning a safe string, the
|
||||
``is_safe`` attribute won't change anything either way.
|
||||
There's no need to worry about the ``is_safe`` attribute in this case
|
||||
(although including it wouldn't hurt anything). Whenever you manually
|
||||
handle the auto-escaping issues and return a safe string, the
|
||||
``is_safe`` attribute won't change anything either way.
|
||||
|
||||
Writing custom template tags
|
||||
----------------------------
|
||||
@@ -981,7 +991,7 @@ Auto-escaping considerations
|
||||
|
||||
The output from template tags is **not** automatically run through the
|
||||
auto-escaping filters. However, there are still a couple of things you should
|
||||
keep in mind when writing a template tag:
|
||||
keep in mind when writing a template tag.
|
||||
|
||||
If the ``render()`` function of your template stores the result in a context
|
||||
variable (rather than returning the result in a string), it should take care
|
||||
@@ -991,18 +1001,17 @@ time, so content that should be safe from further escaping needs to be marked
|
||||
as such.
|
||||
|
||||
Also, if your template tag creates a new context for performing some
|
||||
sub-rendering, you should be careful to set the auto-escape attribute to the
|
||||
current context's value. The ``__init__`` method for the ``Context`` class
|
||||
takes a parameter called ``autoescape`` that you can use for this purpose. For
|
||||
example::
|
||||
sub-rendering, set the auto-escape attribute to the current context's value.
|
||||
The ``__init__`` method for the ``Context`` class takes a parameter called
|
||||
``autoescape`` that you can use for this purpose. For example::
|
||||
|
||||
def render(self, context):
|
||||
# ...
|
||||
new_context = Context({'var': obj}, autoescape=context.autoescape)
|
||||
# ... Do something with new_context ...
|
||||
|
||||
This is not a very common situation, but it is sometimes useful, particularly
|
||||
if you are rendering a template yourself. For example::
|
||||
This is not a very common situation, but it's useful if you're rendering a
|
||||
template yourself. For example::
|
||||
|
||||
def render(self, context):
|
||||
t = template.load_template('small_fragment.html')
|
||||
@@ -1010,7 +1019,7 @@ if you are rendering a template yourself. For example::
|
||||
|
||||
If we had neglected to pass in the current ``context.autoescape`` value to our
|
||||
new ``Context`` in this example, the results would have *always* been
|
||||
automatically escaped, which may not be the desired behaviour if the template
|
||||
automatically escaped, which may not be the desired behavior if the template
|
||||
tag is used inside a ``{% autoescape off %}`` block.
|
||||
|
||||
Registering the tag
|
||||
|
||||
@@ -48,7 +48,7 @@ Recall from Tutorial 1 that you start the development server like so::
|
||||
Now, open a Web browser and go to "/admin/" on your local domain -- e.g.,
|
||||
http://127.0.0.1:8000/admin/. You should see the admin's login screen:
|
||||
|
||||
.. image:: http://media.djangoproject.com/img/doc/tutorial/admin01.png
|
||||
.. image:: http://media.djangoproject.com/img/doc/tutorial-trunk/admin01.png
|
||||
:alt: Django admin login screen
|
||||
|
||||
Enter the admin site
|
||||
@@ -57,9 +57,9 @@ Enter the admin site
|
||||
Now, try logging in. (You created a superuser account in the first part of this
|
||||
tutorial, remember?) You should see the Django admin index page:
|
||||
|
||||
.. image:: http://media.djangoproject.com/img/doc/tutorial/admin02t.png
|
||||
.. image:: http://media.djangoproject.com/img/doc/tutorial-trunk/admin02t.png
|
||||
:alt: Django admin index page
|
||||
:target: http://media.djangoproject.com/img/doc/tutorial/admin02.png
|
||||
:target: http://media.djangoproject.com/img/doc/tutorial-trunk/admin02.png
|
||||
|
||||
You should see a few other types of editable content, including groups, users
|
||||
and sites. These are core features Django ships with by default.
|
||||
@@ -95,23 +95,23 @@ Explore the free admin functionality
|
||||
Now that ``Poll`` has the inner ``Admin`` class, Django knows that it should be
|
||||
displayed on the admin index page:
|
||||
|
||||
.. image:: http://media.djangoproject.com/img/doc/tutorial/admin03t.png
|
||||
.. image:: http://media.djangoproject.com/img/doc/tutorial-trunk/admin03t.png
|
||||
:alt: Django admin index page, now with polls displayed
|
||||
:target: http://media.djangoproject.com/img/doc/tutorial/admin03.png
|
||||
:target: http://media.djangoproject.com/img/doc/tutorial-trunk/admin03.png
|
||||
|
||||
Click "Polls." Now you're at the "change list" page for polls. This page
|
||||
displays all the polls in the database and lets you choose one to change it.
|
||||
There's the "What's up?" poll we created in the first tutorial:
|
||||
|
||||
.. image:: http://media.djangoproject.com/img/doc/tutorial/admin04t.png
|
||||
.. image:: http://media.djangoproject.com/img/doc/tutorial-trunk/admin04t.png
|
||||
:alt: Polls change list page
|
||||
:target: http://media.djangoproject.com/img/doc/tutorial/admin04.png
|
||||
:target: http://media.djangoproject.com/img/doc/tutorial-trunk/admin04.png
|
||||
|
||||
Click the "What's up?" poll to edit it:
|
||||
|
||||
.. image:: http://media.djangoproject.com/img/doc/tutorial/admin05t.png
|
||||
.. image:: http://media.djangoproject.com/img/doc/tutorial-trunk/admin05t.png
|
||||
:alt: Editing form for poll object
|
||||
:target: http://media.djangoproject.com/img/doc/tutorial/admin05.png
|
||||
:target: http://media.djangoproject.com/img/doc/tutorial-trunk/admin05.png
|
||||
|
||||
Things to note here:
|
||||
|
||||
@@ -138,9 +138,9 @@ click "Save and continue editing." Then click "History" in the upper right.
|
||||
You'll see a page listing all changes made to this object via the Django admin,
|
||||
with the timestamp and username of the person who made the change:
|
||||
|
||||
.. image:: http://media.djangoproject.com/img/doc/tutorial/admin06t.png
|
||||
.. image:: http://media.djangoproject.com/img/doc/tutorial-trunk/admin06t.png
|
||||
:alt: History page for poll object
|
||||
:target: http://media.djangoproject.com/img/doc/tutorial/admin06.png
|
||||
:target: http://media.djangoproject.com/img/doc/tutorial-trunk/admin06.png
|
||||
|
||||
Customize the admin form
|
||||
========================
|
||||
@@ -157,7 +157,7 @@ Let's customize this a bit. We can reorder the fields by explicitly adding a
|
||||
|
||||
That made the "Publication date" show up first instead of second:
|
||||
|
||||
.. image:: http://media.djangoproject.com/img/doc/tutorial/admin07.png
|
||||
.. image:: http://media.djangoproject.com/img/doc/tutorial-trunk/admin07.png
|
||||
:alt: Fields have been reordered
|
||||
|
||||
This isn't impressive with only two fields, but for admin forms with dozens
|
||||
@@ -175,9 +175,9 @@ up into fieldsets::
|
||||
The first element of each tuple in ``fields`` is the title of the fieldset.
|
||||
Here's what our form looks like now:
|
||||
|
||||
.. image:: http://media.djangoproject.com/img/doc/tutorial/admin08t.png
|
||||
.. image:: http://media.djangoproject.com/img/doc/tutorial-trunk/admin08t.png
|
||||
:alt: Form has fieldsets now
|
||||
:target: http://media.djangoproject.com/img/doc/tutorial/admin08.png
|
||||
:target: http://media.djangoproject.com/img/doc/tutorial-trunk/admin08.png
|
||||
|
||||
You can assign arbitrary HTML classes to each fieldset. Django provides a
|
||||
``"collapse"`` class that displays a particular fieldset initially collapsed.
|
||||
@@ -190,7 +190,7 @@ aren't commonly used::
|
||||
('Date information', {'fields': ('pub_date',), 'classes': 'collapse'}),
|
||||
)
|
||||
|
||||
.. image:: http://media.djangoproject.com/img/doc/tutorial/admin09.png
|
||||
.. image:: http://media.djangoproject.com/img/doc/tutorial-trunk/admin09.png
|
||||
:alt: Fieldset is initially collapsed
|
||||
|
||||
Adding related objects
|
||||
@@ -213,7 +213,7 @@ that would look like::
|
||||
Now "Choices" is an available option in the Django admin. The "Add choice" form
|
||||
looks like this:
|
||||
|
||||
.. image:: http://media.djangoproject.com/img/doc/tutorial/admin10.png
|
||||
.. image:: http://media.djangoproject.com/img/doc/tutorial-trunk/admin10.png
|
||||
:alt: Choice admin page
|
||||
|
||||
In that form, the "Poll" field is a select box containing every poll in the
|
||||
@@ -250,9 +250,9 @@ deletion of that existing Choice object."
|
||||
|
||||
Load the "Add poll" page to see how that looks:
|
||||
|
||||
.. image:: http://media.djangoproject.com/img/doc/tutorial/admin11t.png
|
||||
.. image:: http://media.djangoproject.com/img/doc/tutorial-trunk/admin11t.png
|
||||
:alt: Add poll page now has choices on it
|
||||
:target: http://media.djangoproject.com/img/doc/tutorial/admin11.png
|
||||
:target: http://media.djangoproject.com/img/doc/tutorial-trunk/admin11.png
|
||||
|
||||
It works like this: There are three slots for related Choices -- as specified
|
||||
by ``num_in_admin`` -- but each time you come back to the "Change" page for an
|
||||
@@ -270,7 +270,7 @@ alternate way of displaying inline related objects::
|
||||
With that ``edit_inline=models.TABULAR`` (instead of ``models.STACKED``), the
|
||||
related objects are displayed in a more compact, table-based format:
|
||||
|
||||
.. image:: http://media.djangoproject.com/img/doc/tutorial/admin12.png
|
||||
.. image:: http://media.djangoproject.com/img/doc/tutorial-trunk/admin12.png
|
||||
:alt: Add poll page now has more compact choices
|
||||
|
||||
Customize the admin change list
|
||||
@@ -281,9 +281,9 @@ Now that the Poll admin page is looking good, let's make some tweaks to the
|
||||
|
||||
Here's what it looks like at this point:
|
||||
|
||||
.. image:: http://media.djangoproject.com/img/doc/tutorial/admin04t.png
|
||||
.. image:: http://media.djangoproject.com/img/doc/tutorial-trunk/admin04t.png
|
||||
:alt: Polls change list page
|
||||
:target: http://media.djangoproject.com/img/doc/tutorial/admin04.png
|
||||
:target: http://media.djangoproject.com/img/doc/tutorial-trunk/admin04.png
|
||||
|
||||
By default, Django displays the ``str()`` of each object. But sometimes it'd
|
||||
be more helpful if we could display individual fields. To do that, use the
|
||||
@@ -303,9 +303,9 @@ method from Tutorial 1::
|
||||
|
||||
Now the poll change list page looks like this:
|
||||
|
||||
.. image:: http://media.djangoproject.com/img/doc/tutorial/admin13t.png
|
||||
.. image:: http://media.djangoproject.com/img/doc/tutorial-trunk/admin13t.png
|
||||
:alt: Polls change list page, updated
|
||||
:target: http://media.djangoproject.com/img/doc/tutorial/admin13.png
|
||||
:target: http://media.djangoproject.com/img/doc/tutorial-trunk/admin13.png
|
||||
|
||||
You can click on the column headers to sort by those values -- except in the
|
||||
case of the ``was_published_today`` header, because sorting by the output of
|
||||
@@ -327,9 +327,9 @@ following line to ``Poll.Admin``::
|
||||
That adds a "Filter" sidebar that lets people filter the change list by the
|
||||
``pub_date`` field:
|
||||
|
||||
.. image:: http://media.djangoproject.com/img/doc/tutorial/admin14t.png
|
||||
.. image:: http://media.djangoproject.com/img/doc/tutorial-trunk/admin14t.png
|
||||
:alt: Polls change list page, updated
|
||||
:target: http://media.djangoproject.com/img/doc/tutorial/admin14.png
|
||||
:target: http://media.djangoproject.com/img/doc/tutorial-trunk/admin14.png
|
||||
|
||||
The type of filter displayed depends on the type of field you're filtering on.
|
||||
Because ``pub_date`` is a DateTimeField, Django knows to give the default
|
||||
|
||||
Reference in New Issue
Block a user