1
0
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:
Justin Bronn
2007-08-26 01:10:53 +00:00
parent a7297a255f
commit 2052b508eb
405 changed files with 29980 additions and 17232 deletions

View File

@@ -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
=============

View File

@@ -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/

View File

@@ -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

View File

@@ -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:

View File

@@ -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

View File

@@ -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
===========

View File

@@ -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/

View File

@@ -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)

View File

@@ -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()
-----------------

View File

@@ -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

View File

@@ -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
--------

View File

@@ -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()

View File

@@ -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?
-----------------

View File

@@ -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/

View File

@@ -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),
)

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View 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
View 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.

View 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
View 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.

View File

@@ -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
----------------------------------------------------

View File

@@ -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):

View File

@@ -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.

View File

@@ -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()``?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@@ -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/

View File

@@ -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

View File

@@ -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
-----------------------

View File

@@ -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.

View File

@@ -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
-------------

View File

@@ -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

View File

@@ -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``.

View File

@@ -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:

View File

@@ -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):

View File

@@ -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

View File

@@ -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
----------------------------

File diff suppressed because it is too large Load Diff

View File

@@ -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.

View File

@@ -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`` --

View File

@@ -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>

View File

@@ -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
View 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.

View File

@@ -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)