mirror of
https://github.com/django/django.git
synced 2025-10-31 09:41:08 +00:00
gis: Made necessary modifications for unicode, manage refactor, backend refactor and merged 5584-6000 via svnmerge from [repos:django/trunk trunk].
git-svn-id: http://code.djangoproject.com/svn/django/branches/gis@6018 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
@@ -138,6 +138,29 @@ Examples:
|
||||
|
||||
You can pass in either an integer or a string representation of an integer.
|
||||
|
||||
naturalday
|
||||
----------
|
||||
|
||||
**New in Django development version**
|
||||
|
||||
For dates that are the current day or within one day, return "today",
|
||||
"tomorrow" or "yesterday", as appropriate. Otherwise, format the date using
|
||||
the passed in format string.
|
||||
|
||||
**Argument:** Date formatting string as described in default tag now_.
|
||||
|
||||
.. _now: ../templates/#now
|
||||
|
||||
Examples (when 'today' is 17 Feb 2007):
|
||||
|
||||
* ``16 Feb 2007`` becomes ``yesterday``.
|
||||
* ``17 Feb 2007`` becomes ``today``.
|
||||
* ``18 Feb 2007`` becomes ``tomorrow``.
|
||||
* Any other day is formatted according to given argument or the
|
||||
`DATE_FORMAT`_ setting if no argument is given.
|
||||
|
||||
.. _DATE_FORMAT: ../settings/#date_format
|
||||
|
||||
flatpages
|
||||
=========
|
||||
|
||||
@@ -214,7 +237,7 @@ A framework for generating syndication feeds, in RSS and Atom, quite easily.
|
||||
|
||||
See the `syndication documentation`_.
|
||||
|
||||
.. _syndication documentation: ../syndication/
|
||||
.. _syndication documentation: ../syndication_feeds/
|
||||
|
||||
Other add-ons
|
||||
=============
|
||||
|
||||
@@ -82,9 +82,6 @@ that 90% of Django can be considered forwards-compatible at this point.
|
||||
That said, these APIs should *not* be considered stable, and are likely to
|
||||
change:
|
||||
|
||||
- `Forms and validation`_ will most likely be completely rewritten to
|
||||
deemphasize Manipulators in favor of validation-aware models.
|
||||
|
||||
- `Serialization`_ is under heavy development; changes are likely.
|
||||
|
||||
- The `authentication`_ framework is changing to be far more flexible, and
|
||||
@@ -114,7 +111,7 @@ change:
|
||||
.. _sending email: ../email/
|
||||
.. _sessions: ../sessions/
|
||||
.. _settings: ../settings/
|
||||
.. _syndication: ../syndication/
|
||||
.. _syndication: ../syndication_feeds/
|
||||
.. _template language: ../templates/
|
||||
.. _transactions: ../transactions/
|
||||
.. _url dispatch: ../url_dispatch/
|
||||
|
||||
@@ -99,7 +99,7 @@ custom methods:
|
||||
should prefer using ``is_authenticated()`` to this method.
|
||||
|
||||
* ``is_authenticated()`` -- Always returns ``True``. This is a way to
|
||||
tell if the user has been authenticated. This does not imply any
|
||||
tell if the user has been authenticated. This does not imply any
|
||||
permissions, and doesn't check if the user is active - it only indicates
|
||||
that the user has provided a valid username and password.
|
||||
|
||||
@@ -114,6 +114,18 @@ custom methods:
|
||||
string is the correct password for the user. (This takes care of the
|
||||
password hashing in making the comparison.)
|
||||
|
||||
* ``set_unusable_password()`` -- **New in Django development version.**
|
||||
Marks the user as having no password set. This isn't the same as having
|
||||
a blank string for a password. ``check_password()`` for this user will
|
||||
never return ``True``. Doesn't save the ``User`` object.
|
||||
|
||||
You may need this if authentication for your application takes place
|
||||
against an existing external source such as an LDAP directory.
|
||||
|
||||
* ``has_usable_password()`` -- **New in Django development version.**
|
||||
Returns ``False`` if ``set_unusable_password()`` has been called for this
|
||||
user.
|
||||
|
||||
* ``get_group_permissions()`` -- Returns a list of permission strings that
|
||||
the user has, through his/her groups.
|
||||
|
||||
@@ -126,7 +138,7 @@ custom methods:
|
||||
|
||||
* ``has_perms(perm_list)`` -- Returns ``True`` if the user has each of the
|
||||
specified permissions, where each perm is in the format
|
||||
``"package.codename"``. If the user is inactive, this method will
|
||||
``"package.codename"``. If the user is inactive, this method will
|
||||
always return ``False``.
|
||||
|
||||
* ``has_module_perms(package_name)`` -- Returns ``True`` if the user has
|
||||
@@ -152,9 +164,11 @@ Manager functions
|
||||
|
||||
The ``User`` model has a custom manager that has the following helper functions:
|
||||
|
||||
* ``create_user(username, email, password)`` -- Creates, saves and returns
|
||||
a ``User``. The ``username``, ``email`` and ``password`` are set as
|
||||
given, and the ``User`` gets ``is_active=True``.
|
||||
* ``create_user(username, email, password=None)`` -- Creates, saves and
|
||||
returns a ``User``. The ``username``, ``email`` and ``password`` are set
|
||||
as given, and the ``User`` gets ``is_active=True``.
|
||||
|
||||
If no password is provided, ``set_unusable_password()`` will be called.
|
||||
|
||||
See _`Creating users` for example usage.
|
||||
|
||||
@@ -220,7 +234,7 @@ the setting and checking of these values behind the scenes.
|
||||
|
||||
Previous Django versions, such as 0.90, used simple MD5 hashes without password
|
||||
salts. For backwards compatibility, those are still supported; they'll be
|
||||
converted automatically to the new style the first time ``check_password()``
|
||||
converted automatically to the new style the first time ``User.check_password()``
|
||||
works correctly for a given user.
|
||||
|
||||
Anonymous users
|
||||
@@ -422,7 +436,10 @@ template context variables:
|
||||
* ``next``: The URL to redirect to after successful login. This may contain
|
||||
a query string, too.
|
||||
* ``site_name``: The name of the current ``Site``, according to the
|
||||
``SITE_ID`` setting. See the `site framework docs`_.
|
||||
``SITE_ID`` setting. If you're using the Django development version and
|
||||
you don't have the site framework installed, this will be set to the
|
||||
value of ``request.META['SERVER_NAME']``. For more on sites, see the
|
||||
`site framework docs`_.
|
||||
|
||||
If you'd prefer not to call the template ``registration/login.html``, you can
|
||||
pass the ``template_name`` parameter via the extra arguments to the view in
|
||||
@@ -661,8 +678,6 @@ Example in Python 2.4 syntax::
|
||||
The permission_required decorator
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
**New in Django development version**
|
||||
|
||||
It's a relatively common task to check whether a user has a particular
|
||||
permission. For that reason, Django provides a shortcut for that case: the
|
||||
``permission_required()`` decorator. Using this decorator, the earlier example
|
||||
|
||||
@@ -543,7 +543,7 @@ Order of MIDDLEWARE_CLASSES
|
||||
If you use ``CacheMiddleware``, it's important to put it in the right place
|
||||
within the ``MIDDLEWARE_CLASSES`` setting, because the cache middleware needs
|
||||
to know which headers by which to vary the cache storage. Middleware always
|
||||
adds something the ``Vary`` response header when it can.
|
||||
adds something to the ``Vary`` response header when it can.
|
||||
|
||||
Put the ``CacheMiddleware`` after any middlewares that might add something to
|
||||
the ``Vary`` header. The following middlewares do so:
|
||||
|
||||
@@ -67,6 +67,13 @@ particular:
|
||||
likely to get lost. If a particular ticket is controversial, please move
|
||||
discussion to `django-developers`_.
|
||||
|
||||
* **Don't** post to django-developers just to announce that you have filed
|
||||
a bug report. All the tickets are mailed to another list
|
||||
(`django-updates`_), which is tracked by developers and triagers, so we
|
||||
see them as they are filed.
|
||||
|
||||
.. _django-updates: http://groups.google.com/group/django-updates
|
||||
|
||||
Reporting security issues
|
||||
=========================
|
||||
|
||||
@@ -279,6 +286,22 @@ Please follow these coding standards when writing code for inclusion in Django:
|
||||
* Mark all strings for internationalization; see the `i18n documentation`_
|
||||
for details.
|
||||
|
||||
* In docstrings, use "action words" such as::
|
||||
|
||||
def foo():
|
||||
"""
|
||||
Calculates something and returns the result.
|
||||
"""
|
||||
pass
|
||||
|
||||
Here's an example of what not to do::
|
||||
|
||||
def foo():
|
||||
"""
|
||||
Calculate something and return the result.
|
||||
"""
|
||||
pass
|
||||
|
||||
* Please don't put your name in the code you contribute. Our policy is to
|
||||
keep contributors' names in the ``AUTHORS`` file distributed with Django
|
||||
-- not scattered throughout the codebase itself. Feel free to include a
|
||||
@@ -324,14 +347,14 @@ Model style
|
||||
Do this::
|
||||
|
||||
class Person(models.Model):
|
||||
first_name = models.CharField(maxlength=20)
|
||||
last_name = models.CharField(maxlength=40)
|
||||
first_name = models.CharField(max_length=20)
|
||||
last_name = models.CharField(max_length=40)
|
||||
|
||||
Don't do this::
|
||||
|
||||
class Person(models.Model):
|
||||
FirstName = models.CharField(maxlength=20)
|
||||
Last_Name = models.CharField(maxlength=40)
|
||||
FirstName = models.CharField(max_length=20)
|
||||
Last_Name = models.CharField(max_length=40)
|
||||
|
||||
* The ``class Meta`` should appear *after* the fields are defined, with
|
||||
a single blank line separating the fields and the class definition.
|
||||
@@ -339,8 +362,8 @@ Model style
|
||||
Do this::
|
||||
|
||||
class Person(models.Model):
|
||||
first_name = models.CharField(maxlength=20)
|
||||
last_name = models.CharField(maxlength=40)
|
||||
first_name = models.CharField(max_length=20)
|
||||
last_name = models.CharField(max_length=40)
|
||||
|
||||
class Meta:
|
||||
verbose_name_plural = 'people'
|
||||
@@ -348,8 +371,8 @@ Model style
|
||||
Don't do this::
|
||||
|
||||
class Person(models.Model):
|
||||
first_name = models.CharField(maxlength=20)
|
||||
last_name = models.CharField(maxlength=40)
|
||||
first_name = models.CharField(max_length=20)
|
||||
last_name = models.CharField(max_length=40)
|
||||
class Meta:
|
||||
verbose_name_plural = 'people'
|
||||
|
||||
@@ -359,8 +382,8 @@ Model style
|
||||
class Meta:
|
||||
verbose_name_plural = 'people'
|
||||
|
||||
first_name = models.CharField(maxlength=20)
|
||||
last_name = models.CharField(maxlength=40)
|
||||
first_name = models.CharField(max_length=20)
|
||||
last_name = models.CharField(max_length=40)
|
||||
|
||||
* The order of model inner classes and standard methods should be as
|
||||
follows (noting that these are not all required):
|
||||
@@ -368,6 +391,7 @@ Model style
|
||||
* All database fields
|
||||
* ``class Meta``
|
||||
* ``class Admin``
|
||||
* ``def __unicode__()``
|
||||
* ``def __str__()``
|
||||
* ``def save()``
|
||||
* ``def get_absolute_url()``
|
||||
@@ -393,11 +417,11 @@ Guidelines for ReST files
|
||||
|
||||
These guidelines regulate the format of our ReST documentation:
|
||||
|
||||
* In section titles, capitalize only initial words and proper nouns.
|
||||
* In section titles, capitalize only initial words and proper nouns.
|
||||
|
||||
* Wrap the documentation at 80 characters wide, unless a code example
|
||||
is significantly less readable when split over two lines, or for another
|
||||
good reason.
|
||||
* Wrap the documentation at 80 characters wide, unless a code example
|
||||
is significantly less readable when split over two lines, or for another
|
||||
good reason.
|
||||
|
||||
Commonly used terms
|
||||
-------------------
|
||||
@@ -405,41 +429,41 @@ Commonly used terms
|
||||
Here are some style guidelines on commonly used terms throughout the
|
||||
documentation:
|
||||
|
||||
* **Django** -- when referring to the framework, capitalize Django. It is
|
||||
lowercase only in Python code and in the djangoproject.com logo.
|
||||
* **Django** -- when referring to the framework, capitalize Django. It is
|
||||
lowercase only in Python code and in the djangoproject.com logo.
|
||||
|
||||
* **e-mail** -- it has a hyphen.
|
||||
* **e-mail** -- it has a hyphen.
|
||||
|
||||
* **MySQL**
|
||||
* **MySQL**
|
||||
|
||||
* **PostgreSQL**
|
||||
* **PostgreSQL**
|
||||
|
||||
* **Python** -- when referring to the language, capitalize Python.
|
||||
* **Python** -- when referring to the language, capitalize Python.
|
||||
|
||||
* **realize**, **customize**, **initialize**, etc. -- use the American
|
||||
"ize" suffix, not "ise."
|
||||
* **realize**, **customize**, **initialize**, etc. -- use the American
|
||||
"ize" suffix, not "ise."
|
||||
|
||||
* **SQLite**
|
||||
* **SQLite**
|
||||
|
||||
* **subclass** -- it's a single word without a hyphen, both as a verb
|
||||
("subclass that model") and as a noun ("create a subclass").
|
||||
* **subclass** -- it's a single word without a hyphen, both as a verb
|
||||
("subclass that model") and as a noun ("create a subclass").
|
||||
|
||||
* **Web**, **World Wide Web**, **the Web** -- note Web is always
|
||||
capitalized when referring to the World Wide Web.
|
||||
* **Web**, **World Wide Web**, **the Web** -- note Web is always
|
||||
capitalized when referring to the World Wide Web.
|
||||
|
||||
* **Web site** -- use two words, with Web capitalized.
|
||||
|
||||
Django-specific terminology
|
||||
---------------------------
|
||||
|
||||
* **model** -- it's not capitalized.
|
||||
* **model** -- it's not capitalized.
|
||||
|
||||
* **template** -- it's not capitalized.
|
||||
* **template** -- it's not capitalized.
|
||||
|
||||
* **URLconf** -- use three capitalized letters, with no space before
|
||||
"conf."
|
||||
* **URLconf** -- use three capitalized letters, with no space before
|
||||
"conf."
|
||||
|
||||
* **view** -- it's not capitalized.
|
||||
* **view** -- it's not capitalized.
|
||||
|
||||
Committing code
|
||||
===============
|
||||
@@ -528,11 +552,9 @@ 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 -- the ``DATABASE_NAME`` (required, but will be ignored),
|
||||
``DATABASE_ENGINE``, ``DATABASE_USER`` and ``DATABASE_PASSWORD`` settings. You
|
||||
will also need a ``ROOT_URLCONF`` setting (its value is ignored; it just needs
|
||||
to be present) and a ``SITE_ID`` setting (any integer value will do) in order
|
||||
for all the tests to pass.
|
||||
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.
|
||||
|
||||
The unit tests will not touch your existing databases; they create a new
|
||||
database, called ``django_test_db``, which is deleted when the tests are
|
||||
|
||||
@@ -41,10 +41,10 @@ CsrfMiddleware does two things:
|
||||
This ensures that only forms that have originated from your web site
|
||||
can be used to POST data back.
|
||||
|
||||
It deliberately only targets HTTP POST requests (and the corresponding
|
||||
POST forms). GET requests ought never to have side effects (if you are
|
||||
using HTTP GET and POST correctly), and so a CSRF attack with a GET
|
||||
request will always be harmless.
|
||||
It deliberately only targets HTTP POST requests (and the corresponding POST
|
||||
forms). GET requests ought never to have any potentially dangerous side
|
||||
effects (see `9.1.1 Safe Methods, HTTP 1.1, RFC 2616`_), and so a
|
||||
CSRF attack with a GET request ought to be harmless.
|
||||
|
||||
POST requests that are not accompanied by a session cookie are not protected,
|
||||
but they do not need to be protected, since the 'attacking' web site
|
||||
@@ -54,6 +54,8 @@ The Content-Type is checked before modifying the response, and only
|
||||
pages that are served as 'text/html' or 'application/xml+xhtml'
|
||||
are modified.
|
||||
|
||||
.. _9.1.1 Safe Methods, HTTP 1.1, RFC 2616: http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html
|
||||
|
||||
Limitations
|
||||
===========
|
||||
|
||||
|
||||
@@ -124,7 +124,7 @@ Several other MySQLdb connection options may be useful, such as ``ssl``,
|
||||
``use_unicode``, ``init_command``, and ``sql_mode``. Consult the
|
||||
`MySQLdb documentation`_ for more details.
|
||||
|
||||
.. _settings documentation: http://www.djangoproject.com/documentation/settings/#database-engine
|
||||
.. _settings documentation: ../settings/#database-engine
|
||||
.. _MySQL option file: http://dev.mysql.com/doc/refman/5.0/en/option-files.html
|
||||
.. _MySQLdb documentation: http://mysql-python.sourceforge.net/
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@ How to use Databrowse
|
||||
2. Register a number of models with the Databrowse site::
|
||||
|
||||
from django.contrib import databrowse
|
||||
from myapp.models import SomeModel, SomeOtherModel
|
||||
|
||||
databrowse.site.register(SomeModel)
|
||||
databrowse.site.register(SomeOtherModel)
|
||||
|
||||
113
docs/db-api.txt
113
docs/db-api.txt
@@ -12,27 +12,27 @@ Throughout this reference, we'll refer to the following models, which comprise
|
||||
a weblog application::
|
||||
|
||||
class Blog(models.Model):
|
||||
name = models.CharField(maxlength=100)
|
||||
name = models.CharField(max_length=100)
|
||||
tagline = models.TextField()
|
||||
|
||||
def __str__(self):
|
||||
def __unicode__(self):
|
||||
return self.name
|
||||
|
||||
class Author(models.Model):
|
||||
name = models.CharField(maxlength=50)
|
||||
email = models.URLField()
|
||||
name = models.CharField(max_length=50)
|
||||
email = models.EmailField()
|
||||
|
||||
def __str__(self):
|
||||
def __unicode__(self):
|
||||
return self.name
|
||||
|
||||
class Entry(models.Model):
|
||||
blog = models.ForeignKey(Blog)
|
||||
headline = models.CharField(maxlength=255)
|
||||
headline = models.CharField(max_length=255)
|
||||
body_text = models.TextField()
|
||||
pub_date = models.DateTimeField()
|
||||
authors = models.ManyToManyField(Author)
|
||||
|
||||
def __str__(self):
|
||||
def __unicode__(self):
|
||||
return self.headline
|
||||
|
||||
Creating objects
|
||||
@@ -118,6 +118,79 @@ happens.
|
||||
Explicitly specifying auto-primary-key values is mostly useful for bulk-saving
|
||||
objects, when you're confident you won't have primary-key collision.
|
||||
|
||||
What happens when you save?
|
||||
---------------------------
|
||||
|
||||
When you save an object, Django performs the following steps:
|
||||
|
||||
1. **Emit a ``pre_save`` signal.** This provides a notification that
|
||||
an object is about to be saved. You can register a listener that
|
||||
will be invoked whenever this signal is emitted. (These signals are
|
||||
not yet documented.)
|
||||
|
||||
2. **Pre-process the data.** Each field on the object is asked to
|
||||
perform any automated data modification that the field may need
|
||||
to perform.
|
||||
|
||||
Most fields do *no* pre-processing -- the field data is kept as-is.
|
||||
Pre-processing is only used on fields that have special behavior.
|
||||
For example, if your model has a ``DateField`` with ``auto_now=True``,
|
||||
the pre-save phase will alter the data in the object to ensure that
|
||||
the date field contains the current date stamp. (Our documentation
|
||||
doesn't yet include a list of all the fields with this "special
|
||||
behavior.")
|
||||
|
||||
3. **Prepare the data for the database.** Each field is asked to provide
|
||||
its current value in a data type that can be written to the database.
|
||||
|
||||
Most fields require *no* data preparation. Simple data types, such as
|
||||
integers and strings, are 'ready to write' as a Python object. However,
|
||||
more complex data types often require some modification.
|
||||
|
||||
For example, ``DateFields`` use a Python ``datetime`` object to store
|
||||
data. Databases don't store ``datetime`` objects, so the field value
|
||||
must be converted into an ISO-compliant date string for insertion
|
||||
into the database.
|
||||
|
||||
4. **Insert the data into the database.** The pre-processed, prepared
|
||||
data is then composed into an SQL statement for insertion into the
|
||||
database.
|
||||
|
||||
5. **Emit a ``post_save`` signal.** As with the ``pre_save`` signal, this
|
||||
is used to provide notification that an object has been successfully
|
||||
saved. (These signals are not yet documented.)
|
||||
|
||||
Raw Saves
|
||||
~~~~~~~~~
|
||||
|
||||
**New in Django development version**
|
||||
|
||||
The pre-processing step (#2 in the previous section) is useful, but it modifies
|
||||
the data stored in a field. This can cause problems if you're relying upon the
|
||||
data you provide being used as-is.
|
||||
|
||||
For example, if you're setting up conditions for a test, you'll want the test
|
||||
conditions to be repeatable. If pre-processing is performed, the data used
|
||||
to specify test conditions may be modified, changing the conditions for the
|
||||
test each time the test is run.
|
||||
|
||||
In cases such as this, you need to prevent pre-processing from being performed
|
||||
when you save an object. To do this, you can invoke a **raw save** by passing
|
||||
``raw=True`` as an argument to the ``save()`` method::
|
||||
|
||||
b4.save(raw=True) # Save object, but do no pre-processing
|
||||
|
||||
A raw save skips the usual data pre-processing that is performed during the
|
||||
save. All other steps in the save (pre-save signal, data preparation, data
|
||||
insertion, and post-save signal) are performed as normal.
|
||||
|
||||
.. admonition:: When to use a raw save
|
||||
|
||||
Generally speaking, you shouldn't need to use a raw save. Disabling field
|
||||
pre-processing is an extraordinary measure that should only be required
|
||||
in extraordinary circumstances, such as setting up reliable test
|
||||
conditions.
|
||||
|
||||
Saving changes to objects
|
||||
=========================
|
||||
|
||||
@@ -140,7 +213,7 @@ object of the right type to the field in question::
|
||||
joe = Author.objects.create(name="Joe")
|
||||
entry.author = joe
|
||||
entry.save()
|
||||
|
||||
|
||||
Django will complain if you try to assign an object of the wrong type.
|
||||
|
||||
How Django knows to UPDATE vs. INSERT
|
||||
@@ -336,7 +409,7 @@ For example, this returns the first 5 objects (``LIMIT 5``)::
|
||||
|
||||
Entry.objects.all()[:5]
|
||||
|
||||
This returns the fifth through tenth objects (``OFFSET 5 LIMIT 5``)::
|
||||
This returns the sixth through tenth objects (``OFFSET 5 LIMIT 5``)::
|
||||
|
||||
Entry.objects.all()[5:10]
|
||||
|
||||
@@ -1430,7 +1503,7 @@ precede the definition of any keyword arguments. For example::
|
||||
|
||||
See the `OR lookups examples page`_ for more examples.
|
||||
|
||||
.. _OR lookups examples page: http://www.djangoproject.com/documentation/models/or_lookups/
|
||||
.. _OR lookups examples page: ../models/or_lookups/
|
||||
|
||||
Related objects
|
||||
===============
|
||||
@@ -1733,8 +1806,8 @@ following model::
|
||||
('F', 'Female'),
|
||||
)
|
||||
class Person(models.Model):
|
||||
name = models.CharField(maxlength=20)
|
||||
gender = models.CharField(maxlength=1, choices=GENDER_CHOICES)
|
||||
name = models.CharField(max_length=20)
|
||||
gender = models.CharField(max_length=1, choices=GENDER_CHOICES)
|
||||
|
||||
...each ``Person`` instance will have a ``get_gender_display()`` method. Example::
|
||||
|
||||
@@ -1761,7 +1834,7 @@ Note that in the case of identical date values, these methods will use the ID
|
||||
as a fallback check. This guarantees that no records are skipped or duplicated.
|
||||
For a full example, see the `lookup API sample model`_.
|
||||
|
||||
.. _lookup API sample model: http://www.djangoproject.com/documentation/models/lookup/
|
||||
.. _lookup API sample model: ../models/lookup/
|
||||
|
||||
get_FOO_filename()
|
||||
------------------
|
||||
@@ -1818,8 +1891,8 @@ get_object_or_404()
|
||||
One common idiom to use ``get()`` and raise ``Http404`` if the
|
||||
object doesn't exist. This idiom is captured by ``get_object_or_404()``.
|
||||
This function takes a Django model as its first argument and an
|
||||
arbitrary number of keyword arguments, which it passes to the manager's
|
||||
``get()`` function. It raises ``Http404`` if the object doesn't
|
||||
arbitrary number of keyword arguments, which it passes to the default
|
||||
manager's ``get()`` function. It raises ``Http404`` if the object doesn't
|
||||
exist. For example::
|
||||
|
||||
# Get the Entry with a primary key of 3
|
||||
@@ -1828,7 +1901,7 @@ exist. For example::
|
||||
When you provide a model to this shortcut function, the default manager
|
||||
is used to execute the underlying ``get()`` query. If you don't want to
|
||||
use the default manager, or if you want to search a list of related objects,
|
||||
you can provide ``get_object_or_404()`` with a manager object instead.
|
||||
you can provide ``get_object_or_404()`` with a ``Manager`` object instead.
|
||||
For example::
|
||||
|
||||
# Get the author of blog instance e with a name of 'Fred'
|
||||
@@ -1838,6 +1911,14 @@ For example::
|
||||
# entry with a primary key of 3
|
||||
e = get_object_or_404(Entry.recent_entries, pk=3)
|
||||
|
||||
**New in Django development version:** The first argument to
|
||||
``get_object_or_404()`` can be a ``QuerySet`` object. This is useful in cases
|
||||
where you've defined a custom manager method. For example::
|
||||
|
||||
# Use a QuerySet returned from a 'published' method of a custom manager
|
||||
# in the search for an entry with primary key of 5
|
||||
e = get_object_or_404(Entry.objects.published(), pk=5)
|
||||
|
||||
get_list_or_404()
|
||||
-----------------
|
||||
|
||||
|
||||
@@ -21,16 +21,17 @@ Linux distributions
|
||||
Debian
|
||||
------
|
||||
|
||||
A `packaged version of Django`_ is available for `Debian GNU/Linux`_, and can be
|
||||
installed from either the "testing" or the "unstable" repositories by typing
|
||||
``apt-get install python-django``.
|
||||
A `packaged version of Django`_ is available for `Debian GNU/Linux`_. Version
|
||||
0.95.1 is available in the "stable" repository; Version 0.96 is available in
|
||||
the "testing" and "unstable" repositories. Regardless of your chosen repository,
|
||||
you can install Django by typing ``apt-get install python-django``.
|
||||
|
||||
When you install this package, ``apt`` will recommend installing a database
|
||||
adapter; you should select and install the adapter for whichever database you
|
||||
plan to use with Django.
|
||||
|
||||
.. _Debian GNU/Linux: http://www.debian.org/
|
||||
.. _packaged version of Django: http://packages.debian.org/testing/python/python-django
|
||||
.. _packaged version of Django: http://packages.debian.org/stable/python/python-django
|
||||
|
||||
Ubuntu
|
||||
------
|
||||
@@ -64,11 +65,24 @@ The `current Gentoo build`_ can be installed by typing ``emerge django``.
|
||||
.. _Gentoo Linux: http://www.gentoo.org/
|
||||
.. _current Gentoo build: http://packages.gentoo.org/packages/?category=dev-python;name=django
|
||||
|
||||
Mac OS X
|
||||
========
|
||||
|
||||
MacPorts
|
||||
--------
|
||||
|
||||
Django 0.96 can be installed via the `MacPorts`_ system. If you're using Python 2.4,
|
||||
type ``sudo port install py-django-devel``. For Python 2.5, type ``sudo port
|
||||
install py25-django-devel``. MacPorts can also be used to install a database,
|
||||
and the Python interface to your chosen database.
|
||||
|
||||
.. _MacPorts: http://www.macports.org/
|
||||
|
||||
For distributors
|
||||
================
|
||||
|
||||
If you'd like to package Django for distribution, we'd be happy to help out!
|
||||
Please join the `django-developers mailing list`_ and introduce yourself.
|
||||
Please join the `django-developers mailing list`_ and introduce yourself.
|
||||
|
||||
We also encourage all distributors to subscribe to the `django-announce mailing
|
||||
list`_, which is a (very) low-traffic list for announcing new releases of Django
|
||||
|
||||
@@ -235,6 +235,7 @@ The ``dumpdata`` command can be used to generate input for ``loaddata``.
|
||||
|
||||
reset [appname appname ...]
|
||||
---------------------------
|
||||
|
||||
Executes the equivalent of ``sqlreset`` for the given appnames.
|
||||
|
||||
runfcgi [options]
|
||||
@@ -400,6 +401,19 @@ install them in the database. This includes any apps shipped with Django that
|
||||
might be in ``INSTALLED_APPS`` by default. When you start a new project, run
|
||||
this command to install the default apps.
|
||||
|
||||
.. admonition:: Syncdb will not alter existing tables
|
||||
|
||||
``syncdb`` will only create tables for models which have not yet been
|
||||
installed. It will *never* issue ``ALTER TABLE`` statements to match
|
||||
changes made to a model class after installation. Changes to model classes
|
||||
and database schemas often involve some form of ambiguity and, in those
|
||||
cases, Django would have to guess at the correct changes to make. There is
|
||||
a risk that critical data would be lost in the process.
|
||||
|
||||
If you have made changes to a model and wish to alter the database tables
|
||||
to match, use the ``sql`` command to display the new SQL structure and
|
||||
compare that to your existing table schema to work out the changes.
|
||||
|
||||
If you're installing the ``django.contrib.auth`` application, ``syncdb`` will
|
||||
give you the option of creating a superuser immediately.
|
||||
|
||||
@@ -413,7 +427,46 @@ test
|
||||
|
||||
Discover and run tests for all installed models. See `Testing Django applications`_ for more information.
|
||||
|
||||
.. _testing django applications: ../testing/
|
||||
.. _testing Django applications: ../testing/
|
||||
|
||||
testserver [fixture fixture ...]
|
||||
--------------------------------
|
||||
|
||||
**New in Django development version**
|
||||
|
||||
Runs a Django development server (as in ``runserver``) using data from the
|
||||
given fixture(s).
|
||||
|
||||
For example, this command::
|
||||
|
||||
django-admin.py testserver mydata.json
|
||||
|
||||
...would perform the following steps:
|
||||
|
||||
1. Create a test database, as described in `testing Django applications`_.
|
||||
2. Populate the test database with fixture data from the given fixtures.
|
||||
(For more on fixtures, see the documentation for ``loaddata`` above.)
|
||||
3. Runs the Django development server (as in ``runserver``), pointed at
|
||||
this newly created test database instead of your production database.
|
||||
|
||||
This is useful in a number of ways:
|
||||
|
||||
* When you're writing `unit tests`_ of how your views act with certain
|
||||
fixture data, you can use ``testserver`` to interact with the views in
|
||||
a Web browser, manually.
|
||||
|
||||
* Let's say you're developing your Django application and have a "pristine"
|
||||
copy of a database that you'd like to interact with. You can dump your
|
||||
database to a fixture (using the ``dumpdata`` command, explained above),
|
||||
then use ``testserver`` to run your Web application with that data. With
|
||||
this arrangement, you have the flexibility of messing up your data
|
||||
in any way, knowing that whatever data changes you're making are only
|
||||
being made to a test database.
|
||||
|
||||
Note that this server can only run on the default port on localhost; it does
|
||||
not yet accept a ``host`` or ``port`` parameter.
|
||||
|
||||
.. _unit tests: ../testing/
|
||||
|
||||
validate
|
||||
--------
|
||||
|
||||
@@ -314,7 +314,7 @@ To send a text and HTML combination, you could write::
|
||||
|
||||
subject, from_email, to = 'hello', 'from@example.com', 'to@example.com'
|
||||
text_content = 'This is an important message.'
|
||||
html_content = '<p>This is an <strong>important</strong> message.'
|
||||
html_content = '<p>This is an <strong>important</strong> message.</p>'
|
||||
msg = EmailMultiAlternatives(subject, text_content, from_email, to)
|
||||
msg.attach_alternative(html_content, "text/html")
|
||||
msg.send()
|
||||
|
||||
@@ -42,7 +42,10 @@ Listen to his music. You'll like it.
|
||||
|
||||
Django is pronounced **JANG**-oh. Rhymes with FANG-oh. The "D" is silent.
|
||||
|
||||
We've also recorded an `audio clip of the pronunciation`_.
|
||||
|
||||
.. _Django Reinhardt: http://en.wikipedia.org/wiki/Django_Reinhardt
|
||||
.. _audio clip of the pronunciation: http://red-bean.com/~adrian/django_pronunciation.mp3
|
||||
|
||||
Is Django stable?
|
||||
-----------------
|
||||
|
||||
@@ -93,7 +93,7 @@ protocol by using the ``protocol=<protocol_name>`` option with
|
||||
``./manage.py runfcgi`` -- where ``<protocol_name>`` may be one of: ``fcgi``
|
||||
(the default), ``scgi`` or ``ajp``. For example::
|
||||
|
||||
./manage.py runfcgi --protocol=scgi
|
||||
./manage.py runfcgi protocol=scgi
|
||||
|
||||
.. _flup: http://www.saddi.com/software/flup/
|
||||
.. _fastcgi: http://www.fastcgi.com/
|
||||
|
||||
@@ -37,17 +37,17 @@ this document, we'll be working with the following model, a "place" object::
|
||||
)
|
||||
|
||||
class Place(models.Model):
|
||||
name = models.CharField(maxlength=100)
|
||||
address = models.CharField(maxlength=100, blank=True)
|
||||
city = models.CharField(maxlength=50, blank=True)
|
||||
name = models.CharField(max_length=100)
|
||||
address = models.CharField(max_length=100, blank=True)
|
||||
city = models.CharField(max_length=50, blank=True)
|
||||
state = models.USStateField()
|
||||
zip_code = models.CharField(maxlength=5, blank=True)
|
||||
zip_code = models.CharField(max_length=5, blank=True)
|
||||
place_type = models.IntegerField(choices=PLACE_TYPES)
|
||||
|
||||
class Admin:
|
||||
pass
|
||||
|
||||
def __str__(self):
|
||||
def __unicode__(self):
|
||||
return self.name
|
||||
|
||||
Defining the above class is enough to create an admin interface to a ``Place``,
|
||||
@@ -388,7 +388,7 @@ for a "contact" form on a website::
|
||||
def __init__(self):
|
||||
self.fields = (
|
||||
forms.EmailField(field_name="from", is_required=True),
|
||||
forms.TextField(field_name="subject", length=30, maxlength=200, is_required=True),
|
||||
forms.TextField(field_name="subject", length=30, max_length=200, is_required=True),
|
||||
forms.SelectField(field_name="urgency", choices=urgency_choices),
|
||||
forms.LargeTextField(field_name="contents", is_required=True),
|
||||
)
|
||||
|
||||
@@ -40,7 +40,7 @@ simple weblog app that drives the blog on djangoproject.com::
|
||||
}
|
||||
|
||||
urlpatterns = patterns('django.views.generic.date_based',
|
||||
(r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/(?P<day>\w{1,2})/(?P<slug>[-\w]+)/$', 'object_detail', dict(info_dict, slug_field='slug')),
|
||||
(r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/(?P<day>\w{1,2})/(?P<slug>[-\w]+)/$', 'object_detail', info_dict),
|
||||
(r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/(?P<day>\w{1,2})/$', 'archive_day', info_dict),
|
||||
(r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/$', 'archive_month', info_dict),
|
||||
(r'^(?P<year>\d{4})/$', 'archive_year', info_dict),
|
||||
@@ -603,7 +603,7 @@ future, the view will throw a 404 error by default, unless you set
|
||||
|
||||
Otherwise, ``slug`` should be the slug of the given object, and
|
||||
``slug_field`` should be the name of the slug field in the ``QuerySet``'s
|
||||
model.
|
||||
model. By default, ``slug_field`` is ``'slug'``.
|
||||
|
||||
**Optional arguments:**
|
||||
|
||||
@@ -804,7 +804,7 @@ A page representing an individual object.
|
||||
|
||||
Otherwise, ``slug`` should be the slug of the given object, and
|
||||
``slug_field`` should be the name of the slug field in the ``QuerySet``'s
|
||||
model.
|
||||
model. By default, ``slug_field`` is ``'slug'``.
|
||||
|
||||
**Optional arguments:**
|
||||
|
||||
@@ -948,7 +948,7 @@ object. This uses the automatic manipulators that come with Django models.
|
||||
|
||||
Otherwise, ``slug`` should be the slug of the given object, and
|
||||
``slug_field`` should be the name of the slug field in the ``QuerySet``'s
|
||||
model.
|
||||
model. By default, ``slug_field`` is ``'slug'``.
|
||||
|
||||
**Optional arguments:**
|
||||
|
||||
@@ -1033,7 +1033,7 @@ contain a form that POSTs to the same URL.
|
||||
|
||||
Otherwise, ``slug`` should be the slug of the given object, and
|
||||
``slug_field`` should be the name of the slug field in the ``QuerySet``'s
|
||||
model.
|
||||
model. By default, ``slug_field`` is ``'slug'``.
|
||||
|
||||
* ``post_delete_redirect``: A URL to which the view will redirect after
|
||||
deleting the object.
|
||||
|
||||
178
docs/i18n.txt
178
docs/i18n.txt
@@ -68,23 +68,41 @@ In Python code
|
||||
Standard translation
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Specify a translation string by using the function ``_()``. (Yes, the name of
|
||||
the function is the "underscore" character.) This function is available
|
||||
globally in any Python module; you don't have to import it.
|
||||
Specify a translation string by using the function ``ugettext()``. It's
|
||||
convention to import this as a shorter alias, ``_``, to save typing.
|
||||
|
||||
.. note::
|
||||
Python's standard library ``gettext`` module installs ``_()`` into the
|
||||
global namespace, as an alias for ``gettext()``. In Django, we have chosen
|
||||
not to follow this practice, for a couple of reasons:
|
||||
|
||||
1. For international character set (Unicode) support, ``ugettext()`` is
|
||||
more useful than ``gettext()``. Sometimes, you should be using
|
||||
``ugettext_lazy()`` as the default translation method for a particular
|
||||
file. Without ``_()`` in the global namespace, the developer has to
|
||||
think about which is the most appropriate translation function.
|
||||
|
||||
2. The underscore character (``_``) is used to represent "the previous
|
||||
result" in Python's interactive shell and doctest tests. Installing a
|
||||
global ``_()`` function causes interference. Explicitly importing
|
||||
``ugettext()`` as ``_()`` avoids this problem.
|
||||
|
||||
In this example, the text ``"Welcome to my site."`` is marked as a translation
|
||||
string::
|
||||
|
||||
from django.utils.translation import ugettext as _
|
||||
|
||||
def my_view(request):
|
||||
output = _("Welcome to my site.")
|
||||
return HttpResponse(output)
|
||||
|
||||
The function ``django.utils.translation.gettext()`` is identical to ``_()``.
|
||||
This example is identical to the previous one::
|
||||
Obviously, you could code this without using the alias. This example is
|
||||
identical to the previous one::
|
||||
|
||||
from django.utils.translation import ugettext
|
||||
|
||||
from django.utils.translation import gettext
|
||||
def my_view(request):
|
||||
output = gettext("Welcome to my site.")
|
||||
output = ugettext("Welcome to my site.")
|
||||
return HttpResponse(output)
|
||||
|
||||
Translation works on computed values. This example is identical to the previous
|
||||
@@ -107,7 +125,7 @@ examples, is that Django's translation-string-detecting utility,
|
||||
``make-messages.py``, won't be able to find these strings. More on
|
||||
``make-messages`` later.)
|
||||
|
||||
The strings you pass to ``_()`` or ``gettext()`` can take placeholders,
|
||||
The strings you pass to ``_()`` or ``ugettext()`` can take placeholders,
|
||||
specified with Python's standard named-string interpolation syntax. Example::
|
||||
|
||||
def my_view(request, n):
|
||||
@@ -120,14 +138,14 @@ while a Spanish translation may be ``"Me llamo Adrian."`` -- with the
|
||||
placeholder (the name) placed after the translated text instead of before it.
|
||||
|
||||
For this reason, you should use named-string interpolation (e.g., ``%(name)s``)
|
||||
instead of positional interpolation (e.g., ``%s`` or ``%d``). If you used
|
||||
positional interpolation, translations wouldn't be able to reorder placeholder
|
||||
text.
|
||||
instead of positional interpolation (e.g., ``%s`` or ``%d``) whenever you
|
||||
have more than a single parameter. If you used positional interpolation,
|
||||
translations wouldn't be able to reorder placeholder text.
|
||||
|
||||
Marking strings as no-op
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Use the function ``django.utils.translation.gettext_noop()`` to mark a string
|
||||
Use the function ``django.utils.translation.ugettext_noop()`` to mark a string
|
||||
as a translation string without translating it. The string is later translated
|
||||
from a variable.
|
||||
|
||||
@@ -139,35 +157,35 @@ as when the string is presented to the user.
|
||||
Lazy translation
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
Use the function ``django.utils.translation.gettext_lazy()`` to translate
|
||||
Use the function ``django.utils.translation.ugettext_lazy()`` to translate
|
||||
strings lazily -- when the value is accessed rather than when the
|
||||
``gettext_lazy()`` function is called.
|
||||
``ugettext_lazy()`` function is called.
|
||||
|
||||
For example, to translate a model's ``help_text``, do the following::
|
||||
|
||||
from django.utils.translation import gettext_lazy
|
||||
from django.utils.translation import ugettext_lazy
|
||||
|
||||
class MyThing(models.Model):
|
||||
name = models.CharField(help_text=gettext_lazy('This is the help text'))
|
||||
name = models.CharField(help_text=ugettext_lazy('This is the help text'))
|
||||
|
||||
In this example, ``gettext_lazy()`` stores a lazy reference to the string --
|
||||
In this example, ``ugettext_lazy()`` stores a lazy reference to the string --
|
||||
not the actual translation. The translation itself will be done when the string
|
||||
is used in a string context, such as template rendering on the Django admin site.
|
||||
|
||||
If you don't like the verbose name ``gettext_lazy``, you can just alias it as
|
||||
If you don't like the verbose name ``ugettext_lazy``, you can just alias it as
|
||||
``_`` (underscore), like so::
|
||||
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
class MyThing(models.Model):
|
||||
name = models.CharField(help_text=_('This is the help text'))
|
||||
|
||||
Always use lazy translations in `Django models`_. And it's a good idea to add
|
||||
Always use lazy translations in `Django models`_. It's a good idea to add
|
||||
translations for the field names and table names, too. This means writing
|
||||
explicit ``verbose_name`` and ``verbose_name_plural`` options in the ``Meta``
|
||||
class, though::
|
||||
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
class MyThing(models.Model):
|
||||
name = models.CharField(_('name'), help_text=_('This is the help text'))
|
||||
@@ -180,24 +198,24 @@ class, though::
|
||||
Pluralization
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
Use the function ``django.utils.translation.ngettext()`` to specify pluralized
|
||||
Use the function ``django.utils.translation.ungettext()`` to specify pluralized
|
||||
messages. Example::
|
||||
|
||||
from django.utils.translation import ngettext
|
||||
from django.utils.translation import ungettext
|
||||
def hello_world(request, count):
|
||||
page = ngettext('there is %(count)d object', 'there are %(count)d objects', count) % {
|
||||
page = ungettext('there is %(count)d object', 'there are %(count)d objects', count) % {
|
||||
'count': count,
|
||||
}
|
||||
return HttpResponse(page)
|
||||
|
||||
``ngettext`` takes three arguments: the singular translation string, the plural
|
||||
``ungettext`` takes three arguments: the singular translation string, the plural
|
||||
translation string and the number of objects (which is passed to the
|
||||
translation languages as the ``count`` variable).
|
||||
|
||||
In template code
|
||||
----------------
|
||||
|
||||
Using translations in `Django templates`_ uses two template tags and a slightly
|
||||
Translations in `Django templates`_ uses two template tags and a slightly
|
||||
different syntax than in Python code. To give your template access to these
|
||||
tags, put ``{% load i18n %}`` toward the top of your template.
|
||||
|
||||
@@ -243,9 +261,9 @@ To pluralize, specify both the singular and plural forms with the
|
||||
{% endblocktrans %}
|
||||
|
||||
Internally, all block and inline translations use the appropriate
|
||||
``gettext`` / ``ngettext`` call.
|
||||
``ugettext`` / ``ungettext`` call.
|
||||
|
||||
Each ``RequestContext`` has access to two translation-specific variables:
|
||||
Each ``RequestContext`` has access to three translation-specific variables:
|
||||
|
||||
* ``LANGUAGES`` is a list of tuples in which the first element is the
|
||||
language code and the second is the language name (in that language).
|
||||
@@ -276,6 +294,71 @@ string, so they don't need to be aware of translations.
|
||||
|
||||
.. _Django templates: ../templates_python/
|
||||
|
||||
Working with lazy translation objects
|
||||
=====================================
|
||||
|
||||
Using ``ugettext_lazy()`` and ``ungettext_lazy()`` to mark strings in models
|
||||
and utility functions is a common operation. When you're working with these
|
||||
objects elsewhere in your code, you should ensure that you don't accidentally
|
||||
convert them to strings, because they should be converted as late as possible
|
||||
(so that the correct locale is in effect). This necessitates the use of a
|
||||
couple of helper functions.
|
||||
|
||||
Joining strings: string_concat()
|
||||
--------------------------------
|
||||
|
||||
Standard Python string joins (``''.join([...])``) will not work on lists
|
||||
containing lazy translation objects. Instead, you can use
|
||||
``django.utils.translation.string_concat()``, which creates a lazy object that
|
||||
concatenates its contents *and* converts them to strings only when the result
|
||||
is included in a string. For example::
|
||||
|
||||
from django.utils.translation import string_concat
|
||||
...
|
||||
name = ugettext_lazy(u'John Lennon')
|
||||
instrument = ugettext_lazy(u'guitar')
|
||||
result = string_concat([name, ': ', instrument])
|
||||
|
||||
In this case, the lazy translations in ``result`` will only be converted to
|
||||
strings when ``result`` itself is used in a string (usually at template
|
||||
rendering time).
|
||||
|
||||
The allow_lazy() decorator
|
||||
--------------------------
|
||||
|
||||
Django offers many utility functions (particularly in ``django.utils``) that
|
||||
take a string as their first argument and do something to that string. These
|
||||
functions are used by template filters as well as directly in other code.
|
||||
|
||||
If you write your own similar functions and deal with translations, you'll
|
||||
face the problem of what to do when the first argument is a lazy translation
|
||||
object. You don't want to convert it to a string immediately, because you might
|
||||
be using this function outside of a view (and hence the current thread's locale
|
||||
setting will not be correct).
|
||||
|
||||
For cases like this, use the ``django.utils.functional.allow_lazy()``
|
||||
decorator. It modifies the function so that *if* it's called with a lazy
|
||||
translation as the first argument, the function evaluation is delayed until it
|
||||
needs to be converted to a string.
|
||||
|
||||
For example::
|
||||
|
||||
from django.utils.functional import allow_lazy
|
||||
|
||||
def fancy_utility_function(s, ...):
|
||||
# Do some conversion on string 's'
|
||||
...
|
||||
fancy_utility_function = allow_lazy(fancy_utility_function, unicode)
|
||||
|
||||
The ``allow_lazy()`` decorator takes, in addition to the function to decorate,
|
||||
a number of extra arguments (``*args``) specifying the type(s) that the
|
||||
original function can return. Usually, it's enough to include ``unicode`` here
|
||||
and ensure that your function returns only Unicode strings.
|
||||
|
||||
Using this decorator means you can write your function and assume that the
|
||||
input is a proper string, then add support for lazy translation objects at the
|
||||
end.
|
||||
|
||||
How to create language files
|
||||
============================
|
||||
|
||||
@@ -487,26 +570,26 @@ Notes:
|
||||
|
||||
* If you define a custom ``LANGUAGES`` setting, as explained in the
|
||||
previous bullet, it's OK to mark the languages as translation strings
|
||||
-- but use a "dummy" ``gettext()`` function, not the one in
|
||||
-- but use a "dummy" ``ugettext()`` function, not the one in
|
||||
``django.utils.translation``. You should *never* import
|
||||
``django.utils.translation`` from within your settings file, because that
|
||||
module in itself depends on the settings, and that would cause a circular
|
||||
import.
|
||||
|
||||
The solution is to use a "dummy" ``gettext()`` function. Here's a sample
|
||||
The solution is to use a "dummy" ``ugettext()`` function. Here's a sample
|
||||
settings file::
|
||||
|
||||
gettext = lambda s: s
|
||||
ugettext = lambda s: s
|
||||
|
||||
LANGUAGES = (
|
||||
('de', gettext('German')),
|
||||
('en', gettext('English')),
|
||||
('de', ugettext('German')),
|
||||
('en', ugettext('English')),
|
||||
)
|
||||
|
||||
With this arrangement, ``make-messages.py`` will still find and mark
|
||||
these strings for translation, but the translation won't happen at
|
||||
runtime -- so you'll have to remember to wrap the languages in the *real*
|
||||
``gettext()`` in any code that uses ``LANGUAGES`` at runtime.
|
||||
``ugettext()`` in any code that uses ``LANGUAGES`` at runtime.
|
||||
|
||||
* The ``LocaleMiddleware`` can only select languages for which there is a
|
||||
Django-provided base translation. If you want to provide translations
|
||||
@@ -712,23 +795,23 @@ interface to access it::
|
||||
|
||||
document.write(gettext('this is to be translated'));
|
||||
|
||||
There even is a ``ngettext`` interface and a string interpolation function::
|
||||
There even is a ``ungettext`` interface and a string interpolation function::
|
||||
|
||||
d = {
|
||||
count: 10
|
||||
};
|
||||
s = interpolate(ngettext('this is %(count)s object', 'this are %(count)s objects', d.count), d);
|
||||
s = interpolate(ungettext('this is %(count)s object', 'this are %(count)s objects', d.count), d);
|
||||
|
||||
The ``interpolate`` function supports both positional interpolation and named
|
||||
interpolation. So the above could have been written as::
|
||||
|
||||
s = interpolate(ngettext('this is %s object', 'this are %s objects', 11), [11]);
|
||||
s = interpolate(ungettext('this is %s object', 'this are %s objects', 11), [11]);
|
||||
|
||||
The interpolation syntax is borrowed from Python. You shouldn't go over the top
|
||||
with string interpolation, though: this is still JavaScript, so the code will
|
||||
have to do repeated regular-expression substitutions. This isn't as fast as
|
||||
string interpolation in Python, so keep it to those cases where you really
|
||||
need it (for example, in conjunction with ``ngettext`` to produce proper
|
||||
need it (for example, in conjunction with ``ungettext`` to produce proper
|
||||
pluralizations).
|
||||
|
||||
Creating JavaScript translation catalogs
|
||||
@@ -750,16 +833,13 @@ Specialities of Django translation
|
||||
If you know ``gettext``, you might note these specialities in the way Django
|
||||
does translation:
|
||||
|
||||
* The string domain is ``django`` or ``djangojs``. The string domain is used to
|
||||
differentiate between different programs that store their data in a
|
||||
common message-file library (usually ``/usr/share/locale/``). The ``django``
|
||||
domain is used for python and template translation strings and is loaded into
|
||||
the global translation catalogs. The ``djangojs`` domain is only used for
|
||||
JavaScript translation catalogs to make sure that those are as small as
|
||||
possible.
|
||||
* Django only uses ``gettext`` and ``gettext_noop``. That's because Django
|
||||
always uses ``DEFAULT_CHARSET`` strings internally. There isn't much use
|
||||
in using ``ugettext``, because you'll always need to produce utf-8
|
||||
anyway.
|
||||
* The string domain is ``django`` or ``djangojs``. The string domain is
|
||||
used to differentiate between different programs that store their data
|
||||
in a common message-file library (usually ``/usr/share/locale/``). The
|
||||
``django`` domain is used for python and template translation strings
|
||||
and is loaded into the global translation catalogs. The ``djangojs``
|
||||
domain is only used for JavaScript translation catalogs to make sure
|
||||
that those are as small as possible.
|
||||
* Django doesn't use ``xgettext`` alone. It uses Python wrappers around
|
||||
``xgettext`` and ``msgfmt``. That's mostly for convenience.
|
||||
|
||||
|
||||
@@ -48,8 +48,8 @@ Get your database running
|
||||
|
||||
If you plan to use Django's database API functionality, you'll need to
|
||||
make sure a database server is running. Django works with PostgreSQL_,
|
||||
MySQL_, Oracle_ and SQLite_ (the latter doesn't require a separate server to
|
||||
be running).
|
||||
MySQL_, Oracle_ and SQLite_ (although SQLite doesn't require a separate server
|
||||
to be running).
|
||||
|
||||
Additionally, you'll need to make sure your Python database bindings are
|
||||
installed.
|
||||
@@ -109,25 +109,29 @@ Install the Django code
|
||||
=======================
|
||||
|
||||
Installation instructions are slightly different depending on whether you're
|
||||
using the latest official version or the latest development version.
|
||||
installing a distribution-specific package, downloading the the latest official
|
||||
release, or fetching the latest development version.
|
||||
|
||||
It's easy either way.
|
||||
It's easy, no matter which way you choose.
|
||||
|
||||
Installing the official version
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Installing a distribution-specific package
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
1. Check the `distribution specific notes`_ to see if your
|
||||
platform/distribution provides official Django packages/installers.
|
||||
Distribution-provided packages will typically allow for automatic
|
||||
installation of dependancies and easy upgrade paths.
|
||||
Check the `distribution specific notes`_ to see if your
|
||||
platform/distribution provides official Django packages/installers.
|
||||
Distribution-provided packages will typically allow for automatic
|
||||
installation of dependancies and easy upgrade paths.
|
||||
|
||||
2. Download the latest release from our `download page`_.
|
||||
Installing an official release
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
3. Untar the downloaded file (e.g. ``tar xzvf Django-NNN.tar.gz``).
|
||||
1. Download the latest release from our `download page`_.
|
||||
|
||||
4. Change into the downloaded directory (e.g. ``cd Django-NNN``).
|
||||
2. Untar the downloaded file (e.g. ``tar xzvf Django-NNN.tar.gz``).
|
||||
|
||||
5. Run ``sudo python setup.py install``.
|
||||
3. Change into the downloaded directory (e.g. ``cd Django-NNN``).
|
||||
|
||||
4. Run ``sudo python setup.py install``.
|
||||
|
||||
The command will install Django in your Python installation's ``site-packages``
|
||||
directory.
|
||||
|
||||
40
docs/man/compile-messages.1
Normal file
40
docs/man/compile-messages.1
Normal file
@@ -0,0 +1,40 @@
|
||||
.TH "compile-messages.py" "1" "August 2007" "Django Project" ""
|
||||
.SH "NAME"
|
||||
compile-messages.py \- Internationalization utility for the Django
|
||||
web framework
|
||||
.SH "SYNOPSIS"
|
||||
.B compile-messages.py \fR[-l <locale>]
|
||||
|
||||
.SH "DESCRIPTION"
|
||||
A Django-customised wrapper around gettext's \fBmsgfmt\fR command. Generates
|
||||
binary message catalogs (.mo files) from textual translation descriptions (.po
|
||||
files).
|
||||
.sp
|
||||
The script should be invoked after running
|
||||
.BI make-messages.py,
|
||||
in the same directory from which
|
||||
.BI make-messages.py
|
||||
was invoked.
|
||||
|
||||
.SH "OPTIONS"
|
||||
.TP
|
||||
.I \-l <locale>
|
||||
Compile the message catalogs for a specific locale. If this option is omitted,
|
||||
all message catalogs are (re-)compiled.
|
||||
|
||||
.SH "SEE ALSO"
|
||||
The man page for
|
||||
.BI msgfmt
|
||||
from the GNU gettext utilities, and the internationalization documentation
|
||||
for Django:
|
||||
.sp
|
||||
.I http://www.djangoproject.com/documentation/i18n/
|
||||
|
||||
.SH "AUTHORS/CREDITS"
|
||||
Originally developed at World Online in Lawrence, Kansas, USA. Refer to the
|
||||
AUTHORS file in the Django distribution for contributors.
|
||||
|
||||
.SH "LICENSE"
|
||||
New BSD license. For the full license text refer to the LICENSE file in the
|
||||
Django distribution.
|
||||
|
||||
34
docs/man/daily_cleanup.1
Normal file
34
docs/man/daily_cleanup.1
Normal file
@@ -0,0 +1,34 @@
|
||||
.TH "daily_cleanup.py" "1" "August 2007" "Django Project" ""
|
||||
.SH "NAME"
|
||||
daily_cleanup.py \- Database clean-up for the Django web framework
|
||||
.SH "SYNOPSIS"
|
||||
.B daily_cleanup.py
|
||||
|
||||
.SH "DESCRIPTION"
|
||||
Removes stale session data from a Django database. This means, any session data
|
||||
which has an expiry date prior to the date the script is run.
|
||||
.sp
|
||||
The script can be run manually or can be scheduled to run at regular
|
||||
intervals as a
|
||||
.BI cron
|
||||
job.
|
||||
|
||||
.SH "ENVIRONMENT"
|
||||
.TP
|
||||
.I DJANGO_SETTINGS_MODULE
|
||||
This environment variable defines the settings module to be read.
|
||||
It should be in Python-import form, e.g. "myproject.settings".
|
||||
|
||||
.SH "SEE ALSO"
|
||||
The sessions documentation:
|
||||
.sp
|
||||
.I http://www.djangoproject.com/documentation/sessions/
|
||||
|
||||
.SH "AUTHORS/CREDITS"
|
||||
Originally developed at World Online in Lawrence, Kansas, USA. Refer to the
|
||||
AUTHORS file in the Django distribution for contributors.
|
||||
|
||||
.SH "LICENSE"
|
||||
New BSD license. For the full license text refer to the LICENSE file in the
|
||||
Django distribution.
|
||||
|
||||
26
docs/man/gather_profile_stats.1
Normal file
26
docs/man/gather_profile_stats.1
Normal file
@@ -0,0 +1,26 @@
|
||||
.TH "gather_profile_stats.py" "1" "August 2007" "Django Project" ""
|
||||
.SH "NAME"
|
||||
gather_profile_stats.py \- Performance analysis tool for the Django web
|
||||
framework
|
||||
.SH "SYNOPSIS"
|
||||
.B python gather_profile_stats.py
|
||||
.I <path>
|
||||
|
||||
.SH "DESCRIPTION"
|
||||
This utility script aggregates profiling logs generated using Python's
|
||||
hotshot profiler. The sole command-line argument is the full path to the
|
||||
directory containing the profiling logfiles.
|
||||
|
||||
.SH "SEE ALSO"
|
||||
Discussion of profiling Django applications on the Django project's wiki:
|
||||
.sp
|
||||
.I http://www.djangoproject.com/wiki/ProfilingDjango
|
||||
|
||||
.SH "AUTHORS/CREDITS"
|
||||
Originally developed at World Online in Lawrence, Kansas, USA. Refer to the
|
||||
AUTHORS file in the Django distribution for contributors.
|
||||
|
||||
.SH "LICENSE"
|
||||
New BSD license. For the full license text refer to the LICENSE file in the
|
||||
Django distribution.
|
||||
|
||||
62
docs/man/make-messages.1
Normal file
62
docs/man/make-messages.1
Normal file
@@ -0,0 +1,62 @@
|
||||
.TH "make-messages.py" "1" "August 2007" "Django Project" ""
|
||||
.SH "NAME"
|
||||
make-messages.py \- Internationalization utility for the Django
|
||||
web framework
|
||||
.SH "SYNOPSIS"
|
||||
.B make-messages.py\fR [\-a] [\-v] [\-l <locale>] [\-d <domain>]
|
||||
|
||||
.SH "DESCRIPTION"
|
||||
This script creates or updates one or more message files for a Django app,
|
||||
a Django project or the Django framework itself. It should be run from one
|
||||
of three places: the root directory of a Django app; the root directory
|
||||
of a Django project; or the root django directory (the one in your PYTHONPATH,
|
||||
not the root of a Subversion checkout).
|
||||
.sp
|
||||
The script will run over the source tree of an application, project or Django
|
||||
itself (depending on where it is invoked), pulling out all strings marked for
|
||||
translation and creating or updating a standard PO-format message file for the
|
||||
specified language. Refer to Django's internationalization documentation for
|
||||
details of where this file is created.
|
||||
.sp
|
||||
The \fI\-a\fR and \fI\-l\fR options are used to control whether message
|
||||
catalogs are created for all locales, or just a single one.
|
||||
|
||||
.SH "OPTIONS"
|
||||
.TP
|
||||
.I \-a
|
||||
Run make-messages for all locales specified in the Django settings file. Cannot
|
||||
be used in conjuntion with \fI\-l\fR.
|
||||
.TP
|
||||
.I \-d <domain>
|
||||
Specifies the translation domain to use. Valid domains are \fIdjango\fR or
|
||||
\fIdjangojs\fR, depending on whether you wish to generate translation strings
|
||||
for the Python or JavaScript components of your app, your project or the
|
||||
framework itself. The default domain is \fIdjango\fR.
|
||||
.TP
|
||||
.I \-l <locale>
|
||||
Extract messages for a particular locale.
|
||||
.TP
|
||||
.I \-v
|
||||
Run verbosely.
|
||||
|
||||
.SH "ENVIRONMENT"
|
||||
.TP
|
||||
.I DJANGO_SETTINGS_MODULE
|
||||
This environment variable defines the settings module to be read.
|
||||
It should be in Python-import form, e.g. "myproject.settings".
|
||||
|
||||
.SH "SEE ALSO"
|
||||
The Django internationalization documentation:
|
||||
.sp
|
||||
.I http://www.djangoproject.com/documentation/i18n/
|
||||
.sp
|
||||
The PO file format is documented in the GNU gettext documentation.
|
||||
|
||||
.SH "AUTHORS/CREDITS"
|
||||
Originally developed at World Online in Lawrence, Kansas, USA. Refer to the
|
||||
AUTHORS file in the Django distribution for contributors.
|
||||
|
||||
.SH "LICENSE"
|
||||
New BSD license. For the full license text refer to the LICENSE file in the
|
||||
Django distribution.
|
||||
|
||||
@@ -91,6 +91,12 @@ django.middleware.gzip.GZipMiddleware
|
||||
Compresses content for browsers that understand gzip compression (all modern
|
||||
browsers).
|
||||
|
||||
It is suggested to place this first in the middleware list, so that the
|
||||
compression of the response content is the last thing that happens. Will not
|
||||
compress content bodies less than 200 bytes long, when the response code is
|
||||
something other than 200, Javascript files (for IE compatibitility), or
|
||||
responses that have the ``Content-Encoding`` header already specified.
|
||||
|
||||
django.middleware.http.ConditionalGetMiddleware
|
||||
-----------------------------------------------
|
||||
|
||||
@@ -116,6 +122,14 @@ not use this middleware. Anybody can spoof the value of
|
||||
``HTTP_X_FORWARDED_FOR``, that means anybody can "fake" their IP address. Only
|
||||
use this when you can absolutely trust the value of ``HTTP_X_FORWARDED_FOR``.
|
||||
|
||||
django.middleware.locale.LocaleMiddleware
|
||||
-----------------------------------------
|
||||
|
||||
Enables language selection based on data from the request. It customizes content
|
||||
for each user. See the `internationalization documentation`_.
|
||||
|
||||
.. _`internationalization documentation`: ../i18n/
|
||||
|
||||
django.contrib.sessions.middleware.SessionMiddleware
|
||||
----------------------------------------------------
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ A companion to this document is the `official repository of model examples`_.
|
||||
``tests/modeltests`` directory.)
|
||||
|
||||
.. _Database API reference: ../db-api/
|
||||
.. _official repository of model examples: http://www.djangoproject.com/documentation/models/
|
||||
.. _official repository of model examples: ../models/
|
||||
|
||||
Quick example
|
||||
=============
|
||||
@@ -33,8 +33,8 @@ This example model defines a ``Person``, which has a ``first_name`` and
|
||||
from django.db import models
|
||||
|
||||
class Person(models.Model):
|
||||
first_name = models.CharField(maxlength=30)
|
||||
last_name = models.CharField(maxlength=30)
|
||||
first_name = models.CharField(max_length=30)
|
||||
last_name = models.CharField(max_length=30)
|
||||
|
||||
``first_name`` and ``last_name`` are *fields* of the model. Each field is
|
||||
specified as a class attribute, and each attribute maps to a database column.
|
||||
@@ -69,13 +69,13 @@ attributes.
|
||||
Example::
|
||||
|
||||
class Musician(models.Model):
|
||||
first_name = models.CharField(maxlength=50)
|
||||
last_name = models.CharField(maxlength=50)
|
||||
instrument = models.CharField(maxlength=100)
|
||||
first_name = models.CharField(max_length=50)
|
||||
last_name = models.CharField(max_length=50)
|
||||
instrument = models.CharField(max_length=100)
|
||||
|
||||
class Album(models.Model):
|
||||
artist = models.ForeignKey(Musician)
|
||||
name = models.CharField(maxlength=100)
|
||||
name = models.CharField(max_length=100)
|
||||
release_date = models.DateField()
|
||||
num_stars = models.IntegerField()
|
||||
|
||||
@@ -142,14 +142,18 @@ For large amounts of text, use ``TextField``.
|
||||
|
||||
The admin represents this as an ``<input type="text">`` (a single-line input).
|
||||
|
||||
``CharField`` has an extra required argument, ``maxlength``, the maximum length
|
||||
(in characters) of the field. The maxlength is enforced at the database level
|
||||
``CharField`` has an extra required argument, ``max_length``, the maximum length
|
||||
(in characters) of the field. The max_length is enforced at the database level
|
||||
and in Django's validation.
|
||||
|
||||
Django veterans: Note that the argument is now called ``max_length`` to
|
||||
provide consistency throughout Django. There is full legacy support for
|
||||
the old ``maxlength`` argument, but ``max_length`` is prefered.
|
||||
|
||||
``CommaSeparatedIntegerField``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
A field of integers separated by commas. As in ``CharField``, the ``maxlength``
|
||||
A field of integers separated by commas. As in ``CharField``, the ``max_length``
|
||||
argument is required.
|
||||
|
||||
``DateField``
|
||||
@@ -217,7 +221,7 @@ The admin represents this as an ``<input type="text">`` (a single-line input).
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
A ``CharField`` that checks that the value is a valid e-mail address.
|
||||
This doesn't accept ``maxlength``; its ``maxlength`` is automatically set to
|
||||
This doesn't accept ``max_length``; its ``max_length`` is automatically set to
|
||||
75.
|
||||
|
||||
``FileField``
|
||||
@@ -400,7 +404,7 @@ Like a ``PositiveIntegerField``, but only allows values under a certain
|
||||
containing only letters, numbers, underscores or hyphens. They're generally
|
||||
used in URLs.
|
||||
|
||||
Like a CharField, you can specify ``maxlength``. If ``maxlength`` is
|
||||
Like a CharField, you can specify ``max_length``. If ``max_length`` is
|
||||
not specified, Django will use a default length of 50.
|
||||
|
||||
Implies ``db_index=True``.
|
||||
@@ -411,7 +415,8 @@ form::
|
||||
|
||||
models.SlugField(prepopulate_from=("pre_name", "name"))
|
||||
|
||||
``prepopulate_from`` doesn't accept DateTimeFields.
|
||||
``prepopulate_from`` doesn't accept DateTimeFields, ForeignKeys nor
|
||||
ManyToManyFields.
|
||||
|
||||
The admin represents ``SlugField`` as an ``<input type="text">`` (a
|
||||
single-line input).
|
||||
@@ -447,9 +452,9 @@ and doesn't give a 404 response).
|
||||
|
||||
The admin represents this as an ``<input type="text">`` (a single-line input).
|
||||
|
||||
``URLField`` takes an optional argument, ``maxlength``, the maximum length (in
|
||||
characters) of the field. The maxlength is enforced at the database level and
|
||||
in Django's validation. If you don't specify ``maxlength``, a default of 200
|
||||
``URLField`` takes an optional argument, ``max_length``, the maximum length (in
|
||||
characters) of the field. The maximum length is enforced at the database level and
|
||||
in Django's validation. If you don't specify ``max_length``, a default of 200
|
||||
is used.
|
||||
|
||||
``USStateField``
|
||||
@@ -536,7 +541,7 @@ The choices list can be defined either as part of your model class::
|
||||
('M', 'Male'),
|
||||
('F', 'Female'),
|
||||
)
|
||||
gender = models.CharField(maxlength=1, choices=GENDER_CHOICES)
|
||||
gender = models.CharField(max_length=1, choices=GENDER_CHOICES)
|
||||
|
||||
or outside your model class altogether::
|
||||
|
||||
@@ -545,7 +550,7 @@ or outside your model class altogether::
|
||||
('F', 'Female'),
|
||||
)
|
||||
class Foo(models.Model):
|
||||
gender = models.CharField(maxlength=1, choices=GENDER_CHOICES)
|
||||
gender = models.CharField(max_length=1, choices=GENDER_CHOICES)
|
||||
|
||||
For each model field that has ``choices`` set, Django will add a method to
|
||||
retrieve the human-readable name for the field's current value. See
|
||||
@@ -620,6 +625,12 @@ Extra "help" text to be displayed under the field on the object's admin
|
||||
form. It's useful for documentation even if your object doesn't have an
|
||||
admin form.
|
||||
|
||||
Note that this value is *not* HTML-escaped when it's displayed in the admin
|
||||
interface. This lets you include HTML in ``help_text`` if you so desire. For
|
||||
example::
|
||||
|
||||
help_text="Please use the following format: <em>YYYY-MM-DD</em>."
|
||||
|
||||
``primary_key``
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
@@ -698,11 +709,11 @@ it using the field's attribute name, converting underscores to spaces.
|
||||
|
||||
In this example, the verbose name is ``"Person's first name"``::
|
||||
|
||||
first_name = models.CharField("Person's first name", maxlength=30)
|
||||
first_name = models.CharField("Person's first name", max_length=30)
|
||||
|
||||
In this example, the verbose name is ``"first name"``::
|
||||
|
||||
first_name = models.CharField(maxlength=30)
|
||||
first_name = models.CharField(max_length=30)
|
||||
|
||||
``ForeignKey``, ``ManyToManyField`` and ``OneToOneField`` require the first
|
||||
argument to be a model class, so use the ``verbose_name`` keyword argument::
|
||||
@@ -727,7 +738,7 @@ Many-to-one relationships
|
||||
To define a many-to-one relationship, use ``ForeignKey``. You use it just like
|
||||
any other ``Field`` type: by including it as a class attribute of your model.
|
||||
|
||||
``ForeignKey`` requires a positional argument: The class to which the model is
|
||||
``ForeignKey`` requires a positional argument: the class to which the model is
|
||||
related.
|
||||
|
||||
For example, if a ``Car`` model has a ``Manufacturer`` -- that is, a
|
||||
@@ -775,7 +786,7 @@ You can, of course, call the field whatever you want. For example::
|
||||
|
||||
See the `Many-to-one relationship model example`_ for a full example.
|
||||
|
||||
.. _Many-to-one relationship model example: http://www.djangoproject.com/documentation/models/many_to_one/
|
||||
.. _Many-to-one relationship model example: ../models/many_to_one/
|
||||
|
||||
``ForeignKey`` fields take a number of extra arguments for defining how the
|
||||
relationship should work. All are optional:
|
||||
@@ -862,7 +873,7 @@ To define a many-to-many relationship, use ``ManyToManyField``. You use it just
|
||||
like any other ``Field`` type: by including it as a class attribute of your
|
||||
model.
|
||||
|
||||
``ManyToManyField`` requires a positional argument: The class to which the
|
||||
``ManyToManyField`` requires a positional argument: the class to which the
|
||||
model is related.
|
||||
|
||||
For example, if a ``Pizza`` has multiple ``Topping`` objects -- that is, a
|
||||
@@ -902,7 +913,7 @@ set up above, the ``Pizza`` admin form would let users select the toppings.
|
||||
|
||||
See the `Many-to-many relationship model example`_ for a full example.
|
||||
|
||||
.. _Many-to-many relationship model example: http://www.djangoproject.com/documentation/models/many_to_many/
|
||||
.. _Many-to-many relationship model example: ../models/many_to_many/
|
||||
|
||||
``ManyToManyField`` objects take a number of extra arguments for defining how
|
||||
the relationship should work. All are optional:
|
||||
@@ -959,7 +970,7 @@ model.
|
||||
This is most useful on the primary key of an object when that object "extends"
|
||||
another object in some way.
|
||||
|
||||
``OneToOneField`` requires a positional argument: The class to which the
|
||||
``OneToOneField`` requires a positional argument: the class to which the
|
||||
model is related.
|
||||
|
||||
For example, if you're building a database of "places", you would build pretty
|
||||
@@ -979,7 +990,116 @@ as a read-only field when you edit an object in the admin interface:
|
||||
|
||||
See the `One-to-one relationship model example`_ for a full example.
|
||||
|
||||
.. _One-to-one relationship model example: http://www.djangoproject.com/documentation/models/one_to_one/
|
||||
.. _One-to-one relationship model example: ../models/one_to_one/
|
||||
|
||||
Custom field types
|
||||
------------------
|
||||
|
||||
**New in Django development version**
|
||||
|
||||
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
|
||||
column types, such as geographic polygons or even user-created types such as
|
||||
`PostgreSQL custom types`_, you can define your own Django ``Field`` subclasses.
|
||||
|
||||
.. _PostgreSQL custom types: http://www.postgresql.org/docs/8.2/interactive/sql-createtype.html
|
||||
|
||||
.. admonition:: Experimental territory
|
||||
|
||||
This is an area of Django that traditionally has not been documented, but
|
||||
we're starting to include bits of documentation, one feature at a time.
|
||||
Please forgive the sparseness of this section.
|
||||
|
||||
If you like living on the edge and are comfortable with the risk of
|
||||
unstable, undocumented APIs, see the code for the core ``Field`` class
|
||||
in ``django/db/models/fields/__init__.py`` -- but if/when the innards
|
||||
change, don't say we didn't warn you.
|
||||
|
||||
To create a custom field type, simply subclass ``django.db.models.Field``.
|
||||
Here is an incomplete list of the methods you should implement:
|
||||
|
||||
``db_type()``
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
Returns the database column data type for the ``Field``, taking into account
|
||||
the current ``DATABASE_ENGINE`` setting.
|
||||
|
||||
Say you've created a PostgreSQL custom type called ``mytype``. You can use this
|
||||
field with Django by subclassing ``Field`` and implementing the ``db_type()``
|
||||
method, like so::
|
||||
|
||||
from django.db import models
|
||||
|
||||
class MytypeField(models.Field):
|
||||
def db_type(self):
|
||||
return 'mytype'
|
||||
|
||||
Once you have ``MytypeField``, you can use it in any model, just like any other
|
||||
``Field`` type::
|
||||
|
||||
class Person(models.Model):
|
||||
name = models.CharField(max_length=80)
|
||||
gender = models.CharField(max_length=1)
|
||||
something_else = MytypeField()
|
||||
|
||||
If you aim to build a database-agnostic application, you should account for
|
||||
differences in database column types. For example, the date/time column type
|
||||
in PostgreSQL is called ``timestamp``, while the same column in MySQL is called
|
||||
``datetime``. The simplest way to handle this in a ``db_type()`` method is to
|
||||
import the Django settings module and check the ``DATABASE_ENGINE`` setting.
|
||||
For example::
|
||||
|
||||
class MyDateField(models.Field):
|
||||
def db_type(self):
|
||||
from django.conf import settings
|
||||
if settings.DATABASE_ENGINE == 'mysql':
|
||||
return 'datetime'
|
||||
else:
|
||||
return 'timestamp'
|
||||
|
||||
The ``db_type()`` method is only called by Django when the framework constructs
|
||||
the ``CREATE TABLE`` statements for your application -- that is, when you first
|
||||
create your tables. It's not called at any other time, so it can afford to
|
||||
execute slightly complex code, such as the ``DATABASE_ENGINE`` check in the
|
||||
above example.
|
||||
|
||||
Some database column types accept parameters, such as ``CHAR(25)``, where the
|
||||
parameter ``25`` represents the maximum column length. In cases like these,
|
||||
it's more flexible if the parameter is specified in the model rather than being
|
||||
hard-coded in the ``db_type()`` method. For example, it wouldn't make much
|
||||
sense to have a ``CharMaxlength25Field``, shown here::
|
||||
|
||||
# This is a silly example of hard-coded parameters.
|
||||
class CharMaxlength25Field(models.Field):
|
||||
def db_type(self):
|
||||
return 'char(25)'
|
||||
|
||||
# In the model:
|
||||
class MyModel(models.Model):
|
||||
# ...
|
||||
my_field = CharMaxlength25Field()
|
||||
|
||||
The better way of doing this would be to make the parameter specifiable at run
|
||||
time -- i.e., when the class is instantiated. To do that, just implement
|
||||
``__init__()``, like so::
|
||||
|
||||
# This is a much more flexible example.
|
||||
class BetterCharField(models.Field):
|
||||
def __init__(self, max_length, *args, **kwargs):
|
||||
self.max_length = max_length
|
||||
super(BetterCharField, self).__init__(*args, **kwargs)
|
||||
|
||||
def db_type(self):
|
||||
return 'char(%s)' % self.max_length
|
||||
|
||||
# In the model:
|
||||
class MyModel(models.Model):
|
||||
# ...
|
||||
my_field = BetterCharField(25)
|
||||
|
||||
Note that if you implement ``__init__()`` on a ``Field`` subclass, it's
|
||||
important to call ``Field.__init__()`` -- i.e., the parent class'
|
||||
``__init__()`` method.
|
||||
|
||||
Meta options
|
||||
============
|
||||
@@ -987,7 +1107,7 @@ Meta options
|
||||
Give your model metadata by using an inner ``class Meta``, like so::
|
||||
|
||||
class Foo(models.Model):
|
||||
bar = models.CharField(maxlength=30)
|
||||
bar = models.CharField(max_length=30)
|
||||
|
||||
class Meta:
|
||||
# ...
|
||||
@@ -1077,7 +1197,7 @@ See `Specifying ordering`_ for more examples.
|
||||
Note that, regardless of how many fields are in ``ordering``, the admin
|
||||
site uses only the first field.
|
||||
|
||||
.. _Specifying ordering: http://www.djangoproject.com/documentation/models/ordering/
|
||||
.. _Specifying ordering: ../models/ordering/
|
||||
|
||||
``permissions``
|
||||
---------------
|
||||
@@ -1161,8 +1281,8 @@ If you want your model to be visible to Django's admin site, give your model an
|
||||
inner ``"class Admin"``, like so::
|
||||
|
||||
class Person(models.Model):
|
||||
first_name = models.CharField(maxlength=30)
|
||||
last_name = models.CharField(maxlength=30)
|
||||
first_name = models.CharField(max_length=30)
|
||||
last_name = models.CharField(max_length=30)
|
||||
|
||||
class Admin:
|
||||
# Admin options go here
|
||||
@@ -1302,8 +1422,8 @@ that displays the ``__str__()`` representation of each object.
|
||||
|
||||
A few special cases to note about ``list_display``:
|
||||
|
||||
* If the field is a ``ForeignKey``, Django will display the ``__str__()``
|
||||
of the related object.
|
||||
* If the field is a ``ForeignKey``, Django will display the
|
||||
``__unicode__()`` of the related object.
|
||||
|
||||
* ``ManyToManyField`` fields aren't supported, because that would entail
|
||||
executing a separate SQL statement for each row in the table. If you
|
||||
@@ -1321,7 +1441,7 @@ A few special cases to note about ``list_display``:
|
||||
Here's a full example model::
|
||||
|
||||
class Person(models.Model):
|
||||
name = models.CharField(maxlength=50)
|
||||
name = models.CharField(max_length=50)
|
||||
birthday = models.DateField()
|
||||
|
||||
class Admin:
|
||||
@@ -1338,9 +1458,9 @@ A few special cases to note about ``list_display``:
|
||||
Here's a full example model::
|
||||
|
||||
class Person(models.Model):
|
||||
first_name = models.CharField(maxlength=50)
|
||||
last_name = models.CharField(maxlength=50)
|
||||
color_code = models.CharField(maxlength=6)
|
||||
first_name = models.CharField(max_length=50)
|
||||
last_name = models.CharField(max_length=50)
|
||||
color_code = models.CharField(max_length=6)
|
||||
|
||||
class Admin:
|
||||
list_display = ('first_name', 'last_name', 'colored_name')
|
||||
@@ -1356,7 +1476,7 @@ A few special cases to note about ``list_display``:
|
||||
Here's a full example model::
|
||||
|
||||
class Person(models.Model):
|
||||
first_name = models.CharField(maxlength=50)
|
||||
first_name = models.CharField(max_length=50)
|
||||
birthday = models.DateField()
|
||||
|
||||
class Admin:
|
||||
@@ -1367,10 +1487,11 @@ A few special cases to note about ``list_display``:
|
||||
born_in_fifties.boolean = True
|
||||
|
||||
|
||||
* The ``__str__()`` method is just as valid in ``list_display`` as any
|
||||
other model method, so it's perfectly OK to do this::
|
||||
* The ``__str__()`` and ``__unicode__()`` methods are just as valid in
|
||||
``list_display`` as any other model method, so it's perfectly OK to do
|
||||
this::
|
||||
|
||||
list_display = ('__str__', 'some_other_field')
|
||||
list_display = ('__unicode__', 'some_other_field')
|
||||
|
||||
* Usually, elements of ``list_display`` that aren't actual database fields
|
||||
can't be used in sorting (because Django does all the sorting at the
|
||||
@@ -1383,8 +1504,8 @@ A few special cases to note about ``list_display``:
|
||||
For example::
|
||||
|
||||
class Person(models.Model):
|
||||
first_name = models.CharField(maxlength=50)
|
||||
color_code = models.CharField(maxlength=6)
|
||||
first_name = models.CharField(max_length=50)
|
||||
color_code = models.CharField(max_length=6)
|
||||
|
||||
class Admin:
|
||||
list_display = ('first_name', 'colored_first_name')
|
||||
@@ -1552,7 +1673,7 @@ with an operator:
|
||||
AND (first_name ILIKE 'lennon' OR last_name ILIKE 'lennon')
|
||||
|
||||
Note that the query input is split by spaces, so, following this example,
|
||||
it's not currently not possible to search for all records in which
|
||||
it's currently not possible to search for all records in which
|
||||
``first_name`` is exactly ``'john winston'`` (containing a space).
|
||||
|
||||
``@``
|
||||
@@ -1634,13 +1755,13 @@ returns a list of all ``OpinionPoll`` objects, each with an extra
|
||||
return result_list
|
||||
|
||||
class OpinionPoll(models.Model):
|
||||
question = models.CharField(maxlength=200)
|
||||
question = models.CharField(max_length=200)
|
||||
poll_date = models.DateField()
|
||||
objects = PollManager()
|
||||
|
||||
class Response(models.Model):
|
||||
poll = models.ForeignKey(Poll)
|
||||
person_name = models.CharField(maxlength=50)
|
||||
person_name = models.CharField(max_length=50)
|
||||
response = models.TextField()
|
||||
|
||||
With this example, you'd use ``OpinionPoll.objects.with_counts()`` to return
|
||||
@@ -1656,8 +1777,8 @@ A ``Manager``'s base ``QuerySet`` returns all objects in the system. For
|
||||
example, using this model::
|
||||
|
||||
class Book(models.Model):
|
||||
title = models.CharField(maxlength=100)
|
||||
author = models.CharField(maxlength=50)
|
||||
title = models.CharField(max_length=100)
|
||||
author = models.CharField(max_length=50)
|
||||
|
||||
...the statement ``Book.objects.all()`` will return all books in the database.
|
||||
|
||||
@@ -1675,8 +1796,8 @@ all objects, and one that returns only the books by Roald Dahl::
|
||||
|
||||
# Then hook it into the Book model explicitly.
|
||||
class Book(models.Model):
|
||||
title = models.CharField(maxlength=100)
|
||||
author = models.CharField(maxlength=50)
|
||||
title = models.CharField(max_length=100)
|
||||
author = models.CharField(max_length=50)
|
||||
|
||||
objects = models.Manager() # The default manager.
|
||||
dahl_objects = DahlBookManager() # The Dahl-specific manager.
|
||||
@@ -1709,9 +1830,9 @@ For example::
|
||||
return super(FemaleManager, self).get_query_set().filter(sex='F')
|
||||
|
||||
class Person(models.Model):
|
||||
first_name = models.CharField(maxlength=50)
|
||||
last_name = models.CharField(maxlength=50)
|
||||
sex = models.CharField(maxlength=1, choices=(('M', 'Male'), ('F', 'Female')))
|
||||
first_name = models.CharField(max_length=50)
|
||||
last_name = models.CharField(max_length=50)
|
||||
sex = models.CharField(max_length=1, choices=(('M', 'Male'), ('F', 'Female')))
|
||||
people = models.Manager()
|
||||
men = MaleManager()
|
||||
women = FemaleManager()
|
||||
@@ -1741,11 +1862,11 @@ model.
|
||||
For example, this model has a few custom methods::
|
||||
|
||||
class Person(models.Model):
|
||||
first_name = models.CharField(maxlength=50)
|
||||
last_name = models.CharField(maxlength=50)
|
||||
first_name = models.CharField(max_length=50)
|
||||
last_name = models.CharField(max_length=50)
|
||||
birth_date = models.DateField()
|
||||
address = models.CharField(maxlength=100)
|
||||
city = models.CharField(maxlength=50)
|
||||
address = models.CharField(max_length=100)
|
||||
city = models.CharField(max_length=50)
|
||||
state = models.USStateField() # Yes, this is America-centric...
|
||||
|
||||
def baby_boomer_status(self):
|
||||
@@ -1776,20 +1897,47 @@ A few object methods have special meaning:
|
||||
-----------
|
||||
|
||||
``__str__()`` is a Python "magic method" that defines what should be returned
|
||||
if you call ``str()`` on the object. Django uses ``str(obj)`` in a number of
|
||||
places, most notably as the value displayed to render an object in the Django
|
||||
admin site and as the value inserted into a template when it displays an
|
||||
object. Thus, you should always return a nice, human-readable string for the
|
||||
object's ``__str__``. Although this isn't required, it's strongly encouraged.
|
||||
if you call ``str()`` on the object. Django uses ``str(obj)`` (or the related
|
||||
function, ``unicode(obj)`` -- see below) in a number of places, most notably
|
||||
as the value displayed to render an object in the Django admin site and as the
|
||||
value inserted into a template when it displays an object. Thus, you should
|
||||
always return a nice, human-readable string for the object's ``__str__``.
|
||||
Although this isn't required, it's strongly encouraged (see the description of
|
||||
``__unicode__``, below, before putting ``_str__`` methods everywhere).
|
||||
|
||||
For example::
|
||||
|
||||
class Person(models.Model):
|
||||
first_name = models.CharField(maxlength=50)
|
||||
last_name = models.CharField(maxlength=50)
|
||||
first_name = models.CharField(max_length=50)
|
||||
last_name = models.CharField(max_length=50)
|
||||
|
||||
def __str__(self):
|
||||
return '%s %s' % (self.first_name, self.last_name)
|
||||
# Note use of django.utils.encoding.smart_str() here because
|
||||
# first_name and last_name will be unicode strings.
|
||||
return smart_str('%s %s' % (self.first_name, self.last_name))
|
||||
|
||||
``__unicode__``
|
||||
---------------
|
||||
|
||||
The ``__unicode__()`` method is called whenever you call ``unicode()`` on an
|
||||
object. Since Django's database backends will return Unicode strings in your
|
||||
model's attributes, you would normally want to write a ``__unicode__()``
|
||||
method for your model. The example in the previous section could be written
|
||||
more simply as::
|
||||
|
||||
class Person(models.Model):
|
||||
first_name = models.CharField(max_length=50)
|
||||
last_name = models.CharField(max_length=50)
|
||||
|
||||
def __unicode__(self):
|
||||
return u'%s %s' % (self.first_name, self.last_name)
|
||||
|
||||
If you define a ``__unicode__()`` method on your model and not a ``__str__()``
|
||||
method, Django will automatically provide you with a ``__str__()`` that calls
|
||||
``__unicode()__`` and then converts the result correctly to a UTF-8 encoded
|
||||
string object. This is recommended development practice: define only
|
||||
``__unicode__()`` and let Django take care of the conversion to string objects
|
||||
when required.
|
||||
|
||||
``get_absolute_url``
|
||||
--------------------
|
||||
@@ -1805,10 +1953,12 @@ Django uses this in its admin interface. If an object defines
|
||||
link that will jump you directly to the object's public view, according to
|
||||
``get_absolute_url()``.
|
||||
|
||||
Also, a couple of other bits of Django, such as the syndication-feed framework,
|
||||
Also, a couple of other bits of Django, such as the `syndication feed framework`_,
|
||||
use ``get_absolute_url()`` as a convenience to reward people who've defined the
|
||||
method.
|
||||
|
||||
.. _syndication feed framework: ../syndication_feeds/
|
||||
|
||||
It's good practice to use ``get_absolute_url()`` in templates, instead of
|
||||
hard-coding your objects' URLs. For example, this template code is bad::
|
||||
|
||||
@@ -1823,7 +1973,9 @@ But this template code is good::
|
||||
characters (required by the URI spec, `RFC 2396`_) that have been
|
||||
URL-encoded, if necessary. Code and templates using ``get_absolute_url()``
|
||||
should be able to use the result directly without needing to do any
|
||||
further processing.
|
||||
further processing. You may wish to use the
|
||||
``django.utils.encoding.iri_to_uri()`` function to help with this if you
|
||||
are using unicode strings a lot.
|
||||
|
||||
.. _RFC 2396: http://www.ietf.org/rfc/rfc2396.txt
|
||||
|
||||
@@ -1841,7 +1993,7 @@ works out the correct full URL path using the URLconf, substituting the
|
||||
parameters you have given into the URL. For example, if your URLconf
|
||||
contained a line such as::
|
||||
|
||||
(r'^/people/(\d+)/$', 'people.views.details'),
|
||||
(r'^people/(\d+)/$', 'people.views.details'),
|
||||
|
||||
...your model could have a ``get_absolute_url`` method that looked like this::
|
||||
|
||||
@@ -1864,8 +2016,8 @@ Similarly, if you had a URLconf entry that looked like::
|
||||
'day': self.created.day})
|
||||
get_absolute_url = permalink(get_absolute_url)
|
||||
|
||||
Notice that we specify an empty sequence for the second argument in this case,
|
||||
because we only want to pass keyword arguments, not named arguments.
|
||||
Notice that we specify an empty sequence for the second parameter in this case,
|
||||
because we only want to pass keyword parameters, not positional ones.
|
||||
|
||||
In this way, you're tying the model's absolute URL to the view that is used
|
||||
to display it, without repeating the URL information anywhere. You can still
|
||||
@@ -1917,7 +2069,7 @@ A classic use-case for overriding the built-in methods is if you want something
|
||||
to happen whenever you save an object. For example::
|
||||
|
||||
class Blog(models.Model):
|
||||
name = models.CharField(maxlength=100)
|
||||
name = models.CharField(max_length=100)
|
||||
tagline = models.TextField()
|
||||
|
||||
def save(self):
|
||||
@@ -1928,7 +2080,7 @@ to happen whenever you save an object. For example::
|
||||
You can also prevent saving::
|
||||
|
||||
class Blog(models.Model):
|
||||
name = models.CharField(maxlength=100)
|
||||
name = models.CharField(max_length=100)
|
||||
tagline = models.TextField()
|
||||
|
||||
def save(self):
|
||||
|
||||
@@ -50,8 +50,8 @@ directive. The latter is used for pointing at places on your filesystem,
|
||||
whereas ``<Location>`` points at places in the URL structure of a Web site.
|
||||
``<Directory>`` would be meaningless here.
|
||||
|
||||
Also, if you've manually altered your ``PYTHONPATH`` to put your Django project
|
||||
on it, you'll need to tell mod_python:
|
||||
Also, if your Django project is not on the default ``PYTHONPATH`` for your
|
||||
computer, you'll have to tell mod_python where your project can be found:
|
||||
|
||||
.. parsed-literal::
|
||||
|
||||
@@ -63,6 +63,30 @@ on it, you'll need to tell mod_python:
|
||||
**PythonPath "['/path/to/project'] + sys.path"**
|
||||
</Location>
|
||||
|
||||
The value you use for ``PythonPath`` should include the parent directories of
|
||||
all the modules you are going to import in your application. It should also
|
||||
include the parent directory of the ``DJANGO_SETTINGS_MODULE`` location. This
|
||||
is exactly the same situation as setting the Python path for interactive
|
||||
usage. Whenever you try to import something, Python will run through all the
|
||||
directories in ``sys.path`` in turn, from first to last, and try to import
|
||||
from each directory until one succeeds.
|
||||
|
||||
An example might make this clearer. Suppose
|
||||
you have some applications under ``/usr/local/django-apps/`` (for example,
|
||||
``/usr/local/django-apps/weblog/`` and so forth), your settings file is at
|
||||
``/var/www/mysite/settings.py`` and you have specified
|
||||
``DJANGO_SETTINGS_MODULE`` as in the above example. In this case, you would
|
||||
need to write your ``PythonPath`` directive as::
|
||||
|
||||
PythonPath "['/var/production/django-apps/', '/var/www'] + sys.path"
|
||||
|
||||
With this path, ``import weblog`` and ``import mysite.settings`` will both
|
||||
work. If you had ``import blogroll`` in your code somewhere and ``blogroll``
|
||||
lived under the ``weblog/`` directory, you would *also* need to add
|
||||
``/var/production/django-apps/weblog/`` to your ``PythonPath``. Remember: the
|
||||
**parent directories** of anything you import directly must be on the Python
|
||||
path.
|
||||
|
||||
.. caution::
|
||||
|
||||
If you're using Windows, remember that the path will contain backslashes.
|
||||
|
||||
@@ -641,7 +641,7 @@ the "Outputting forms as HTML" section above.
|
||||
The simplest way to display a form's HTML is to use the variable on its own,
|
||||
like this::
|
||||
|
||||
<form method="post">
|
||||
<form method="post" action="">
|
||||
<table>{{ form }}</table>
|
||||
<input type="submit" />
|
||||
</form>
|
||||
@@ -653,7 +653,7 @@ class' ``__str__()`` method calls its ``as_table()`` method.
|
||||
|
||||
The following is equivalent but a bit more explicit::
|
||||
|
||||
<form method="post">
|
||||
<form method="post" action="">
|
||||
<table>{{ form.as_table }}</table>
|
||||
<input type="submit" />
|
||||
</form>
|
||||
@@ -675,10 +675,10 @@ individual fields for complete template control over the form's design.
|
||||
The easiest way is to iterate over the form's fields, with
|
||||
``{% for field in form %}``. For example::
|
||||
|
||||
<form method="post">
|
||||
<form method="post" action="">
|
||||
<dl>
|
||||
{% for field in form %}
|
||||
<dt>{{ field.label }}</dt>
|
||||
<dt>{{ field.label_tag }}</dt>
|
||||
<dd>{{ field }}</dd>
|
||||
{% if field.help_text %}<dd>{{ field.help_text }}</dd>{% endif %}
|
||||
{% if field.errors %}<dd class="myerrors">{{ field.errors }}</dd>{% endif %}
|
||||
@@ -696,13 +696,13 @@ Alternatively, you can arrange the form's fields explicitly, by name. Do that
|
||||
by accessing ``{{ form.fieldname }}``, where ``fieldname`` is the field's name.
|
||||
For example::
|
||||
|
||||
<form method="post">
|
||||
<form method="post" action="">
|
||||
<ul class="myformclass">
|
||||
<li>{{ form.sender.label }} {{ form.sender }}</li>
|
||||
<li>{{ form.sender.label_tag }} {{ form.sender }}</li>
|
||||
<li class="helptext">{{ form.sender.help_text }}</li>
|
||||
{% if form.sender.errors %}<ul class="errorlist">{{ form.sender.errors }}</ul>{% endif %}
|
||||
|
||||
<li>{{ form.subject.label }} {{ form.subject }}</li>
|
||||
<li>{{ form.subject.label_tag }} {{ form.subject }}</li>
|
||||
<li class="helptext">{{ form.subject.help_text }}</li>
|
||||
{% if form.subject.errors %}<ul class="errorlist">{{ form.subject.errors }}</ul>{% endif %}
|
||||
|
||||
@@ -710,6 +710,49 @@ For example::
|
||||
</ul>
|
||||
</form>
|
||||
|
||||
Binding uploaded files to a form
|
||||
--------------------------------
|
||||
|
||||
**New in Django development version**
|
||||
|
||||
Dealing with forms that have ``FileField`` and ``ImageField`` fields
|
||||
is a little more complicated than a normal form.
|
||||
|
||||
Firstly, in order to upload files, you'll need to make sure that your
|
||||
``<form>`` element correctly defines the ``enctype`` as
|
||||
``"multipart/form-data"``::
|
||||
|
||||
<form enctype="multipart/form-data" method="post" action="/foo/">
|
||||
|
||||
Secondly, when you use the form, you need to bind the file data. File
|
||||
data is handled separately to normal form data, so when your form
|
||||
contains a ``FileField`` and ``ImageField``, you will need to specify
|
||||
a second argument when you bind your form. So if we extend our
|
||||
ContactForm to include an ``ImageField`` called ``mugshot``, we
|
||||
need to bind the file data containing the mugshot image::
|
||||
|
||||
# Bound form with an image field
|
||||
>>> data = {'subject': 'hello',
|
||||
... 'message': 'Hi there',
|
||||
... 'sender': 'foo@example.com',
|
||||
... 'cc_myself': True}
|
||||
>>> file_data = {'mugshot': {'filename':'face.jpg'
|
||||
... 'content': <file data>}}
|
||||
>>> f = ContactFormWithMugshot(data, file_data)
|
||||
|
||||
In practice, you will usually specify ``request.FILES`` as the source
|
||||
of file data (just like you use ``request.POST`` as the source of
|
||||
form data)::
|
||||
|
||||
# Bound form with an image field, data from the request
|
||||
>>> f = ContactFormWithMugshot(request.POST, request.FILES)
|
||||
|
||||
Constructing an unbound form is the same as always -- just omit both
|
||||
form data *and* file data::
|
||||
|
||||
# Unbound form with a image field
|
||||
>>> f = ContactFormWithMugshot()
|
||||
|
||||
Subclassing forms
|
||||
-----------------
|
||||
|
||||
@@ -919,7 +962,7 @@ validation if a particular field's value is not given. ``initial`` values are
|
||||
~~~~~~~~~~
|
||||
|
||||
The ``widget`` argument lets you specify a ``Widget`` class to use when
|
||||
rendering this ``Field``. See "Widgets" below for more information.
|
||||
rendering this ``Field``. See "Widgets"_ below for more information.
|
||||
|
||||
``help_text``
|
||||
~~~~~~~~~~~~~
|
||||
@@ -1086,6 +1129,24 @@ If no ``input_formats`` argument is provided, the default input formats are::
|
||||
'%m/%d/%y %H:%M', # '10/25/06 14:30'
|
||||
'%m/%d/%y', # '10/25/06'
|
||||
|
||||
``DecimalField``
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
**New in Django development version**
|
||||
|
||||
* Default widget: ``TextInput``
|
||||
* Empty value: ``None``
|
||||
* Normalizes to: A Python ``decimal``.
|
||||
* Validates that the given value is a decimal. Leading and trailing
|
||||
whitespace is ignored.
|
||||
|
||||
Takes four optional arguments: ``max_value``, ``min_value``, ``max_digits``,
|
||||
and ``decimal_places``. The first two define the limits for the fields value.
|
||||
``max_digits`` is the maximum number of digits (those before the decimal
|
||||
point plus those after the decimal point, with leading zeros stripped)
|
||||
permitted in the value, whilst ``decimal_places`` is the maximum number of
|
||||
decimal places permitted.
|
||||
|
||||
``EmailField``
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
@@ -1099,6 +1160,54 @@ Has two optional arguments for validation, ``max_length`` and ``min_length``.
|
||||
If provided, these arguments ensure that the string is at most or at least the
|
||||
given length.
|
||||
|
||||
``FileField``
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
**New in Django development version**
|
||||
|
||||
* Default widget: ``FileInput``
|
||||
* Empty value: ``None``
|
||||
* Normalizes to: An ``UploadedFile`` object that wraps the file content
|
||||
and file name into a single object.
|
||||
* Validates that non-empty file data has been bound to the form.
|
||||
|
||||
An ``UploadedFile`` object has two attributes:
|
||||
|
||||
====================== =====================================================
|
||||
Argument Description
|
||||
====================== =====================================================
|
||||
``filename`` The name of the file, provided by the uploading
|
||||
client.
|
||||
``content`` The array of bytes comprising the file content.
|
||||
====================== =====================================================
|
||||
|
||||
The string representation of an ``UploadedFile`` is the same as the filename
|
||||
attribute.
|
||||
|
||||
When you use a ``FileField`` on a form, you must also remember to
|
||||
`bind the file data to the form`_.
|
||||
|
||||
.. _`bind the file data to the form`: `Binding uploaded files to a form`_
|
||||
|
||||
``ImageField``
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
**New in Django development version**
|
||||
|
||||
* Default widget: ``FileInput``
|
||||
* Empty value: ``None``
|
||||
* Normalizes to: An ``UploadedFile`` object that wraps the file content
|
||||
and file name into a single object.
|
||||
* Validates that file data has been bound to the form, and that the
|
||||
file is of an image format understood by PIL.
|
||||
|
||||
Using an ImageField requires that the `Python Imaging Library`_ is installed.
|
||||
|
||||
When you use a ``FileField`` on a form, you must also remember to
|
||||
`bind the file data to the form`_.
|
||||
|
||||
.. _Python Imaging Library: http://www.pythonware.com/products/pil/
|
||||
|
||||
``IntegerField``
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
@@ -1108,6 +1217,9 @@ given length.
|
||||
* Validates that the given value is an integer. Leading and trailing
|
||||
whitespace is allowed, as in Python's ``int()`` function.
|
||||
|
||||
Takes two optional arguments for validation, ``max_value`` and ``min_value``.
|
||||
These control the range of values permitted in the field.
|
||||
|
||||
``MultipleChoiceField``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@@ -1222,7 +1334,7 @@ Custom form and field validation
|
||||
|
||||
Form validation happens when the data is cleaned. If you want to customise
|
||||
this process, there are various places you can change, each one serving a
|
||||
different purpose. Thee types of cleaning methods are run during form
|
||||
different purpose. Three types of cleaning methods are run during form
|
||||
processing. These are normally executed when you call the ``is_valid()``
|
||||
method on a form. There are other things that can trigger cleaning and
|
||||
validation (accessing the ``errors`` attribute or calling ``full_clean()``
|
||||
@@ -1307,12 +1419,12 @@ keep it simple and assume e-mail validation is contained in a function called
|
||||
|
||||
class MultiEmailField(forms.Field):
|
||||
def clean(self, value):
|
||||
if not value:
|
||||
raise forms.ValidationError('Enter at least one e-mail address.')
|
||||
emails = value.split(',')
|
||||
for email in emails:
|
||||
if not is_valid_email(email):
|
||||
raise forms.ValidationError('%s is not a valid e-mail address.' % email)
|
||||
if not emails:
|
||||
raise forms.ValidationError('Enter at least one e-mail address.')
|
||||
return emails
|
||||
|
||||
Let's alter the ongoing ``ContactForm`` example to demonstrate how you'd use
|
||||
@@ -1325,6 +1437,156 @@ like so::
|
||||
senders = MultiEmailField()
|
||||
cc_myself = forms.BooleanField()
|
||||
|
||||
Widgets
|
||||
=======
|
||||
|
||||
A widget is Django's representation of a HTML input element. The widget
|
||||
handles the rendering of the HTML, and the extraction of data from a GET/POST
|
||||
dictionary that corresponds to the widget.
|
||||
|
||||
Django provides a representation of all the basic HTML widgets, plus some
|
||||
commonly used groups of widgets:
|
||||
|
||||
============================ ===========================================
|
||||
Widget HTML Equivalent
|
||||
============================ ===========================================
|
||||
``TextInput`` ``<input type='text' ...``
|
||||
``PasswordInput`` ``<input type='password' ...``
|
||||
``HiddenInput`` ``<input type='hidden' ...``
|
||||
``MultipleHiddenInput`` Multiple ``<input type='hidden' ...``
|
||||
instances.
|
||||
``FileInput`` ``<input type='file' ...``
|
||||
``Textarea`` ``<textarea>...</textarea>``
|
||||
``CheckboxInput`` ``<input type='checkbox' ...``
|
||||
``Select`` ``<select><option ...``
|
||||
``NullBooleanSelect`` Select widget with options 'Unknown',
|
||||
'Yes' and 'No'
|
||||
``SelectMultiple`` ``<select multiple='multiple'><option ...``
|
||||
``RadioSelect`` ``<ul><li><input type='radio' ...``
|
||||
``CheckboxSelectMultiple`` ``<ul><li><input type='checkbox' ...``
|
||||
``MultiWidget`` Wrapper around multiple other widgets
|
||||
``SplitDateTimeWidget`` Wrapper around two ``TextInput`` widgets:
|
||||
one for the Date, and one for the Time.
|
||||
============================ ===========================================
|
||||
|
||||
Specifying widgets
|
||||
------------------
|
||||
|
||||
Whenever you specify a field on a form, Django will use a default widget
|
||||
that is appropriate to the type of data that is to be displayed. To find
|
||||
which widget is used on which field, see the documentation for the
|
||||
built-in Field classes.
|
||||
|
||||
However, if you want to use a different widget for a field, you can -
|
||||
just use the 'widget' argument on the field definition. For example::
|
||||
|
||||
class CommentForm(forms.Form):
|
||||
name = forms.CharField()
|
||||
url = forms.URLField()
|
||||
comment = forms.CharField(widget=forms.Textarea)
|
||||
|
||||
This would specify a form with a comment that uses a larger Textarea widget,
|
||||
rather than the default TextInput widget.
|
||||
|
||||
Customizing widget instances
|
||||
----------------------------
|
||||
|
||||
When Django renders a widget as HTML, it only renders the bare minimum
|
||||
HTML - Django doesn't add a class definition, or any other widget-specific
|
||||
attributes. This means that all 'TextInput' widgets will appear the same
|
||||
on your web page.
|
||||
|
||||
If you want to make one widget look different to another, you need to
|
||||
specify additional attributes for each widget. When you specify a
|
||||
widget, you can provide a list of attributes that will be added to the
|
||||
rendered HTML for the widget.
|
||||
|
||||
For example, take the following simple form::
|
||||
|
||||
class CommentForm(forms.Form):
|
||||
name = forms.CharField()
|
||||
url = forms.URLField()
|
||||
comment = forms.CharField()
|
||||
|
||||
This form will include three default TextInput widgets, with default rendering -
|
||||
no CSS class, no extra attributes. This means that the inputs boxes provided for
|
||||
each widget will be rendered exactly the same::
|
||||
|
||||
>>> f = CommentForm(auto_id=False)
|
||||
>>> f.as_table()
|
||||
<tr><th>Name:</th><td><input type="text" name="name" /></td></tr>
|
||||
<tr><th>Url:</th><td><input type="text" name="url"/></td></tr>
|
||||
<tr><th>Comment:</th><td><input type="text" name="comment" /></td></tr>
|
||||
|
||||
On a real web page, you probably don't want every widget to look the same. You
|
||||
might want a larger input element for the comment, and you might want the
|
||||
'name' widget to have some special CSS class. To do this, you specify a
|
||||
custom widget for your fields, and specify some attributes to use
|
||||
when rendering those widgets::
|
||||
|
||||
class CommentForm(forms.Form):
|
||||
name = forms.CharField(
|
||||
widget=forms.TextInput(attrs={'class':'special'}))
|
||||
url = forms.URLField()
|
||||
comment = forms.CharField(
|
||||
widget=forms.TextInput(attrs={'size':'40'}))
|
||||
|
||||
Django will then include the extra attributes in the rendered output::
|
||||
|
||||
>>> f = CommentForm(auto_id=False)
|
||||
>>> f.as_table()
|
||||
<tr><th>Name:</th><td><input type="text" name="name" class="special"/></td></tr>
|
||||
<tr><th>Url:</th><td><input type="text" name="url"/></td></tr>
|
||||
<tr><th>Comment:</th><td><input type="text" name="comment" size="40"/></td></tr>
|
||||
|
||||
Custom Widgets
|
||||
--------------
|
||||
|
||||
When you start to write a lot of forms, you will probably find that you will
|
||||
reuse certain sets of widget attributes over and over again. Rather than
|
||||
repeat these attribute definitions every time you need them, Django allows
|
||||
you to capture those definitions as a custom widget.
|
||||
|
||||
For example, if you find that you are including a lot of comment fields on forms,
|
||||
you could capture the idea of a ``TextInput`` with a specific ``size`` attribute
|
||||
as a custom extension to the ``TextInput`` widget::
|
||||
|
||||
class CommentWidget(forms.TextInput):
|
||||
def __init__(self, *args, **kwargs):
|
||||
kwargs.setdefault('attrs',{}).update({'size': '40'})
|
||||
super(forms.TextInput, self).__init__(*args, **kwargs)
|
||||
|
||||
Then you can use this widget in your forms::
|
||||
|
||||
class CommentForm(forms.Form):
|
||||
name = forms.CharField()
|
||||
url = forms.URLField()
|
||||
comment = forms.CharField(widget=CommentWidget)
|
||||
|
||||
You can even customize your custom widget, in the same way as you would
|
||||
any other widget. Adding a once-off class to your ``CommentWidget`` is as
|
||||
simple as adding an attribute definition::
|
||||
|
||||
class CommentForm(forms.Form):
|
||||
name = forms.CharField(max_length=20)
|
||||
url = forms.URLField()
|
||||
comment = forms.CharField(
|
||||
widget=CommentWidget(attrs={'class': 'special'}))
|
||||
|
||||
Django also makes it easy to specify a custom field type that uses your custom
|
||||
widget. For example, you could define a customized field type for comments
|
||||
by defining::
|
||||
|
||||
class CommentInput(forms.CharField):
|
||||
widget = CommentWidget
|
||||
|
||||
You can then use this field whenever you have a form that requires a comment::
|
||||
|
||||
class CommentForm(forms.Form):
|
||||
name = forms.CharField()
|
||||
url = forms.URLField()
|
||||
comment = CommentInput()
|
||||
|
||||
Generating forms for models
|
||||
===========================
|
||||
|
||||
@@ -1372,17 +1634,17 @@ the full list of conversions:
|
||||
``AutoField`` Not represented in the form
|
||||
``BooleanField`` ``BooleanField``
|
||||
``CharField`` ``CharField`` with ``max_length`` set to
|
||||
the model field's ``maxlength``
|
||||
the model field's ``max_length``
|
||||
``CommaSeparatedIntegerField`` ``CharField``
|
||||
``DateField`` ``DateField``
|
||||
``DateTimeField`` ``DateTimeField``
|
||||
``DecimalField`` ``DecimalField``
|
||||
``EmailField`` ``EmailField``
|
||||
``FileField`` ``CharField``
|
||||
``FileField`` ``FileField``
|
||||
``FilePathField`` ``CharField``
|
||||
``FloatField`` ``FloatField``
|
||||
``ForeignKey`` ``ModelChoiceField`` (see below)
|
||||
``ImageField`` ``CharField``
|
||||
``ImageField`` ``ImageField``
|
||||
``IntegerField`` ``IntegerField``
|
||||
``IPAddressField`` ``CharField``
|
||||
``ManyToManyField`` ``ModelMultipleChoiceField`` (see
|
||||
@@ -1452,15 +1714,15 @@ Consider this set of models::
|
||||
)
|
||||
|
||||
class Author(models.Model):
|
||||
name = models.CharField(maxlength=100)
|
||||
title = models.CharField(maxlength=3, choices=TITLE_CHOICES)
|
||||
name = models.CharField(max_length=100)
|
||||
title = models.CharField(max_length=3, choices=TITLE_CHOICES)
|
||||
birth_date = models.DateField(blank=True, null=True)
|
||||
|
||||
def __str__(self):
|
||||
def __unicode__(self):
|
||||
return self.name
|
||||
|
||||
class Book(models.Model):
|
||||
name = models.CharField(maxlength=100)
|
||||
name = models.CharField(max_length=100)
|
||||
authors = models.ManyToManyField(Author)
|
||||
|
||||
With these models, a call to ``form_for_model(Author)`` would return a ``Form``
|
||||
@@ -1495,6 +1757,51 @@ example::
|
||||
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
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@@ -1624,6 +1931,42 @@ 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()
|
||||
|
||||
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()``?
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
||||
@@ -25,18 +25,18 @@ far, it's been solving two years' worth of database-schema problems. Here's a
|
||||
quick example::
|
||||
|
||||
class Reporter(models.Model):
|
||||
full_name = models.CharField(maxlength=70)
|
||||
full_name = models.CharField(max_length=70)
|
||||
|
||||
def __str__(self):
|
||||
def __unicode__(self):
|
||||
return self.full_name
|
||||
|
||||
class Article(models.Model):
|
||||
pub_date = models.DateTimeField()
|
||||
headline = models.CharField(maxlength=200)
|
||||
headline = models.CharField(max_length=200)
|
||||
article = models.TextField()
|
||||
reporter = models.ForeignKey(Reporter)
|
||||
|
||||
def __str__(self):
|
||||
def __unicode__(self):
|
||||
return self.headline
|
||||
|
||||
Install it
|
||||
@@ -54,7 +54,7 @@ Enjoy the free API
|
||||
==================
|
||||
|
||||
With that, you've got a free, and rich, Python API to access your data. The API
|
||||
is created on the fly: No code generation necessary::
|
||||
is created on the fly, no code generation necessary::
|
||||
|
||||
>>> from mysite.models import Reporter, Article
|
||||
|
||||
@@ -124,7 +124,7 @@ is created on the fly: No code generation necessary::
|
||||
# Delete an object with delete().
|
||||
>>> r.delete()
|
||||
|
||||
A dynamic admin interface: It's not just scaffolding -- it's the whole house
|
||||
A dynamic admin interface: it's not just scaffolding -- it's the whole house
|
||||
============================================================================
|
||||
|
||||
Once your models are defined, Django can automatically create a professional,
|
||||
@@ -134,7 +134,7 @@ your model classes::
|
||||
|
||||
class Article(models.Model):
|
||||
pub_date = models.DateTimeField()
|
||||
headline = models.CharField(maxlength=200)
|
||||
headline = models.CharField(max_length=200)
|
||||
article = models.TextField()
|
||||
reporter = models.ForeignKey(Reporter)
|
||||
class Admin: pass
|
||||
@@ -165,9 +165,9 @@ example above::
|
||||
from django.conf.urls.defaults import *
|
||||
|
||||
urlpatterns = patterns('',
|
||||
(r'^/articles/(\d{4})/$', 'mysite.views.year_archive'),
|
||||
(r'^/articles/(\d{4})/(\d{2})/$', 'mysite.views.month_archive'),
|
||||
(r'^/articles/(\d{4})/(\d{2})/(\d+)/$', 'mysite.views.article_detail'),
|
||||
(r'^articles/(\d{4})/$', 'mysite.views.year_archive'),
|
||||
(r'^articles/(\d{4})/(\d{2})/$', 'mysite.views.month_archive'),
|
||||
(r'^articles/(\d{4})/(\d{2})/(\d+)/$', 'mysite.views.article_detail'),
|
||||
)
|
||||
|
||||
The code above maps URLs, as simple regular expressions, to the location of
|
||||
@@ -250,7 +250,7 @@ Finally, Django uses the concept of "template inheritance": That's what the
|
||||
``{% extends "base.html" %}`` does. It means "First load the template called
|
||||
'base', which has defined a bunch of blocks, and fill the blocks with the
|
||||
following blocks." In short, that lets you dramatically cut down on redundancy
|
||||
in templates: Each template has to define only what's unique to that template.
|
||||
in templates: each template has to define only what's unique to that template.
|
||||
|
||||
Here's what the "base.html" template might look like::
|
||||
|
||||
@@ -288,14 +288,16 @@ This has been only a quick overview of Django's functionality. Some more useful
|
||||
features:
|
||||
|
||||
* A caching framework that integrates with memcached or other backends.
|
||||
* A syndication framework that makes creating RSS and Atom feeds as easy as
|
||||
* A `syndication framework`_ that makes creating RSS and Atom feeds as easy as
|
||||
writing a small Python class.
|
||||
* More sexy automatically-generated admin features -- this overview barely
|
||||
scratched the surface.
|
||||
|
||||
.. _syndication framework: ../syndication_feeds/
|
||||
|
||||
The next obvious steps are for you to `download Django`_, read `the tutorial`_
|
||||
and join `the community`_. Thanks for your interest!
|
||||
|
||||
.. _download Django: http://www.djangoproject.com/download/
|
||||
.. _the tutorial: http://www.djangoproject.com/documentation/tutorial01/
|
||||
.. _the tutorial: ../tutorial01/
|
||||
.. _the community: http://www.djangoproject.com/community/
|
||||
|
||||
@@ -114,7 +114,7 @@ there's a #django channel on irc.freenode.net that is regularly populated by
|
||||
Django users and developers from around the world. Friendly people are usually
|
||||
available at any hour of the day -- to help, or just to chat.
|
||||
|
||||
.. _online: http://www.djangoproject.com/documentation/
|
||||
.. _online: http://www.djangoproject.com/documentation/0.95/
|
||||
.. _Django website: http://www.djangoproject.com/
|
||||
.. _FAQ: http://www.djangoproject.com/documentation/faq/
|
||||
.. _django-users: http://groups.google.com/group/django-users
|
||||
|
||||
@@ -38,6 +38,16 @@ All attributes except ``session`` should be considered read-only.
|
||||
elif request.method == 'POST':
|
||||
do_something_else()
|
||||
|
||||
``encoding``
|
||||
**New in Django development version**
|
||||
|
||||
A string representing the current encoding used to decode form submission
|
||||
data (or ``None``, which means the ``DEFAULT_CHARSET`` setting is used).
|
||||
You can write to this attribute to change the encoding used when accessing
|
||||
the form data. Any subsequent attribute accesses (such as reading from
|
||||
``GET`` or ``POST``) will use the new ``encoding`` value. Useful if you
|
||||
know the form data is not in the ``DEFAULT_CHARSET`` encoding.
|
||||
|
||||
``GET``
|
||||
A dictionary-like object containing all given HTTP GET parameters. See the
|
||||
``QueryDict`` documentation below.
|
||||
@@ -297,7 +307,7 @@ In contrast to ``HttpRequest`` objects, which are created automatically by
|
||||
Django, ``HttpResponse`` objects are your responsibility. Each view you write
|
||||
is responsible for instantiating, populating and returning an ``HttpResponse``.
|
||||
|
||||
The ``HttpResponse`` class lives at ``django.http.HttpResponse``.
|
||||
The ``HttpResponse`` class lives in the ``django.http`` module.
|
||||
|
||||
Usage
|
||||
-----
|
||||
@@ -342,7 +352,7 @@ hard-coded strings. If you use this technique, follow these guidelines:
|
||||
Methods
|
||||
-------
|
||||
|
||||
``__init__(content='', mimetype=DEFAULT_CONTENT_TYPE)``
|
||||
``__init__(content='', mimetype=None, status=200, content_type=DEFAULT_CONTENT_TYPE)``
|
||||
Instantiates an ``HttpResponse`` object with the given page content (a
|
||||
string) and MIME type. The ``DEFAULT_CONTENT_TYPE`` is ``'text/html'``.
|
||||
|
||||
@@ -350,6 +360,16 @@ Methods
|
||||
return strings, and those strings will be joined together to form the
|
||||
content of the response.
|
||||
|
||||
``status`` is the `HTTP Status code`_ for the response.
|
||||
|
||||
**(New in Django development version)** ``content_type`` is an alias for
|
||||
``mimetype``. Historically, the parameter was only called ``mimetype``,
|
||||
but since this is actually the value included in the HTTP ``Content-Type``
|
||||
header, it can also include the character set encoding, which makes it
|
||||
more than just a MIME type specification. If ``mimetype`` is specifiedi
|
||||
(not None), that value is used. Otherwise, ``content_type`` is used. If
|
||||
neither is given, the ``DEFAULT_CONTENT_TYPE`` setting is used.
|
||||
|
||||
``__setitem__(header, value)``
|
||||
Sets the given header name to the given value. Both ``header`` and
|
||||
``value`` should be strings.
|
||||
@@ -396,6 +416,8 @@ Methods
|
||||
``write(content)``, ``flush()`` and ``tell()``
|
||||
These methods make an ``HttpResponse`` instance a file-like object.
|
||||
|
||||
.. _HTTP Status code: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10
|
||||
|
||||
HttpResponse subclasses
|
||||
-----------------------
|
||||
|
||||
|
||||
@@ -190,6 +190,12 @@ deleted::
|
||||
# request.session['foo'] instead of request.session.
|
||||
request.session['foo']['bar'] = 'baz'
|
||||
|
||||
In the last case of the above example, we can tell the session object
|
||||
explicitly that it has been modified by setting the ``modified`` attribute on
|
||||
the session object::
|
||||
|
||||
request.session.modified = True
|
||||
|
||||
To change this default behavior, set the ``SESSION_SAVE_EVERY_REQUEST`` setting
|
||||
to ``True``. If ``SESSION_SAVE_EVERY_REQUEST`` is ``True``, Django will save
|
||||
the session to the database on every single request.
|
||||
|
||||
@@ -233,12 +233,21 @@ Default: ``'simple://'``
|
||||
The cache backend to use. See the `cache docs`_.
|
||||
|
||||
CACHE_MIDDLEWARE_KEY_PREFIX
|
||||
---------------------------
|
||||
|
||||
Default: ``''`` (Empty string)
|
||||
|
||||
The cache key prefix that the cache middleware should use. See the
|
||||
`cache docs`_.
|
||||
|
||||
CACHE_MIDDLEWARE_SECONDS
|
||||
------------------------
|
||||
|
||||
Default: ``600``
|
||||
|
||||
The default number of seconds to cache a page when the caching middleware or
|
||||
``cache_page()`` decorator is used.
|
||||
|
||||
DATABASE_ENGINE
|
||||
---------------
|
||||
|
||||
@@ -442,6 +451,16 @@ Default: ``False``
|
||||
|
||||
Whether to use a TLS (secure) connection when talking to the SMTP server.
|
||||
|
||||
FILE_CHARSET
|
||||
------------
|
||||
|
||||
**New in Django development version**
|
||||
|
||||
Default: ``'utf-8'``
|
||||
|
||||
The character encoding used to decode any files read from disk. This includes
|
||||
template files and initial SQL data files.
|
||||
|
||||
FIXTURE_DIRS
|
||||
-------------
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ you express this information in Python code.
|
||||
It works much like Django's `syndication framework`_. To create a sitemap, just
|
||||
write a ``Sitemap`` class and point to it in your URLconf_.
|
||||
|
||||
.. _syndication framework: ../syndication/
|
||||
.. _syndication framework: ../syndication_feeds/
|
||||
.. _URLconf: ../url_dispatch/
|
||||
|
||||
Installation
|
||||
|
||||
@@ -46,7 +46,7 @@ that's represented by a ``ManyToManyField`` in the ``Article`` model::
|
||||
from django.contrib.sites.models import Site
|
||||
|
||||
class Article(models.Model):
|
||||
headline = models.CharField(maxlength=200)
|
||||
headline = models.CharField(max_length=200)
|
||||
# ...
|
||||
sites = models.ManyToManyField(Site)
|
||||
|
||||
@@ -87,7 +87,7 @@ like this::
|
||||
from django.contrib.sites.models import Site
|
||||
|
||||
class Article(models.Model):
|
||||
headline = models.CharField(maxlength=200)
|
||||
headline = models.CharField(max_length=200)
|
||||
# ...
|
||||
site = models.ForeignKey(Site)
|
||||
|
||||
@@ -229,7 +229,7 @@ Use ``CurrentSiteManager`` by adding it to your model explicitly. For example::
|
||||
|
||||
class Photo(models.Model):
|
||||
photo = models.FileField(upload_to='/home/photos')
|
||||
photographer_name = models.CharField(maxlength=100)
|
||||
photographer_name = models.CharField(max_length=100)
|
||||
pub_date = models.DateField()
|
||||
site = models.ForeignKey(Site)
|
||||
objects = models.Manager()
|
||||
@@ -257,7 +257,7 @@ this::
|
||||
|
||||
class Photo(models.Model):
|
||||
photo = models.FileField(upload_to='/home/photos')
|
||||
photographer_name = models.CharField(maxlength=100)
|
||||
photographer_name = models.CharField(max_length=100)
|
||||
pub_date = models.DateField()
|
||||
publish_on = models.ForeignKey(Site)
|
||||
objects = models.Manager()
|
||||
@@ -318,5 +318,23 @@ Here's how Django uses the sites framework:
|
||||
|
||||
.. _redirects framework: ../redirects/
|
||||
.. _flatpages framework: ../flatpages/
|
||||
.. _syndication framework: ../syndication/
|
||||
.. _syndication framework: ../syndication_feeds/
|
||||
.. _authentication framework: ../authentication/
|
||||
|
||||
``RequestSite`` objects
|
||||
=======================
|
||||
|
||||
**New in Django development version**
|
||||
|
||||
Some ``django.contrib`` applications take advantage of the sites framework but
|
||||
are architected in a way that doesn't *require* the sites framework to be
|
||||
installed in your database. (Some people don't want to, or just aren't *able*
|
||||
to install the extra database table that the sites framework requires.) For
|
||||
those cases, the framework provides a ``RequestSite`` class, which can be used
|
||||
as a fallback when the database-backed sites framework is not available.
|
||||
|
||||
A ``RequestSite`` object has a similar interface to a normal ``Site`` object,
|
||||
except its ``__init__()`` method takes an ``HttpRequest`` object. It's able to
|
||||
deduce the ``domain`` and ``name`` by looking at the request's domain. It has
|
||||
``save()`` and ``delete()`` methods to match the interface of ``Site``, but
|
||||
the methods raise ``NotImplementedError``.
|
||||
|
||||
@@ -103,10 +103,10 @@ Do this by wrapping an ``if DEBUG`` statement around the
|
||||
from django.conf import settings
|
||||
|
||||
urlpatterns = patterns('',
|
||||
(r'^/articles/2003/$', 'news.views.special_case_2003'),
|
||||
(r'^/articles/(?P<year>\d{4})/$', 'news.views.year_archive'),
|
||||
(r'^/articles/(?P<year>\d{4})/(?P<month>\d{2})/$', 'news.views.month_archive'),
|
||||
(r'^/articles/(?P<year>\d{4})/(?P<month>\d{2})/(?P<day>\d+)/$', 'news.views.article_detail'),
|
||||
(r'^articles/2003/$', 'news.views.special_case_2003'),
|
||||
(r'^articles/(?P<year>\d{4})/$', 'news.views.year_archive'),
|
||||
(r'^articles/(?P<year>\d{4})/(?P<month>\d{2})/$', 'news.views.month_archive'),
|
||||
(r'^articles/(?P<year>\d{4})/(?P<month>\d{2})/(?P<day>\d+)/$', 'news.views.article_detail'),
|
||||
)
|
||||
|
||||
if settings.DEBUG:
|
||||
|
||||
@@ -31,6 +31,12 @@ To create a feed, just write a ``Feed`` class and point to it in your URLconf_.
|
||||
Initialization
|
||||
--------------
|
||||
|
||||
If you're not using the latest Django development version, you'll need to make
|
||||
sure Django's sites framework is installed -- including its database table.
|
||||
(See the `sites framework documentation`_ for more information.) This has
|
||||
changed in the Django development version; the syndication feed framework no
|
||||
longer requires the sites framework.
|
||||
|
||||
To activate syndication feeds on your Django site, add this line to your
|
||||
URLconf_::
|
||||
|
||||
@@ -72,6 +78,7 @@ The above example registers two feeds:
|
||||
|
||||
Once that's set up, you just need to define the ``Feed`` classes themselves.
|
||||
|
||||
.. _sites framework documentation: ../sites/
|
||||
.. _URLconf: ../url_dispatch/
|
||||
.. _settings file: ../settings/
|
||||
|
||||
@@ -131,9 +138,14 @@ put into those elements.
|
||||
|
||||
* ``{{ obj }}`` -- The current object (one of whichever objects you
|
||||
returned in ``items()``).
|
||||
* ``{{ site }}`` -- A ``django.models.core.sites.Site`` object
|
||||
* ``{{ site }}`` -- A ``django.contrib.sites.models.Site`` object
|
||||
representing the current site. This is useful for
|
||||
``{{ site.domain }}`` or ``{{ site.name }}``.
|
||||
``{{ site.domain }}`` or ``{{ site.name }}``. Note that if you're
|
||||
using the latest Django development version and do *not* have the
|
||||
Django sites framework installed, this will be set to a
|
||||
``django.contrib.sites.models.RequestSite`` object. See the
|
||||
`RequestSite section of the sites framework documentation`_ for
|
||||
more.
|
||||
|
||||
If you don't create a template for either the title or description, the
|
||||
framework will use the template ``"{{ obj }}"`` by default -- that is,
|
||||
@@ -164,6 +176,7 @@ put into those elements.
|
||||
.. _chicagocrime.org: http://www.chicagocrime.org/
|
||||
.. _object-relational mapper: ../db-api/
|
||||
.. _Django templates: ../templates/
|
||||
.. _RequestSite section of the sites framework documentation: ../sites/#requestsite-objects
|
||||
|
||||
A complex example
|
||||
-----------------
|
||||
@@ -416,6 +429,26 @@ This example illustrates all possible attributes and methods for a ``Feed`` clas
|
||||
|
||||
link = '/foo/bar/' # Hard-coded link.
|
||||
|
||||
# GUID -- One of the following three is optional. The framework looks
|
||||
# for them in this order. This property is only used for Atom feeds
|
||||
# (where it is the feed-level ID element). If not provided, the feed
|
||||
# link is used as the ID.
|
||||
#
|
||||
# (New in Django development version)
|
||||
|
||||
def feed_guid(self, obj):
|
||||
"""
|
||||
Takes the object returned by get_object() and returns the globally
|
||||
unique ID for the feed as a normal Python string.
|
||||
"""
|
||||
|
||||
def feed_guid(self):
|
||||
"""
|
||||
Returns the feed's globally unique ID as a normal Python string.
|
||||
"""
|
||||
|
||||
feed_guid = '/foo/bar/1234' # Hard-coded guid.
|
||||
|
||||
# DESCRIPTION -- One of the following three is required. The framework
|
||||
# looks for them in this order.
|
||||
|
||||
@@ -556,7 +589,18 @@ This example illustrates all possible attributes and methods for a ``Feed`` clas
|
||||
Returns the URL for every item in the feed.
|
||||
"""
|
||||
|
||||
# ITEM AUTHOR NAME --One of the following three is optional. The
|
||||
# ITEM_GUID -- The following method is optional. This property is
|
||||
# only used for Atom feeds (it is the ID element for an item in an
|
||||
# Atom feed). If not provided, the item's link is used by default.
|
||||
#
|
||||
# (New in Django development version)
|
||||
|
||||
def item_guid(self, obj):
|
||||
"""
|
||||
Takes an item, as return by items(), and returns the item's ID.
|
||||
"""
|
||||
|
||||
# ITEM AUTHOR NAME -- One of the following three is optional. The
|
||||
# framework looks for them in this order.
|
||||
|
||||
def item_author_name(self, item):
|
||||
|
||||
@@ -741,8 +741,19 @@ regroup
|
||||
Regroup a list of alike objects by a common attribute.
|
||||
|
||||
This complex tag is best illustrated by use of an example: say that ``people``
|
||||
is a list of ``Person`` objects that have ``first_name``, ``last_name``, and
|
||||
``gender`` attributes, and you'd like to display a list that looks like:
|
||||
is a list of people represented by dictionaries with ``first_name``,
|
||||
``last_name``, and ``gender`` keys::
|
||||
|
||||
people = [
|
||||
{'first_name': 'George', 'last_name': 'Bush', 'gender': 'Male'},
|
||||
{'first_name': 'Bill', 'last_name': 'Clinton', 'gender': 'Male'},
|
||||
{'first_name': 'Margaret', 'last_name': 'Thatcher', 'gender': 'Female'},
|
||||
{'first_name': 'Condoleezza', 'last_name': 'Rice', 'gender': 'Female'},
|
||||
{'first_name': 'Pat', 'last_name': 'Smith', 'gender': 'Unknown'},
|
||||
]
|
||||
|
||||
...and you'd like to display a hierarchical list that is ordered by gender,
|
||||
like this:
|
||||
|
||||
* Male:
|
||||
* George Bush
|
||||
@@ -753,33 +764,72 @@ is a list of ``Person`` objects that have ``first_name``, ``last_name``, and
|
||||
* Unknown:
|
||||
* Pat Smith
|
||||
|
||||
The following snippet of template code would accomplish this dubious task::
|
||||
You can use the ``{% regroup %}`` tag to group the list of people by gender.
|
||||
The following snippet of template code would accomplish this::
|
||||
|
||||
{% regroup people by gender as gender_list %}
|
||||
|
||||
{% regroup people by gender as grouped %}
|
||||
<ul>
|
||||
{% for group in grouped %}
|
||||
<li>{{ group.grouper }}
|
||||
{% for gender in gender_list %}
|
||||
<li>{{ gender.grouper }}
|
||||
<ul>
|
||||
{% for item in group.list %}
|
||||
<li>{{ item }}</li>
|
||||
{% for item in gender.list %}
|
||||
<li>{{ item.first_name }} {{ item.last_name }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
As you can see, ``{% regroup %}`` populates a variable with a list of objects
|
||||
with ``grouper`` and ``list`` attributes. ``grouper`` contains the item that
|
||||
was grouped by; ``list`` contains the list of objects that share that
|
||||
``grouper``. In this case, ``grouper`` would be ``Male``, ``Female`` and
|
||||
``Unknown``, and ``list`` is the list of people with those genders.
|
||||
Let's walk through this example. ``{% regroup %}`` takes three arguments: the
|
||||
list you want to regroup, the attribute to group by, and the name of the
|
||||
resulting list. Here, we're regrouping the ``people`` list by the ``gender``
|
||||
attribute and calling the result ``gender_list``.
|
||||
|
||||
Note that ``{% regroup %}`` does not work when the list to be grouped is not
|
||||
sorted by the key you are grouping by! This means that if your list of people
|
||||
was not sorted by gender, you'd need to make sure it is sorted before using it,
|
||||
i.e.::
|
||||
``{% regroup %}`` produces a list (in this case, ``gender_list``) of
|
||||
**group objects**. Each group object has two attributes:
|
||||
|
||||
{% regroup people|dictsort:"gender" by gender as grouped %}
|
||||
* ``grouper`` -- the item that was grouped by (e.g., the string "Male" or
|
||||
"Female").
|
||||
* ``list`` -- a list of all items in this group (e.g., a list of all people
|
||||
with gender='Male').
|
||||
|
||||
Note that ``{% regroup %}`` does not order its input! Our example relies on
|
||||
the fact that the ``people`` list was ordered by ``gender`` in the first place.
|
||||
If the ``people`` list did *not* order its members by ``gender``, the regrouping
|
||||
would naively display more than one group for a single gender. For example,
|
||||
say the ``people`` list was set to this (note that the males are not grouped
|
||||
together)::
|
||||
|
||||
people = [
|
||||
{'first_name': 'Bill', 'last_name': 'Clinton', 'gender': 'Male'},
|
||||
{'first_name': 'Pat', 'last_name': 'Smith', 'gender': 'Unknown'},
|
||||
{'first_name': 'Margaret', 'last_name': 'Thatcher', 'gender': 'Female'},
|
||||
{'first_name': 'George', 'last_name': 'Bush', 'gender': 'Male'},
|
||||
{'first_name': 'Condoleezza', 'last_name': 'Rice', 'gender': 'Female'},
|
||||
]
|
||||
|
||||
With this input for ``people``, the example ``{% regroup %}`` template code
|
||||
above would result in the following output:
|
||||
|
||||
* Male:
|
||||
* Bill Clinton
|
||||
* Unknown:
|
||||
* Pat Smith
|
||||
* Female:
|
||||
* Margaret Thatcher
|
||||
* Male:
|
||||
* George Bush
|
||||
* Female:
|
||||
* Condoleezza Rice
|
||||
|
||||
The easiest solution to this gotcha is to make sure in your view code that the
|
||||
data is ordered according to how you want to display it.
|
||||
|
||||
Another solution is to sort the data in the template using the ``dictsort``
|
||||
filter, if your data is in a list of dictionaries::
|
||||
|
||||
{% regroup people|dictsort:"gender" by gender as gender_list %}
|
||||
|
||||
spaceless
|
||||
~~~~~~~~~
|
||||
@@ -887,6 +937,12 @@ such as this::
|
||||
|
||||
The template tag will output the string ``/clients/client/123/``.
|
||||
|
||||
**New in development version:** If you're using `named URL patterns`_,
|
||||
you can refer to the name of the pattern in the ``url`` tag instead of
|
||||
using the path to the view.
|
||||
|
||||
.. _named URL patterns: ../url_dispatch/#naming-url-patterns
|
||||
|
||||
widthratio
|
||||
~~~~~~~~~~
|
||||
|
||||
@@ -950,7 +1006,7 @@ Removes all values of arg from the given string.
|
||||
date
|
||||
~~~~
|
||||
|
||||
Formats a date according to the given format (same as the ``now`` tag).
|
||||
Formats a date according to the given format (same as the `now`_ tag).
|
||||
|
||||
default
|
||||
~~~~~~~
|
||||
@@ -965,14 +1021,14 @@ If value is ``None``, use given default.
|
||||
dictsort
|
||||
~~~~~~~~
|
||||
|
||||
Takes a list of dicts, returns that list sorted by the property given in the
|
||||
argument.
|
||||
Takes a list of dictionaries, returns that list sorted by the key given in
|
||||
the argument.
|
||||
|
||||
dictsortreversed
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
Takes a list of dicts, returns that list sorted in reverse order by the
|
||||
property given in the argument.
|
||||
Takes a list of dictionaries, returns that list sorted in reverse order by the
|
||||
key given in the argument.
|
||||
|
||||
divisibleby
|
||||
~~~~~~~~~~~
|
||||
@@ -1040,6 +1096,16 @@ right-most digit, 2 is the second-right-most digit, etc. Returns the original
|
||||
value for invalid input (if input or argument is not an integer, or if argument
|
||||
is less than 1). Otherwise, output is always an integer.
|
||||
|
||||
iriencode
|
||||
~~~~~~~~~
|
||||
|
||||
Converts an IRI (Internationalized Resource Identifier) to a string that is
|
||||
suitable for including in a URL. This is necessary if you're trying to use
|
||||
strings containing non-ASCII characters in a URL.
|
||||
|
||||
It's safe to use this filter on a string that has already gone through the
|
||||
``urlencode`` filter.
|
||||
|
||||
join
|
||||
~~~~
|
||||
|
||||
@@ -1179,7 +1245,10 @@ Strips all [X]HTML tags.
|
||||
time
|
||||
~~~~
|
||||
|
||||
Formats a time according to the given format (same as the ``now`` tag).
|
||||
Formats a time according to the given format (same as the `now`_ tag).
|
||||
The time filter will only accept parameters in the format string that relate
|
||||
to the time of day, not the date (for obvious reasons). If you need to
|
||||
format a date, use the `date`_ filter.
|
||||
|
||||
timesince
|
||||
~~~~~~~~~
|
||||
@@ -1263,12 +1332,17 @@ urlize
|
||||
|
||||
Converts URLs in plain text into clickable links.
|
||||
|
||||
Note that if ``urlize`` is applied to text that already contains HTML markup,
|
||||
things won't work as expected. Apply this filter only to *plain* text.
|
||||
|
||||
urlizetrunc
|
||||
~~~~~~~~~~~
|
||||
|
||||
Converts URLs into clickable links, truncating URLs longer than the given
|
||||
character limit.
|
||||
|
||||
As with urlize_, this filter should only be applied to *plain* text.
|
||||
|
||||
**Argument:** Length to truncate URLs to
|
||||
|
||||
wordcount
|
||||
|
||||
@@ -277,7 +277,7 @@ Subclassing Context: RequestContext
|
||||
|
||||
Django comes with a special ``Context`` class,
|
||||
``django.template.RequestContext``, that acts slightly differently than
|
||||
the normal ``django.template.Context``. The first difference is that takes
|
||||
the normal ``django.template.Context``. The first difference is that it takes
|
||||
an `HttpRequest object`_ as its first argument. For example::
|
||||
|
||||
c = RequestContext(request, {
|
||||
@@ -311,9 +311,10 @@ optional, third positional argument, ``processors``. In this example, the
|
||||
|
||||
def some_view(request):
|
||||
# ...
|
||||
return RequestContext(request, {
|
||||
c = RequestContext(request, {
|
||||
'foo': 'bar',
|
||||
}, [ip_address_processor])
|
||||
return t.render(c)
|
||||
|
||||
Note::
|
||||
If you're using Django's ``render_to_response()`` shortcut to populate a
|
||||
@@ -673,11 +674,11 @@ If you are writing a template filter which only expects a string as the first
|
||||
argument, you should use the included decorator ``stringfilter`` which will convert
|
||||
an object to it's string value before being passed to your function::
|
||||
|
||||
from django import template
|
||||
from django.template.defaultfilters import stringfilter
|
||||
|
||||
@template.stringfilter
|
||||
@stringfilter
|
||||
def lower(value):
|
||||
return value.lower()
|
||||
return value.lower()
|
||||
|
||||
Writing custom template tags
|
||||
----------------------------
|
||||
|
||||
1310
docs/testing.txt
1310
docs/testing.txt
File diff suppressed because it is too large
Load Diff
@@ -22,10 +22,10 @@ installed.
|
||||
.. admonition:: Where to get help:
|
||||
|
||||
If you're having trouble going through this tutorial, please post a message
|
||||
to `django-users`_ or drop by `#django`_ on ``irc.freenode.net`` and we'll
|
||||
to `django-users`_ or drop by `#django`_ on ``irc.freenode.net`` and we'll
|
||||
try to help.
|
||||
|
||||
.. _django-users: http://groups.google.com/group/django-users
|
||||
.. _django-users: http://groups.google.com/group/django-users
|
||||
.. _#django: irc://irc.freenode.net/django
|
||||
|
||||
Creating a project
|
||||
@@ -42,7 +42,7 @@ code, then run the command ``django-admin.py startproject mysite``. This
|
||||
will create a ``mysite`` directory in your current directory.
|
||||
|
||||
.. note::
|
||||
|
||||
|
||||
You'll need to avoid naming projects after built-in Python or Django
|
||||
components. In particular, this means you should avoid using names like
|
||||
``django`` (which will conflict with Django itself) or ``site`` (which
|
||||
@@ -251,12 +251,12 @@ These concepts are represented by simple Python classes. Edit the
|
||||
from django.db import models
|
||||
|
||||
class Poll(models.Model):
|
||||
question = models.CharField(maxlength=200)
|
||||
question = models.CharField(max_length=200)
|
||||
pub_date = models.DateTimeField('date published')
|
||||
|
||||
class Choice(models.Model):
|
||||
poll = models.ForeignKey(Poll)
|
||||
choice = models.CharField(maxlength=200)
|
||||
choice = models.CharField(max_length=200)
|
||||
votes = models.IntegerField()
|
||||
|
||||
The code is straightforward. Each model is represented by a class that
|
||||
@@ -279,7 +279,7 @@ name for ``Poll.pub_date``. For all other fields in this model, the field's
|
||||
machine-readable name will suffice as its human-readable name.
|
||||
|
||||
Some ``Field`` classes have required elements. ``CharField``, for example,
|
||||
requires that you give it a ``maxlength``. That's used not only in the database
|
||||
requires that you give it a ``max_length``. That's used not only in the database
|
||||
schema, but in validation, as we'll soon see.
|
||||
|
||||
Finally, note a relationship is defined, using ``models.ForeignKey``. That tells
|
||||
@@ -321,7 +321,7 @@ Now Django knows ``mysite`` includes the ``polls`` app. Let's run another comman
|
||||
|
||||
python manage.py sql polls
|
||||
|
||||
You should see something similar to the following (the CREATE TABLE SQL statements
|
||||
You should see something similar to the following (the CREATE TABLE SQL statements
|
||||
for the polls app)::
|
||||
|
||||
BEGIN;
|
||||
@@ -341,7 +341,7 @@ for the polls app)::
|
||||
Note the following:
|
||||
|
||||
* The exact output will vary depending on the database you are using.
|
||||
|
||||
|
||||
* Table names are automatically generated by combining the name of the app
|
||||
(``polls``) and the lowercase name of the model -- ``poll`` and
|
||||
``choice``. (You can override this behavior.)
|
||||
@@ -371,8 +371,8 @@ If you're interested, also run the following commands:
|
||||
construction of your models.
|
||||
|
||||
* ``python manage.py sqlcustom polls`` -- Outputs any custom SQL statements
|
||||
(such as table modifications or constraints) that are defined for the
|
||||
application.
|
||||
(such as table modifications or constraints) that are defined for the
|
||||
application.
|
||||
|
||||
* ``python manage.py sqlclear polls`` -- Outputs the necessary ``DROP
|
||||
TABLE`` statements for this app, according to which tables already exist
|
||||
@@ -444,8 +444,8 @@ Once you're in the shell, explore the database API::
|
||||
[]
|
||||
|
||||
# Create a new Poll.
|
||||
>>> from datetime import datetime
|
||||
>>> p = Poll(question="What's up?", pub_date=datetime.now())
|
||||
>>> import datetime
|
||||
>>> p = Poll(question="What's up?", pub_date=datetime.datetime.now())
|
||||
|
||||
# Save the object into the database. You have to call save() explicitly.
|
||||
>>> p.save()
|
||||
@@ -461,10 +461,10 @@ Once you're in the shell, explore the database API::
|
||||
>>> p.question
|
||||
"What's up?"
|
||||
>>> p.pub_date
|
||||
datetime.datetime(2005, 7, 15, 12, 00, 53)
|
||||
datetime.datetime(2007, 7, 15, 12, 00, 53)
|
||||
|
||||
# Change values by changing the attributes, then calling save().
|
||||
>>> p.pub_date = datetime(2005, 4, 1, 0, 0)
|
||||
>>> p.pub_date = datetime.datetime(2007, 4, 1, 0, 0)
|
||||
>>> p.save()
|
||||
|
||||
# objects.all() displays all the polls in the database.
|
||||
@@ -474,22 +474,39 @@ Once you're in the shell, explore the database API::
|
||||
|
||||
Wait a minute. ``<Poll: Poll object>`` is, utterly, an unhelpful
|
||||
representation of this object. Let's fix that by editing the polls model (in
|
||||
the ``polls/models.py`` file) and adding a ``__str__()`` method to both
|
||||
the ``polls/models.py`` file) and adding a ``__unicode__()`` method to both
|
||||
``Poll`` and ``Choice``::
|
||||
|
||||
class Poll(models.Model):
|
||||
# ...
|
||||
def __str__(self):
|
||||
def __unicode__(self):
|
||||
return self.question
|
||||
|
||||
class Choice(models.Model):
|
||||
# ...
|
||||
def __str__(self):
|
||||
def __unicode__(self):
|
||||
return self.choice
|
||||
|
||||
It's important to add ``__str__()`` methods to your models, not only for your
|
||||
own sanity when dealing with the interactive prompt, but also because objects'
|
||||
representations are used throughout Django's automatically-generated admin.
|
||||
It's important to add ``__unicode__()`` methods to your models, not only for
|
||||
your own sanity when dealing with the interactive prompt, but also because
|
||||
objects' representations are used throughout Django's automatically-generated
|
||||
admin.
|
||||
|
||||
.. admonition:: Why ``__unicode__()`` and not ``__str__()``?
|
||||
|
||||
If you're familiar with Python, you might be in the habit of adding
|
||||
``__str__()`` methods to your classes, not ``__unicode__()`` methods.
|
||||
We use ``__unicode__()`` here because Django models deal with Unicode by
|
||||
default. All data stored in your database is converted to Unicode when it's
|
||||
returned.
|
||||
|
||||
Django models have a default ``__str__()`` method that calls
|
||||
``__unicode__()`` and converts the result to a UTF-8 bytestring. This means
|
||||
that ``unicode(p)`` will return a Unicode string, and ``str(p)`` will return
|
||||
a normal string, with characters encoded as UTF-8.
|
||||
|
||||
If all of this is jibberish to you, just remember to add ``__unicode__()``
|
||||
methods to your models. With any luck, things should Just Work for you.
|
||||
|
||||
Note these are normal Python methods. Let's add a custom method, just for
|
||||
demonstration::
|
||||
@@ -509,7 +526,7 @@ Let's jump back into the Python interactive shell by running
|
||||
|
||||
>>> from mysite.polls.models import Poll, Choice
|
||||
|
||||
# Make sure our __str__() addition worked.
|
||||
# Make sure our __unicode__() addition worked.
|
||||
>>> Poll.objects.all()
|
||||
[<Poll: What's up?>]
|
||||
|
||||
@@ -520,9 +537,9 @@ Let's jump back into the Python interactive shell by running
|
||||
>>> Poll.objects.filter(question__startswith='What')
|
||||
[<Poll: What's up?>]
|
||||
|
||||
# Get the poll whose year is 2005. Of course, if you're going through this
|
||||
# Get the poll whose year is 2007. Of course, if you're going through this
|
||||
# tutorial in another year, change as appropriate.
|
||||
>>> Poll.objects.get(pub_date__year=2005)
|
||||
>>> Poll.objects.get(pub_date__year=2007)
|
||||
<Poll: What's up?>
|
||||
|
||||
>>> Poll.objects.get(id=2)
|
||||
@@ -563,9 +580,9 @@ Let's jump back into the Python interactive shell by running
|
||||
|
||||
# The API automatically follows relationships as far as you need.
|
||||
# Use double underscores to separate relationships.
|
||||
# This works as many levels deep as you want. There's no limit.
|
||||
# Find all Choices for any poll whose pub_date is in 2005.
|
||||
>>> Choice.objects.filter(poll__pub_date__year=2005)
|
||||
# This works as many levels deep as you want; there's no limit.
|
||||
# Find all Choices for any poll whose pub_date is in 2007.
|
||||
>>> Choice.objects.filter(poll__pub_date__year=2007)
|
||||
[<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]
|
||||
|
||||
# Let's delete one of the choices. Use delete() for that.
|
||||
|
||||
@@ -240,7 +240,7 @@ default, provide enough fields for 3 Choices."
|
||||
|
||||
Then change the other fields in ``Choice`` to give them ``core=True``::
|
||||
|
||||
choice = models.CharField(maxlength=200, core=True)
|
||||
choice = models.CharField(max_length=200, core=True)
|
||||
votes = models.IntegerField(core=True)
|
||||
|
||||
This tells Django: "When you edit a Choice on the Poll admin page, the 'choice'
|
||||
@@ -362,8 +362,8 @@ think they should.
|
||||
Customize the admin look and feel
|
||||
=================================
|
||||
|
||||
Clearly, having "Django administration" and "example.com" at the top of each
|
||||
admin page is ridiculous. It's just placeholder text.
|
||||
Clearly, having "Django administration" at the top of each admin page is
|
||||
ridiculous. It's just placeholder text.
|
||||
|
||||
That's easy to change, though, using Django's template system. The Django admin
|
||||
is powered by Django itself, and its interfaces use Django's own template
|
||||
@@ -389,7 +389,7 @@ as above, then copy ``django/contrib/admin/templates/admin/base_site.html`` to
|
||||
``admin`` subdirectory.
|
||||
|
||||
Then, just edit the file and replace the generic Django text with your own
|
||||
site's name and URL as you see fit.
|
||||
site's name as you see fit.
|
||||
|
||||
Note that any of Django's default admin templates can be overridden. To
|
||||
override a template, just do the same thing you did with ``base_site.html`` --
|
||||
|
||||
@@ -355,8 +355,9 @@ view code.
|
||||
Use the template system
|
||||
=======================
|
||||
|
||||
Back to our ``polls.detail`` view. Given the context variable ``poll``, here's
|
||||
what the template might look like::
|
||||
Back to the ``detail()`` view for our poll application. Given the context
|
||||
variable ``poll``, here's what the "polls/detail.html" template might look
|
||||
like::
|
||||
|
||||
<h1>{{ poll.question }}</h1>
|
||||
<ul>
|
||||
|
||||
@@ -8,8 +8,8 @@ application and will focus on simple form processing and cutting down our code.
|
||||
Write a simple form
|
||||
===================
|
||||
|
||||
Let's update our poll detail template from the last tutorial, so that the
|
||||
template contains an HTML ``<form>`` element::
|
||||
Let's update our poll detail template ("polls/detail.html") from the last
|
||||
tutorial, so that the template contains an HTML ``<form>`` element::
|
||||
|
||||
<h1>{{ poll.question }}</h1>
|
||||
|
||||
@@ -193,7 +193,7 @@ Change it like so::
|
||||
urlpatterns = patterns('',
|
||||
(r'^$', 'django.views.generic.list_detail.object_list', info_dict),
|
||||
(r'^(?P<object_id>\d+)/$', 'django.views.generic.list_detail.object_detail', info_dict),
|
||||
(r'^(?P<object_id>\d+)/results/$', 'django.views.generic.list_detail.object_detail', dict(info_dict, template_name='polls/results.html')),
|
||||
url(r'^(?P<object_id>\d+)/results/$', 'django.views.generic.list_detail.object_detail', dict(info_dict, template_name='polls/results.html'), 'poll_results'),
|
||||
(r'^(?P<poll_id>\d+)/vote/$', 'mysite.polls.views.vote'),
|
||||
)
|
||||
|
||||
@@ -209,6 +209,15 @@ objects" and "display a detail page for a particular type of object."
|
||||
from the URL to be called ``"object_id"``, so we've changed ``poll_id`` to
|
||||
``object_id`` for the generic views.
|
||||
|
||||
* We've added a name, ``poll_results``, to the results view so that we
|
||||
have a way to refer to its URL later on (see the documentation about
|
||||
`naming URL patterns`_ for information). We're also using the `url()`_
|
||||
function from ``django.conf.urls.defaults`` here. It's a good habit to
|
||||
use ``url()`` when you are providing a pattern name like this.
|
||||
|
||||
.. _naming URL patterns: ../url_dispatch/#naming-url-patterns
|
||||
.. _url(): ../url_dispatch/#url
|
||||
|
||||
By default, the ``object_detail`` generic view uses a template called
|
||||
``<app name>/<model name>_detail.html``. In our case, it'll use the template
|
||||
``"polls/poll_detail.html"``. Thus, rename your ``polls/detail.html`` template to
|
||||
@@ -255,6 +264,15 @@ the new templates and context variables. Change the template call from
|
||||
``polls/detail.html`` to ``polls/poll_detail.html``, and pass ``object`` in the
|
||||
context instead of ``poll``.
|
||||
|
||||
The last thing to do is fix the URL handling to account for the use of generic
|
||||
views. In the vote view above, we used the ``reverse()`` function to avoid
|
||||
hard-coding our URLs. Now that we've switched to a generic view, we'll need to
|
||||
change the ``reverse()`` call to point back to our new generic view. We can't
|
||||
simply use the view function anymore -- generic views can be (and are) used
|
||||
multiple times -- but we can use the name we've given::
|
||||
|
||||
return HttpResponseRedirect(reverse('poll_results', args=(p.id,)))
|
||||
|
||||
Run the server, and use your new polling app based on generic views.
|
||||
|
||||
For full details on generic views, see the `generic views documentation`_.
|
||||
|
||||
364
docs/unicode.txt
Normal file
364
docs/unicode.txt
Normal file
@@ -0,0 +1,364 @@
|
||||
======================
|
||||
Unicode data in Django
|
||||
======================
|
||||
|
||||
**New in Django development version**
|
||||
|
||||
Django natively supports Unicode data everywhere. Providing your database can
|
||||
somehow store the data, you can safely pass around Unicode strings to
|
||||
templates, models and the database.
|
||||
|
||||
This document tells you what you need to know if you're writing applications
|
||||
that use data or templates that are encoded in something other than ASCII.
|
||||
|
||||
Creating the database
|
||||
=====================
|
||||
|
||||
Make sure your database is configured to be able to store arbitrary string
|
||||
data. Normally, this means giving it an encoding of UTF-8 or UTF-16. If you use
|
||||
a more restrictive encoding -- for example, latin1 (iso8859-1) -- you won't be
|
||||
able to store certain characters in the database, and information will be lost.
|
||||
|
||||
* MySQL users, refer to the `MySQL manual`_ (section 10.3.2 for MySQL 5.1) for
|
||||
details on how to set or alter the database character set encoding.
|
||||
|
||||
* PostgreSQL users, refer to the `PostgreSQL manual`_ (section 21.2.2 in
|
||||
PostgreSQL 8) for details on creating databases with the correct encoding.
|
||||
|
||||
* SQLite users, there is nothing you need to do. SQLite always uses UTF-8
|
||||
for internal encoding.
|
||||
|
||||
.. _MySQL manual: http://www.mysql.org/doc/refman/5.1/en/charset-database.html
|
||||
.. _PostgreSQL manual: http://www.postgresql.org/docs/8.2/static/multibyte.html#AEN24104
|
||||
|
||||
All of Django's database backends automatically convert Unicode strings into
|
||||
the appropriate encoding for talking to the database. They also automatically
|
||||
convert strings retrieved from the database into Python Unicode strings. You
|
||||
don't even need to tell Django what encoding your database uses: that is
|
||||
handled transparently.
|
||||
|
||||
For more, see the section "The database API" below.
|
||||
|
||||
General string handling
|
||||
=======================
|
||||
|
||||
Whenever you use strings with Django -- e.g., in database lookups, template
|
||||
rendering or anywhere else -- you have two choices for encoding those strings.
|
||||
You can use Unicode strings, or you can use normal strings (sometimes called
|
||||
"bytestrings") that are encoded using UTF-8.
|
||||
|
||||
.. admonition:: Warning
|
||||
|
||||
A bytestring does not carry any information with it about its encoding.
|
||||
For that reason, we have to make an assumption, and Django assumes that all
|
||||
bytestrings are in UTF-8.
|
||||
|
||||
If you pass a string to Django that has been encoded in some other format,
|
||||
things will go wrong in interesting ways. Usually, Django will raise a
|
||||
``UnicodeDecodeError`` at some point.
|
||||
|
||||
If your code only uses ASCII data, it's safe to use your normal strings,
|
||||
passing them around at will, because ASCII is a subset of UTF-8.
|
||||
|
||||
Don't be fooled into thinking that if your ``DEFAULT_CHARSET`` setting is set
|
||||
to something other than ``'utf-8'`` you can use that other encoding in your
|
||||
bytestrings! ``DEFAULT_CHARSET`` only applies to the strings generated as
|
||||
the result of template rendering (and e-mail). Django will always assume UTF-8
|
||||
encoding for internal bytestrings. The reason for this is that the
|
||||
``DEFAULT_CHARSET`` setting is not actually under your control (if you are the
|
||||
application developer). It's under the control of the person installing and
|
||||
using your application -- and if that person chooses a different setting, your
|
||||
code must still continue to work. Ergo, it cannot rely on that setting.
|
||||
|
||||
In most cases when Django is dealing with strings, it will convert them to
|
||||
Unicode strings before doing anything else. So, as a general rule, if you pass
|
||||
in a bytestring, be prepared to receive a Unicode string back in the result.
|
||||
|
||||
Translated strings
|
||||
------------------
|
||||
|
||||
Aside from Unicode strings and bytestrings, there's a third type of string-like
|
||||
object you may encounter when using Django. The framework's
|
||||
internationalization features introduce the concept of a "lazy translation" --
|
||||
a string that has been marked as translated but whose actual translation result
|
||||
isn't determined until the object is used in a string. This feature is useful
|
||||
in cases where the translation locale is unknown until the string is used, even
|
||||
though the string might have originally been created when the code was first
|
||||
imported.
|
||||
|
||||
Normally, you won't have to worry about lazy translations. Just be aware that
|
||||
if you examine an object and it claims to be a
|
||||
``django.utils.functional.__proxy__`` object, it is a lazy translation.
|
||||
Calling ``unicode()`` with the lazy translation as the argument will generate a
|
||||
Unicode string in the current locale.
|
||||
|
||||
For more details about lazy translation objects, refer to the
|
||||
internationalization_ documentation.
|
||||
|
||||
.. _internationalization: ../i18n/#lazy-translation
|
||||
|
||||
Useful utility functions
|
||||
------------------------
|
||||
|
||||
Because some string operations come up again and again, Django ships with a few
|
||||
useful functions that should make working with Unicode and bytestring objects
|
||||
a bit easier.
|
||||
|
||||
Conversion functions
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The ``django.utils.encoding`` module contains a few functions that are handy
|
||||
for converting back and forth between Unicode and bytestrings.
|
||||
|
||||
* ``smart_unicode(s, encoding='utf-8', errors='strict')`` converts its
|
||||
input to a Unicode string. The ``encoding`` parameter specifies the input
|
||||
encoding. (For example, Django uses this internally when processing form
|
||||
input data, which might not be UTF-8 encoded.) The ``errors`` parameter
|
||||
takes any of the values that are accepted by Python's ``unicode()``
|
||||
function for its error handling.
|
||||
|
||||
If you pass ``smart_unicode()`` an object that has a ``__unicode__``
|
||||
method, it will use that method to do the conversion.
|
||||
|
||||
* ``force_unicode(s, encoding='utf-8', errors='strict')`` is identical to
|
||||
``smart_unicode()`` in almost all cases. The difference is when the
|
||||
first argument is a `lazy translation`_ instance. While
|
||||
``smart_unicode()`` preserves lazy translations, ``force_unicode()``
|
||||
forces those objects to a Unicode string (causing the translation to
|
||||
occur). Normally, you'll want to use ``smart_unicode()``. However,
|
||||
``force_unicode()`` is useful in template tags and filters that
|
||||
absolutely *must* have a string to work with, not just something that can
|
||||
be converted to a string.
|
||||
|
||||
* ``smart_str(s, encoding='utf-8', strings_only=False, errors='strict')``
|
||||
is essentially the opposite of ``smart_unicode()``. It forces the first
|
||||
argument to a bytestring. The ``strings_only`` parameter, if set to True,
|
||||
will result in Python integers, booleans and ``None`` not being
|
||||
converted to a string (they keep their original types). This is slightly
|
||||
different semantics from Python's builtin ``str()`` function, but the
|
||||
difference is needed in a few places within Django's internals.
|
||||
|
||||
Normally, you'll only need to use ``smart_unicode()``. Call it as early as
|
||||
possible on any input data that might be either Unicode or a bytestring, and
|
||||
from then on, you can treat the result as always being Unicode.
|
||||
|
||||
.. _lazy translation: ../i18n/#lazy-translation
|
||||
|
||||
URI and IRI handling
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Web frameworks have to deal with URLs (which are a type of URI_). One
|
||||
requirement of URLs is that they are encoded using only ASCII characters.
|
||||
However, in an international environment, you might need to construct a
|
||||
URL from an IRI_ -- very loosely speaking, a URI that can contain Unicode
|
||||
characters. Quoting and converting an IRI to URI can be a little tricky, so
|
||||
Django provides some assistance.
|
||||
|
||||
* The function ``django.utils.encoding.iri_to_uri()`` implements the
|
||||
conversion from IRI to URI as required by the specification (`RFC
|
||||
3987`_).
|
||||
|
||||
* The functions ``django.utils.http.urlquote()`` and
|
||||
``django.utils.http.urlquote_plus()`` are versions of Python's standard
|
||||
``urllib.quote()`` and ``urllib.quote_plus()`` that work with non-ASCII
|
||||
characters. (The data is converted to UTF-8 prior to encoding.)
|
||||
|
||||
These two groups of functions have slightly different purposes, and it's
|
||||
important to keep them straight. Normally, you would use ``urlquote()`` on the
|
||||
individual portions of the IRI or URI path so that any reserved characters
|
||||
such as '&' or '%' are correctly encoded. Then, you apply ``iri_to_uri()`` to
|
||||
the full IRI and it converts any non-ASCII characters to the correct encoded
|
||||
values.
|
||||
|
||||
.. note::
|
||||
Technically, it isn't correct to say that ``iri_to_uri()`` implements the
|
||||
full algorithm in the IRI specification. It doesn't (yet) perform the
|
||||
international domain name encoding portion of the algorithm.
|
||||
|
||||
The ``iri_to_uri()`` function will not change ASCII characters that are
|
||||
otherwise permitted in a URL. So, for example, the character '%' is not
|
||||
further encoded when passed to ``iri_to_uri()``. This means you can pass a
|
||||
full URL to this function and it will not mess up the query string or anything
|
||||
like that.
|
||||
|
||||
An example might clarify things here::
|
||||
|
||||
>>> urlquote(u'Paris & Orléans')
|
||||
u'Paris%20%26%20Orl%C3%A9ans'
|
||||
>>> iri_to_uri(u'/favorites/François/%s' % urlquote(u'Paris & Orléans'))
|
||||
'/favorites/Fran%C3%A7ois/Paris%20%26%20Orl%C3%A9ans'
|
||||
|
||||
If you look carefully, you can see that the portion that was generated by
|
||||
``urlquote()`` in the second example was not double-quoted when passed to
|
||||
``iri_to_uri()``. This is a very important and useful feature. It means that
|
||||
you can construct your IRI without worrying about whether it contains
|
||||
non-ASCII characters and then, right at the end, call ``iri_to_uri()`` on the
|
||||
result.
|
||||
|
||||
The ``iri_to_uri()`` function is also idempotent, which means the following is
|
||||
always true::
|
||||
|
||||
iri_to_uri(iri_to_uri(some_string)) = iri_to_uri(some_string)
|
||||
|
||||
So you can safely call it multiple times on the same IRI without risking
|
||||
double-quoting problems.
|
||||
|
||||
.. _URI: http://www.ietf.org/rfc/rfc2396.txt
|
||||
.. _IRI: http://www.ietf.org/rfc/rfc3987.txt
|
||||
.. _RFC 3987: IRI_
|
||||
|
||||
Models
|
||||
======
|
||||
|
||||
Because all strings are returned from the database as Unicode strings, model
|
||||
fields that are character based (CharField, TextField, URLField, etc) will
|
||||
contain Unicode values when Django retrieves data from the database. This
|
||||
is *always* the case, even if the data could fit into an ASCII bytestring.
|
||||
|
||||
You can pass in bytestrings when creating a model or populating a field, and
|
||||
Django will convert it to Unicode when it needs to.
|
||||
|
||||
Choosing between ``__str__()`` and ``__unicode__()``
|
||||
----------------------------------------------------
|
||||
|
||||
One consequence of using Unicode by default is that you have to take some care
|
||||
when printing data from the model.
|
||||
|
||||
In particular, rather than giving your model a ``__str__()`` method, we
|
||||
recommended you implement a ``__unicode__()`` method. In the ``__unicode__()``
|
||||
method, you can quite safely return the values of all your fields without
|
||||
having to worry about whether they fit into a bytestring or not. (The way
|
||||
Python works, the result of ``__str__()`` is *always* a bytestring, even if you
|
||||
accidentally try to return a Unicode object).
|
||||
|
||||
You can still create a ``__str__()`` method on your models if you want, of
|
||||
course, but you shouldn't need to do this unless you have a good reason.
|
||||
Django's ``Model`` base class automatically provides a ``__str__()``
|
||||
implementation that calls ``__unicode__()`` and encodes the result into UTF-8.
|
||||
This means you'll normally only need to implement a ``__unicode__()`` method
|
||||
and let Django handle the coercion to a bytestring when required.
|
||||
|
||||
Taking care in ``get_absolute_url()``
|
||||
-------------------------------------
|
||||
|
||||
URLs can only contain ASCII characters. If you're constructing a URL from
|
||||
pieces of data that might be non-ASCII, be careful to encode the results in a
|
||||
way that is suitable for a URL. The ``django.db.models.permalink()`` decorator
|
||||
handles this for you automatically.
|
||||
|
||||
If you're constructing a URL manually (i.e., *not* using the ``permalink()``
|
||||
decorator), you'll need to take care of the encoding yourself. In this case,
|
||||
use the ``iri_to_uri()`` and ``urlquote()`` functions that were documented
|
||||
above_. For example::
|
||||
|
||||
from django.utils.encoding import iri_to_uri
|
||||
from django.utils.http import urlquote
|
||||
|
||||
def get_absolute_url(self):
|
||||
url = u'/person/%s/?x=0&y=0' % urlquote(self.location)
|
||||
return iri_to_uri(url)
|
||||
|
||||
This function returns a correctly encoded URL even if ``self.location`` is
|
||||
something like "Jack visited Paris & Orléans". (In fact, the ``iri_to_uri()``
|
||||
call isn't strictly necessary in the above example, because all the
|
||||
non-ASCII characters would have been removed in quoting in the first line.)
|
||||
|
||||
.. _above: `URI and IRI handling`_
|
||||
|
||||
The database API
|
||||
================
|
||||
|
||||
You can pass either Unicode strings or UTF-8 bytestrings as arguments to
|
||||
``filter()`` methods and the like in the database API. The following two
|
||||
querysets are identical::
|
||||
|
||||
qs = People.objects.filter(name__contains=u'Å')
|
||||
qs = People.objects.filter(name__contains='\xc3\85') # UTF-8 encoding of Å
|
||||
|
||||
Templates
|
||||
=========
|
||||
|
||||
You can use either Unicode or bytestrings when creating templates manually::
|
||||
|
||||
from django.template import Template
|
||||
t1 = Template('This is a bytestring template.')
|
||||
t2 = Template(u'This is a Unicode template.')
|
||||
|
||||
But the common case is to read templates from the filesystem, and this creates
|
||||
a slight complication: not all filesystems store their data encoded as UTF-8.
|
||||
If your template files are not stored with a UTF-8 encoding, set the ``FILE_CHARSET``
|
||||
setting to the encoding of the files on disk. When Django reads in a template
|
||||
file, it will convert the data from this encoding to Unicode. (``FILE_CHARSET``
|
||||
is set to ``'utf-8'`` by default.)
|
||||
|
||||
The ``DEFAULT_CHARSET`` setting controls the encoding of rendered templates.
|
||||
This is set to UTF-8 by default.
|
||||
|
||||
Template tags and filters
|
||||
-------------------------
|
||||
|
||||
A couple of tips to remember when writing your own template tags and filters:
|
||||
|
||||
* Always return Unicode strings from a template tag's ``render()`` method
|
||||
and from template filters.
|
||||
|
||||
* Use ``force_unicode()`` in preference to ``smart_unicode()`` in these
|
||||
places. Tag rendering and filter calls occur as the template is being
|
||||
rendered, so there is no advantage to postponing the conversion of lazy
|
||||
translation objects into strings. It's easier to work solely with Unicode
|
||||
strings at that point.
|
||||
|
||||
E-mail
|
||||
======
|
||||
|
||||
Django's e-mail framework (in ``django.core.mail``) supports Unicode
|
||||
transparently. You can use Unicode data in the message bodies and any headers.
|
||||
However, you're still obligated to respect the requirements of the e-mail
|
||||
specifications, so, for example, e-mail addresses should use only ASCII
|
||||
characters.
|
||||
|
||||
The following code example demonstrates that everything except e-mail addresses
|
||||
can be non-ASCII::
|
||||
|
||||
from django.core.mail import EmailMessage
|
||||
|
||||
subject = u'My visit to Sør-Trøndelag'
|
||||
sender = u'Arnbjörg Ráðormsdóttir <arnbjorg@example.com>'
|
||||
recipients = ['Fred <fred@example.com']
|
||||
body = u'...'
|
||||
EmailMessage(subject, body, sender, recipients).send()
|
||||
|
||||
Form submission
|
||||
===============
|
||||
|
||||
HTML form submission is a tricky area. There's no guarantee that the
|
||||
submission will include encoding information, which means the framework might
|
||||
have to guess at the encoding of submitted data.
|
||||
|
||||
Django adopts a "lazy" approach to decoding form data. The data in an
|
||||
``HttpRequest`` object is only decoded when you access it. In fact, most of
|
||||
the data is not decoded at all. Only the ``HttpRequest.GET`` and
|
||||
``HttpRequest.POST`` data structures have any decoding applied to them. Those
|
||||
two fields will return their members as Unicode data. All other attributes and
|
||||
methods of ``HttpRequest`` return data exactly as it was submitted by the
|
||||
client.
|
||||
|
||||
By default, the ``DEFAULT_CHARSET`` setting is used as the assumed encoding
|
||||
for form data. If you need to change this for a particular form, you can set
|
||||
the ``encoding`` attribute on an ``HttpRequest`` instance. For example::
|
||||
|
||||
def some_view(request):
|
||||
# We know that the data must be encoded as KOI8-R (for some reason).
|
||||
request.encoding = 'koi8-r'
|
||||
...
|
||||
|
||||
You can even change the encoding after having accessed ``request.GET`` or
|
||||
``request.POST``, and all subsequent accesses will use the new encoding.
|
||||
|
||||
Most developers won't need to worry about changing form encoding, but this is
|
||||
a useful feature for applications that talk to legacy systems whose encoding
|
||||
you cannot control.
|
||||
|
||||
Django does not decode the data of file uploads, because that data is normally
|
||||
treated as collections of bytes, rather than strings. Any automatic decoding
|
||||
there would alter the meaning of the stream of bytes.
|
||||
@@ -204,8 +204,16 @@ optional extra arguments dictionary. For example::
|
||||
...
|
||||
)
|
||||
|
||||
This function takes five arguments, most of which are optional::
|
||||
|
||||
url(regex, view, kwargs=None, name=None, prefix='')
|
||||
|
||||
See `Naming URL patterns`_ for why the ``name`` parameter is useful.
|
||||
|
||||
The ``prefix`` parameter has the same meaning as the first argument to
|
||||
``patterns()`` and is only relevant when you're passing a string as the
|
||||
``view`` parameter.
|
||||
|
||||
handler404
|
||||
----------
|
||||
|
||||
@@ -317,7 +325,7 @@ Old::
|
||||
from django.conf.urls.defaults import *
|
||||
|
||||
urlpatterns = patterns('',
|
||||
(r'^/?$', 'django.views.generic.date_based.archive_index'),
|
||||
(r'^$', 'django.views.generic.date_based.archive_index'),
|
||||
(r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/$', 'django.views.generic.date_based.archive_month'),
|
||||
(r'^tag/(?P<tag>\w+)/$', 'weblog.views.tag'),
|
||||
)
|
||||
@@ -327,7 +335,7 @@ New::
|
||||
from django.conf.urls.defaults import *
|
||||
|
||||
urlpatterns = patterns('django.views.generic.date_based',
|
||||
(r'^/?$', 'archive_index'),
|
||||
(r'^$', 'archive_index'),
|
||||
(r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/$','archive_month'),
|
||||
)
|
||||
|
||||
@@ -392,7 +400,7 @@ dictionary of extra keyword arguments to pass to the view function.
|
||||
For example::
|
||||
|
||||
urlpatterns = patterns('blog.views',
|
||||
(r'^/blog/(?P<year>\d{4})/$', 'year_archive', {'foo': 'bar'}),
|
||||
(r'^blog/(?P<year>\d{4})/$', 'year_archive', {'foo': 'bar'}),
|
||||
)
|
||||
|
||||
In this example, for a request to ``/blog/2005/``, Django will call the
|
||||
@@ -404,7 +412,7 @@ This technique is used in `generic views`_ and in the `syndication framework`_
|
||||
to pass metadata and options to views.
|
||||
|
||||
.. _generic views: ../generic_views/
|
||||
.. _syndication framework: ../syndication/
|
||||
.. _syndication framework: ../syndication_feeds/
|
||||
|
||||
.. admonition:: Dealing with conflicts
|
||||
|
||||
@@ -512,7 +520,7 @@ view::
|
||||
|
||||
This is completely valid, but it leads to problems when you try to do reverse
|
||||
URL matching (through the ``permalink()`` decorator or the ``{% url %}``
|
||||
template tag). Continuing this example, if you wanted to retrieve the URL for
|
||||
`template tag`_). Continuing this example, if you wanted to retrieve the URL for
|
||||
the ``archive`` view, Django's reverse URL matcher would get confused, because
|
||||
*two* URLpatterns point at that view.
|
||||
|
||||
@@ -552,14 +560,16 @@ not restricted to valid Python names.
|
||||
name, will decrease the chances of collision. We recommend something like
|
||||
``myapp-comment`` instead of ``comment``.
|
||||
|
||||
.. _template tag: ../templates/#url
|
||||
|
||||
Utility methods
|
||||
===============
|
||||
|
||||
reverse()
|
||||
---------
|
||||
|
||||
If you need to use something similar to the ``{% url %}`` template tag in your
|
||||
code, Django provides the ``django.core.urlresolvers.reverse()``. The
|
||||
If you need to use something similar to the ``{% url %}`` `template tag`_ in
|
||||
your code, Django provides the ``django.core.urlresolvers.reverse()``. The
|
||||
``reverse()`` function has the following signature::
|
||||
|
||||
reverse(viewname, urlconf=None, args=None, kwargs=None)
|
||||
|
||||
Reference in New Issue
Block a user