summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorAdrian Holovaty <adrian@holovaty.com>2007-05-12 02:36:05 +0000
committerAdrian Holovaty <adrian@holovaty.com>2007-05-12 02:36:05 +0000
commit415e84ad53e0d0d8f7df87784c1893489bdbe0b8 (patch)
tree09541f8319c45ec51fb44154534abc41cb86aee9 /docs
parent4938c8ea6db6f23ebb0883b8a092985344508b25 (diff)
newforms-admin: Merged to [5194]
git-svn-id: http://code.djangoproject.com/svn/django/branches/newforms-admin@5195 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'docs')
-rw-r--r--docs/add_ons.txt2
-rw-r--r--docs/api_stability.txt6
-rw-r--r--docs/authentication.txt36
-rw-r--r--docs/contributing.txt9
-rw-r--r--docs/databases.txt9
-rw-r--r--docs/databrowse.txt56
-rw-r--r--docs/db-api.txt14
-rw-r--r--docs/distributions.txt10
-rw-r--r--docs/django-admin.txt77
-rw-r--r--docs/documentation.txt8
-rw-r--r--docs/email.txt87
-rw-r--r--docs/faq.txt4
-rw-r--r--docs/flatpages.txt4
-rw-r--r--docs/forms.txt22
-rw-r--r--docs/generic_views.txt4
-rw-r--r--docs/i18n.txt8
-rw-r--r--docs/install.txt43
-rw-r--r--docs/legacy_databases.txt10
-rw-r--r--docs/model-api.txt57
-rw-r--r--docs/overview.txt2
-rw-r--r--docs/redirects.txt4
-rw-r--r--docs/request_response.txt1
-rw-r--r--docs/serialization.txt4
-rw-r--r--docs/sessions.txt2
-rw-r--r--docs/settings.txt101
-rw-r--r--docs/sitemaps.txt2
-rw-r--r--docs/sites.txt4
-rw-r--r--docs/syndication_feeds.txt27
-rw-r--r--docs/templates.txt12
-rw-r--r--docs/templates_python.txt31
-rw-r--r--docs/testing.txt259
-rw-r--r--docs/tutorial01.txt10
-rw-r--r--docs/tutorial02.txt8
-rw-r--r--docs/tutorial03.txt4
-rw-r--r--docs/tutorial04.txt4
-rw-r--r--docs/url_dispatch.txt56
36 files changed, 695 insertions, 302 deletions
diff --git a/docs/add_ons.txt b/docs/add_ons.txt
index b92ae0bd17..4f45d99d9a 100644
--- a/docs/add_ons.txt
+++ b/docs/add_ons.txt
@@ -24,7 +24,7 @@ admin
The automatic Django administrative interface. For more information, see
`Tutorial 2`_.
-.. _Tutorial 2: ../tutorial2/
+.. _Tutorial 2: ../tutorial02/
auth
====
diff --git a/docs/api_stability.txt b/docs/api_stability.txt
index 508336e0ef..cfaffeac6b 100644
--- a/docs/api_stability.txt
+++ b/docs/api_stability.txt
@@ -100,14 +100,14 @@ change:
.. _caching: ../cache/
.. _custom template tags and libraries: ../templates_python/
-.. _database lookup: ../db_api/
-.. _django-admin utility: ../django_admin/
+.. _database lookup: ../db-api/
+.. _django-admin utility: ../django-admin/
.. _fastcgi integration: ../fastcgi/
.. _flatpages: ../flatpages/
.. _generic views: ../generic_views/
.. _internationalization: ../i18n/
.. _legacy database integration: ../legacy_databases/
-.. _model definition: ../model_api/
+.. _model definition: ../model-api/
.. _mod_python integration: ../modpython/
.. _redirects: ../redirects/
.. _request/response objects: ../request_response/
diff --git a/docs/authentication.txt b/docs/authentication.txt
index aff336f67a..091a30a895 100644
--- a/docs/authentication.txt
+++ b/docs/authentication.txt
@@ -144,7 +144,7 @@ custom methods:
Raises ``django.contrib.auth.models.SiteProfileNotAvailable`` if the current site
doesn't allow profiles.
-.. _Django model: ../model_api/
+.. _Django model: ../model-api/
.. _DEFAULT_FROM_EMAIL: ../settings/#default-from-email
Manager functions
@@ -204,9 +204,12 @@ The ``password`` attribute of a ``User`` object is a string in this format::
That's hashtype, salt and hash, separated by the dollar-sign character.
-Hashtype is either ``sha1`` (default) or ``md5`` -- the algorithm used to
-perform a one-way hash of the password. Salt is a random string used to salt
-the raw password to create the hash.
+Hashtype is either ``sha1`` (default), ``md5`` or ``crypt`` -- the algorithm
+used to perform a one-way hash of the password. Salt is a random string used
+to salt the raw password to create the hash. Note that the ``crypt`` method is
+only supported on platforms that have the standard Python ``crypt`` module
+available, and ``crypt`` support is only available in the Django development
+version.
For example::
@@ -387,14 +390,15 @@ introduced in Python 2.4::
``login_required`` does the following:
- * If the user isn't logged in, redirect to ``/accounts/login/``, passing
- the current absolute URL in the query string as ``next``. For example:
+ * If the user isn't logged in, redirect to ``settings.LOGIN_URL``
+ (``/accounts/login/`` by default), passing the current absolute URL
+ in the query string as ``next``. For example:
``/accounts/login/?next=/polls/3/``.
* If the user is logged in, execute the view normally. The view code is
free to assume the user is logged in.
-Note that you'll need to map the appropriate Django view to ``/accounts/login/``.
-To do this, add the following line to your URLconf::
+Note that you'll need to map the appropriate Django view to ``settings.LOGIN_URL``.
+For example, using the defaults, add the following line to your URLconf::
(r'^accounts/login/$', 'django.contrib.auth.views.login'),
@@ -405,9 +409,9 @@ Here's what ``django.contrib.auth.views.login`` does:
* If called via ``POST``, it tries to log the user in. If login is
successful, the view redirects to the URL specified in ``next``. If
- ``next`` isn't provided, it redirects to ``/accounts/profile/`` (which is
- currently hard-coded). If login isn't successful, it redisplays the login
- form.
+ ``next`` isn't provided, it redirects to ``settings.LOGIN_REDIRECT_URL``
+ (which defaults to ``/accounts/profile/``). If login isn't successful,
+ it redisplays the login form.
It's your responsibility to provide the login form in a template called
``registration/login.html`` by default. This template gets passed three
@@ -487,7 +491,7 @@ Logs a user out, then redirects to the login page.
**Optional arguments:**
* ``login_url``: The URL of the login page to redirect to. This
- will default to ``/accounts/login/`` if not supplied.
+ will default to ``settings.LOGIN_URL`` if not supplied.
``django.contrib.auth.views.password_change``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -569,7 +573,7 @@ successful login.
**Optional arguments:**
* ``login_url``: The URL of the login page to redirect to. This
- will default to ``/accounts/login/`` if not supplied.
+ will default to ``settings.LOGIN_URL`` if not supplied.
Built-in manipulators
---------------------
@@ -636,7 +640,7 @@ Note that ``user_passes_test`` does not automatically check that the ``User``
is not anonymous.
``user_passes_test()`` takes an optional ``login_url`` argument, which lets you
-specify the URL for your login page (``/accounts/login/`` by default).
+specify the URL for your login page (``settings.LOGIN_URL`` by default).
Example in Python 2.3 syntax::
@@ -680,7 +684,7 @@ parameter. Example::
my_view = permission_required('polls.can_vote', login_url='/loginpage/')(my_view)
As in the ``login_required`` decorator, ``login_url`` defaults to
-``'/accounts/login/'``.
+``settings.LOGIN_URL``.
Limiting access to generic views
--------------------------------
@@ -757,7 +761,7 @@ This example model creates three custom permissions::
The only thing this does is create those extra permissions when you run
``syncdb``.
-.. _model Meta attribute: ../model_api/#meta-options
+.. _model Meta attribute: ../model-api/#meta-options
API reference
-------------
diff --git a/docs/contributing.txt b/docs/contributing.txt
index 1d2b635b76..d05c166b37 100644
--- a/docs/contributing.txt
+++ b/docs/contributing.txt
@@ -396,10 +396,11 @@ 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_ENGINE``, ``DATABASE_USER`` and ``DATABASE_PASSWORD``.
-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 -- 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.
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
diff --git a/docs/databases.txt b/docs/databases.txt
index 3545b58d47..b73f39843c 100644
--- a/docs/databases.txt
+++ b/docs/databases.txt
@@ -69,9 +69,12 @@ For now, InnoDB is probably your best choice.
MySQLdb
-------
-`MySQLdb`_ is the Python interface to MySQL. 1.2.1 is the first version that
-has support for MySQL 4.1 and newer. If you are trying to use an older version
-of MySQL, then 1.2.0 *might* work for you.
+`MySQLdb`_ is the Python interface to MySQL. Version 1.2.1p2 or later is
+required for full MySQL support in Django. Earlier versions will not work with
+the ``mysql`` backend.
+
+If you are trying to use an older version of MySQL and the ``mysql_old``
+backend, then 1.2.0 *might* work for you.
.. _MySQLdb: http://sourceforge.net/projects/mysql-python
diff --git a/docs/databrowse.txt b/docs/databrowse.txt
new file mode 100644
index 0000000000..e9691cc879
--- /dev/null
+++ b/docs/databrowse.txt
@@ -0,0 +1,56 @@
+==========
+Databrowse
+==========
+
+Databrowse is a Django application that lets you browse your data.
+
+As the Django admin dynamically creates an admin interface by introspecting
+your models, Databrowse dynamically creates a rich, browsable Web site by
+introspecting your models.
+
+.. admonition:: Note
+
+ Databrowse is **very** new and is currently under active development. It
+ may change substantially before the next Django release.
+
+ With that said, it's easy to use, and it doesn't require writing any
+ code. So you can play around with it today, with very little investment in
+ time or coding.
+
+How to use Databrowse
+=====================
+
+ 1. Point Django at the default Databrowse templates. There are two ways to
+ do this:
+
+ * Add ``'django.contrib.databrowse'`` to your ``INSTALLED_APPS``
+ setting. This will work if your ``TEMPLATE_LOADERS`` setting includes
+ the ``app_directories`` template loader (which is the case by
+ default). See the `template loader docs`_ for more.
+
+ * Otherwise, determine the full filesystem path to the
+ ``django/contrib/databrowse/templates`` directory, and add that
+ directory to your ``TEMPLATE_DIRS`` setting.
+
+ 2. Register a number of models with the Databrowse site::
+
+ from django.contrib import databrowse
+
+ databrowse.site.register(SomeModel)
+ databrowse.site.register(SomeOtherModel)
+
+ Note that you should register the model *classes*, not instances.
+
+ It doesn't matter where you put this, as long as it gets executed at
+ some point. A good place for it is in your URLconf file (``urls.py``).
+
+ 3. Add the following line to your URLconf::
+
+ (r'^databrowse/(.*)', databrowse.site.root),
+
+ The prefix doesn't matter -- you can use ``databrowse/`` or ``db/`` or
+ whatever you'd like.
+
+ 4. Run the Django server and visit ``/databrowse/`` in your browser.
+
+.. _template loader docs: ../templates_python/#loader-types
diff --git a/docs/db-api.txt b/docs/db-api.txt
index 64db3def96..9d2f09daf3 100644
--- a/docs/db-api.txt
+++ b/docs/db-api.txt
@@ -6,7 +6,7 @@ Once you've created your `data models`_, Django automatically gives you a
database-abstraction API that lets you create, retrieve, update and delete
objects. This document explains that API.
-.. _`data models`: ../model_api/
+.. _`data models`: ../model-api/
Throughout this reference, we'll refer to the following models, which comprise
a weblog application::
@@ -85,7 +85,7 @@ There's no way to tell what the value of an ID will be before you call
unless you explicitly specify ``primary_key=True`` on a field. See the
`AutoField documentation`_.)
-.. _AutoField documentation: ../model_api/#autofield
+.. _AutoField documentation: ../model-api/#autofield
Explicitly specifying auto-primary-key values
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -112,7 +112,7 @@ the previous record in the database::
b4 = Blog(id=3, name='Not Cheddar', tagline='Anything but cheese.')
b4.save() # Overrides the previous blog with ID=3!
-See _`How Django knows to UPDATE vs. INSERT`, below, for the reason this
+See `How Django knows to UPDATE vs. INSERT`_, below, for the reason this
happens.
Explicitly specifying auto-primary-key values is mostly useful for bulk-saving
@@ -714,7 +714,7 @@ QuerySet methods that do not return QuerySets
The following ``QuerySet`` methods evaluate the ``QuerySet`` and return
something *other than* a ``QuerySet``.
-These methods do not use a cache (see _`Caching and QuerySets` below). Rather,
+These methods do not use a cache (see `Caching and QuerySets`_ below). Rather,
they query the database each time they're called.
``get(**kwargs)``
@@ -906,8 +906,8 @@ The database API supports the following lookup types:
exact
~~~~~
-Exact match. If the value provided for comparison is ``None``, it will
-be interpreted as an SQL ``NULL`` (See isnull_ for more details).
+Exact match. If the value provided for comparison is ``None``, it will
+be interpreted as an SQL ``NULL`` (See isnull_ for more details).
Examples::
@@ -1801,4 +1801,4 @@ interface to your database. You can access your database via other tools,
programming languages or database frameworks; there's nothing Django-specific
about your database.
-.. _Executing custom SQL: ../model_api/#executing-custom-sql
+.. _Executing custom SQL: ../model-api/#executing-custom-sql
diff --git a/docs/distributions.txt b/docs/distributions.txt
index 63206c535e..4ec265f93c 100644
--- a/docs/distributions.txt
+++ b/docs/distributions.txt
@@ -47,16 +47,18 @@ Fedora
------
A Django package is available for `Fedora Linux`_, in the "Fedora Extras"
-repository. The `current Fedora package`_ is based on Django 0.95.1, and can be
-installed by typing ``yum install Django``.
+repository. The `current Fedora package`_ is based on Django 0.96, and can be
+installed by typing ``yum install Django``. The previous link is for the i386
+binary. Users of other architectures should be able to use that as a starting
+point to find their preferred version.
.. _Fedora Linux: http://fedora.redhat.com/
-.. _current Fedora package: http://fedoraproject.org/extras/6/i386/repodata/repoview/Django-0-0.95.1-1.fc6.html
+.. _current Fedora package: http://download.fedora.redhat.com/pub/fedora/linux/extras/6/i386/repoview/Django.html
Gentoo
------
-A Django build is available for `Gentoo Linux`_, and is based on Django 0.95.1.
+A Django build is available for `Gentoo Linux`_, and is based on Django 0.96.
The `current Gentoo build`_ can be installed by typing ``emerge django``.
.. _Gentoo Linux: http://www.gentoo.org/
diff --git a/docs/django-admin.txt b/docs/django-admin.txt
index 388eaf98ac..cc2eadc365 100644
--- a/docs/django-admin.txt
+++ b/docs/django-admin.txt
@@ -29,6 +29,9 @@ Generally, when working on a single Django project, it's easier to use
``--settings`` command line option, if you need to switch between multiple
Django settings files.
+The command-line examples throughout this document use ``django-admin.py`` to
+be consistent, but any example can use ``manage.py`` just as well.
+
Usage
=====
@@ -58,7 +61,7 @@ Prints the admin-index template snippet for the given appnames.
Use admin-index template snippets if you want to customize the look and feel of
your admin's index page. See `Tutorial 2`_ for more information.
-.. _Tutorial 2: ../tutorial2/
+.. _Tutorial 2: ../tutorial02/
createcachetable [tablename]
----------------------------
@@ -100,23 +103,24 @@ if you're ever curious to see the full list of defaults.
dumpdata [appname appname ...]
------------------------------
-Output to standard output all data in the database associated with the named
+Output to standard output all data in the database associated with the named
application(s).
By default, the database will be dumped in JSON format. If you want the output
-to be in another format, use the ``--format`` option (e.g., ``format=xml``).
-You may specify any Django serialization backend (including any user specified
-serialization backends named in the ``SERIALIZATION_MODULES`` setting).
+to be in another format, use the ``--format`` option (e.g., ``format=xml``).
+You may specify any Django serialization backend (including any user specified
+serialization backends named in the ``SERIALIZATION_MODULES`` setting). The
+``--indent`` option can be used to pretty-print the output.
If no application name is provided, all installed applications will be dumped.
-The output of ``dumpdata`` can be used as input for ``loaddata``.
+The output of ``dumpdata`` can be used as input for ``loaddata``.
flush
-----
-Return the database to the state it was in immediately after syncdb was
-executed. This means that all data will be removed from the database, any
+Return the database to the state it was in immediately after syncdb was
+executed. This means that all data will be removed from the database, any
post-synchronization handlers will be re-executed, and the ``initial_data``
fixture will be re-installed.
@@ -178,37 +182,37 @@ Django will search in three locations for fixtures:
3. In the literal path named by the fixture
Django will load any and all fixtures it finds in these locations that match
-the provided fixture names.
+the provided fixture names.
-If the named fixture has a file extension, only fixtures of that type
+If the named fixture has a file extension, only fixtures of that type
will be loaded. For example::
django-admin.py loaddata mydata.json
-
-would only load JSON fixtures called ``mydata``. The fixture extension
-must correspond to the registered name of a serializer (e.g., ``json`` or
+
+would only load JSON fixtures called ``mydata``. The fixture extension
+must correspond to the registered name of a serializer (e.g., ``json`` or
``xml``).
-If you omit the extension, Django will search all available fixture types
+If you omit the extension, Django will search all available fixture types
for a matching fixture. For example::
django-admin.py loaddata mydata
-
+
would look for any fixture of any fixture type called ``mydata``. If a fixture
directory contained ``mydata.json``, that fixture would be loaded
-as a JSON fixture. However, if two fixtures with the same name but different
-fixture type are discovered (for example, if ``mydata.json`` and
-``mydata.xml`` were found in the same fixture directory), fixture
-installation will be aborted, and any data installed in the call to
+as a JSON fixture. However, if two fixtures with the same name but different
+fixture type are discovered (for example, if ``mydata.json`` and
+``mydata.xml`` were found in the same fixture directory), fixture
+installation will be aborted, and any data installed in the call to
``loaddata`` will be removed from the database.
-The fixtures that are named can include directory components. These
+The fixtures that are named can include directory components. These
directories will be included in the search path. For example::
django-admin.py loaddata foo/bar/mydata.json
-
-would search ``<appname>/fixtures/foo/bar/mydata.json`` for each installed
-application, ``<dirname>/foo/bar/mydata.json`` for each directory in
+
+would search ``<appname>/fixtures/foo/bar/mydata.json`` for each installed
+application, ``<dirname>/foo/bar/mydata.json`` for each directory in
``FIXTURE_DIRS``, and the literal path ``foo/bar/mydata.json``.
Note that the order in which fixture files are processed is undefined. However,
@@ -217,16 +221,18 @@ one fixture can reference data in another fixture. If the database backend
supports row-level constraints, these constraints will be checked at the
end of the transaction.
+The ``dumpdata`` command can be used to generate input for ``loaddata``.
+
.. admonition:: MySQL and Fixtures
- Unfortunately, MySQL isn't capable of completely supporting all the
+ Unfortunately, MySQL isn't capable of completely supporting all the
features of Django fixtures. If you use MyISAM tables, MySQL doesn't
- support transactions or constraints, so you won't get a rollback if
- multiple transaction files are found, or validation of fixture data.
- If you use InnoDB tables, you won't be able to have any forward
- references in your data files - MySQL doesn't provide a mechanism to
- defer checking of row constraints until a transaction is committed.
-
+ support transactions or constraints, so you won't get a rollback if
+ multiple transaction files are found, or validation of fixture data.
+ If you use InnoDB tables, you won't be able to have any forward
+ references in your data files - MySQL doesn't provide a mechanism to
+ defer checking of row constraints until a transaction is committed.
+
reset [appname appname ...]
---------------------------
Executes the equivalent of ``sqlreset`` for the given appnames.
@@ -326,7 +332,7 @@ sqlall [appname appname ...]
Prints the CREATE TABLE and initial-data SQL statements for the given appnames.
-Refer to the description of ``sqlinitialdata`` for an explanation of how to
+Refer to the description of ``sqlcustom`` for an explanation of how to
specify initial data.
sqlclear [appname appname ...]
@@ -397,8 +403,8 @@ this command to install the default apps.
If you're installing the ``django.contrib.auth`` application, ``syncdb`` will
give you the option of creating a superuser immediately.
-``syncdb`` will also search for and install any fixture named ``initial_data``.
-See the documentation for ``loaddata`` for details on the specification of
+``syncdb`` will also search for and install any fixture named ``initial_data``.
+See the documentation for ``loaddata`` for details on the specification of
fixture data files.
test
@@ -471,7 +477,7 @@ Example usage::
django-admin.py dumpdata --indent=4
-Specifies the number of spaces that will be used for indentation when
+Specifies the number of spaces that will be used for indentation when
pretty-printing output. By default, output will *not* be pretty-printed.
Pretty-printing will only be enabled if the indent option is provided.
@@ -512,7 +518,8 @@ and `2` is verbose output.
------------
Example usage::
- django-admin.py manage.py --adminmedia=/tmp/new-admin-style/
+
+ django-admin.py --adminmedia=/tmp/new-admin-style/
Tells Django where to find the various CSS and JavaScript files for the admin
interface when running the development server. Normally these files are served
diff --git a/docs/documentation.txt b/docs/documentation.txt
index e72dd47ba1..decb066fa1 100644
--- a/docs/documentation.txt
+++ b/docs/documentation.txt
@@ -94,12 +94,10 @@ Formatting
The text documentation is written in ReST (ReStructured Text) format. That
means it's easy to read but is also formatted in a way that makes it easy to
-convert into other formats, such as HTML. If you're interested, the script that
-converts the ReST text docs into djangoproject.com's HTML lives at
-`djangoproject.com/django_website/apps/docs/parts/build_documentation.py`_ in
-the Django Subversion repository.
+convert into other formats, such as HTML. If you have the `reStructuredText`_
+library installed, you can use ``rst2html`` to generate your own HTML files.
-.. _djangoproject.com/django_website/apps/docs/parts/build_documentation.py: http://code.djangoproject.com/browser/djangoproject.com/django_website/apps/docs/parts/build_documentation.py
+.. _reStructuredText: http://docutils.sourceforge.net/rst.html
Differences between versions
============================
diff --git a/docs/email.txt b/docs/email.txt
index 1f4ce4ef42..66948e5294 100644
--- a/docs/email.txt
+++ b/docs/email.txt
@@ -19,13 +19,23 @@ In two lines::
send_mail('Subject here', 'Here is the message.', 'from@example.com',
['to@example.com'], fail_silently=False)
-
+
+Mail is sent using the SMTP host and port specified in the `EMAIL_HOST`_ and
+`EMAIL_PORT`_ settings. The `EMAIL_HOST_USER`_ and `EMAIL_HOST_PASSWORD`_
+settings, if set, are used to authenticate to the SMTP server, and the
+`EMAIL_USE_TLS`_ setting controls whether a secure connection is used.
+
.. note::
- The character set of email sent with ``django.core.mail`` will be set to
+ The character set of e-mail sent with ``django.core.mail`` will be set to
the value of your `DEFAULT_CHARSET setting`_.
-
-.. _DEFAULT_CHARSET setting: ../settings/#DEFAULT_CHARSET
+
+.. _DEFAULT_CHARSET setting: ../settings/#default-charset
+.. _EMAIL_HOST: ../settings/#email-host
+.. _EMAIL_PORT: ../settings/#email-port
+.. _EMAIL_HOST_USER: ../settings/#email-host-user
+.. _EMAIL_HOST_PASSWORD: ../settings/#email-host-password
+.. _EMAIL_USE_TLS: ../settings/#email-use-tls
send_mail()
===========
@@ -174,3 +184,72 @@ from the request's POST data, sends that to admin@example.com and redirects to
return HttpResponse('Make sure all fields are entered and valid.')
.. _Header injection: http://securephp.damonkohler.com/index.php/Email_Injection
+
+The EmailMessage and SMTPConnection classes
+===========================================
+
+**New in Django development version**
+
+Django's ``send_mail()`` and ``send_mass_mail()`` functions are actually thin
+wrappers that make use of the ``EmailMessage`` and ``SMTPConnection`` classes
+in ``django.core.mail``. If you ever need to customize the way Django sends
+e-mail, you can subclass these two classes to suit your needs.
+
+.. note::
+ Not all features of the ``EmailMessage`` class are available through the
+ ``send_mail()`` and related wrapper functions. If you wish to use advanced
+ features, such as BCC'ed recipients or multi-part e-mail, you'll need to
+ create ``EmailMessage`` instances directly.
+
+In general, ``EmailMessage`` is responsible for creating the e-mail message
+itself. ``SMTPConnection`` is responsible for the network connection side of
+the operation. This means you can reuse the same connection (an
+``SMTPConnection`` instance) for multiple messages.
+
+The ``EmailMessage`` class is initialized as follows::
+
+ email = EmailMessage(subject, body, from_email, to, bcc, connection)
+
+All of these parameters are optional. If ``from_email`` is omitted, the value
+from ``settings.DEFAULT_FROM_EMAIL`` is used. Both the ``to`` and ``bcc``
+parameters are lists of addresses, as strings.
+
+For example::
+
+ email = EmailMessage('Hello', 'Body goes here', 'from@example.com',
+ ['to1@example.com', 'to2@example.com'],
+ ['bcc@example.com'])
+
+The class has the following methods:
+
+ * ``send()`` sends the message, using either the connection that is
+ specified in the ``connection`` attribute, or creating a new connection
+ if none already exists.
+
+ * ``message()`` constructs a ``django.core.mail.SafeMIMEText`` object (a
+ sub-class of Python's ``email.MIMEText.MIMEText`` class) holding the
+ message to be sent. If you ever need to extend the `EmailMessage` class,
+ you'll probably want to override this method to put the content you wish
+ into the MIME object.
+
+ * ``recipients()`` returns a list of all the recipients of the message,
+ whether they're recorded in the ``to`` or ``bcc`` attributes. This is
+ another method you might need to override when sub-classing, because the
+ SMTP server needs to be told the full list of recipients when the message
+ is sent. If you add another way to specify recipients in your class, they
+ need to be returned from this method as well.
+
+The ``SMTPConnection`` class is initialized with the host, port, username and
+password for the SMTP server. If you don't specify one or more of those
+options, they are read from your settings file.
+
+If you're sending lots of messages at once, the ``send_messages()`` method of
+the ``SMTPConnection`` class is useful. It takes a list of ``EmailMessage``
+instances (or subclasses) and sends them over a single connection. For example,
+if you have a function called ``get_notification_email()`` that returns a
+list of ``EmailMessage`` objects representing some periodic e-mail you wish to
+send out, you could send this with::
+
+ connection = SMTPConnection() # Use default settings for connection
+ messages = get_notification_email()
+ connection.send_messages(messages)
diff --git a/docs/faq.txt b/docs/faq.txt
index 202b73c6be..bdd8c5360e 100644
--- a/docs/faq.txt
+++ b/docs/faq.txt
@@ -278,7 +278,7 @@ How do I get started?
.. _`Download the code`: http://www.djangoproject.com/download/
.. _`installation guide`: ../install/
-.. _tutorial: ../tutorial1/
+.. _tutorial: ../tutorial01/
.. _documentation: ../
.. _ask questions: http://www.djangoproject.com/community/
@@ -512,7 +512,7 @@ type, create an initial data file and put something like this in it::
As explained in the `SQL initial data file`_ documentation, this SQL file can
contain arbitrary SQL, so you can make any sorts of changes you need to make.
-.. _SQL initial data file: ../model_api/#providing-initial-sql-data
+.. _SQL initial data file: ../model-api/#providing-initial-sql-data
Why is Django leaking memory?
-----------------------------
diff --git a/docs/flatpages.txt b/docs/flatpages.txt
index cb910e812d..1422f16b6b 100644
--- a/docs/flatpages.txt
+++ b/docs/flatpages.txt
@@ -84,9 +84,9 @@ Flatpages are represented by a standard `Django model`_, which lives in
`django/contrib/flatpages/models.py`_. You can access flatpage objects via the
`Django database API`_.
-.. _Django model: ../model_api/
+.. _Django model: ../model-api/
.. _django/contrib/flatpages/models.py: http://code.djangoproject.com/browser/django/trunk/django/contrib/flatpages/models.py
-.. _Django database API: ../db_api/
+.. _Django database API: ../db-api/
Flatpage templates
==================
diff --git a/docs/forms.txt b/docs/forms.txt
index ce1010235f..329e84a1b1 100644
--- a/docs/forms.txt
+++ b/docs/forms.txt
@@ -517,7 +517,7 @@ to put punctuation at the end of your validation messages.
When are validators called?
---------------------------
-After a form has been submitted, Django validates each field in turn. First,
+After a form has been submitted, Django validates each field in turn. First,
if the field is required, Django checks that it is present and non-empty. Then,
if that test passes *and the form submission contained data* for that field, all
the validators for that field are called in turn. The emphasized portion in the
@@ -615,15 +615,19 @@ fails. If no message is passed in, a default message is used.
``other_value``, then the validators in ``validator_list`` are all run
against the current field.
+``RequiredIfOtherFieldGiven``
+ Takes a field name of the current field is only required if the other
+ field has a value.
+
+``RequiredIfOtherFieldsGiven``
+ Similar to ``RequiredIfOtherFieldGiven``, except that it takes a list of
+ field names and if any one of the supplied fields has a value provided,
+ the current field being validated is required.
+
``RequiredIfOtherFieldNotGiven``
Takes the name of the other field and this field is only required if the
other field has no value.
-``RequiredIfOtherFieldsNotGiven``
- Similar to ``RequiredIfOtherFieldNotGiven``, except that it takes a list
- of field names and if any one of the supplied fields does not have a value
- provided, the field being validated is required.
-
``RequiredIfOtherFieldEquals`` and ``RequiredIfOtherFieldDoesNotEqual``
Each of these validator classes takes a field name and a value (in that
order). If the given field does (or does not have, in the latter case) the
@@ -650,8 +654,8 @@ fails. If no message is passed in, a default message is used.
``NumberIsInRange``
Takes two boundary numbers, ``lower`` and ``upper``, and checks that the
field is greater than ``lower`` (if given) and less than ``upper`` (if
- given).
-
+ given).
+
Both checks are inclusive. That is, ``NumberIsInRange(10, 20)`` will allow
values of both 10 and 20. This validator only checks numeric values
(e.g., float and integer values).
@@ -691,5 +695,5 @@ fails. If no message is passed in, a default message is used.
document for more details).
.. _`generic views`: ../generic_views/
-.. _`models API`: ../model_api/
+.. _`models API`: ../model-api/
.. _settings: ../settings/
diff --git a/docs/generic_views.txt b/docs/generic_views.txt
index 0496a58691..bb5f7320f6 100644
--- a/docs/generic_views.txt
+++ b/docs/generic_views.txt
@@ -44,7 +44,7 @@ simple weblog app that drives the blog on djangoproject.com::
(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),
- (r'^/?$', 'archive_index', info_dict),
+ (r'^$', 'archive_index', info_dict),
)
As you can see, this URLconf defines a few options in ``info_dict``.
@@ -71,7 +71,7 @@ are first evaluated, so if you want to pass in a QuerySet via
``extra_context`` that is always fresh you need to wrap it in a function or
lambda that returns the QuerySet.
-.. _database API docs: ../db_api/
+.. _database API docs: ../db-api/
"Simple" generic views
======================
diff --git a/docs/i18n.txt b/docs/i18n.txt
index 4a05e53ddf..1d7a0063b2 100644
--- a/docs/i18n.txt
+++ b/docs/i18n.txt
@@ -175,7 +175,7 @@ class, though::
verbose_name = _('my thing')
verbose_name_plural = _('mythings')
-.. _Django models: ../model_api/
+.. _Django models: ../model-api/
Pluralization
~~~~~~~~~~~~~
@@ -310,7 +310,7 @@ To create or update a message file, run this command::
...where ``de`` is the language code for the message file you want to create.
The language code, in this case, is in locale format. For example, it's
-``pt_BR`` for Brazilian and ``de_AT`` for Austrian German.
+``pt_BR`` for Brazilian Portugese and ``de_AT`` for Austrian German.
The script should be run from one of three places:
@@ -463,8 +463,8 @@ following this algorithm:
Notes:
* In each of these places, the language preference is expected to be in the
- standard language format, as a string. For example, Brazilian is
- ``pt-br``.
+ standard language format, as a string. For example, Brazilian Portugese
+ is ``pt-br``.
* If a base language is available but the sublanguage specified is not,
Django uses the base language. For example, if a user specifies ``de-at``
(Austrian German) but Django only has ``de`` available, Django uses
diff --git a/docs/install.txt b/docs/install.txt
index dbbde93f83..6be52aab0d 100644
--- a/docs/install.txt
+++ b/docs/install.txt
@@ -45,19 +45,20 @@ 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_
-(recommended), MySQL_ and SQLite_.
+make sure a database server is running. Django works with PostgreSQL_,
+MySQL_ and SQLite_.
Additionally, you'll need to make sure your Python database bindings are
installed.
-* If you're using PostgreSQL, you'll need the psycopg_ package (version 2 is
- recommended with ``postgresql_psycopg2`` backend, version 1.1 works also with the
- ``postgresql``` backend).
-
+* If you're using PostgreSQL, you'll need the psycopg_ package. Django supports
+ both version 1 and 2. (When you configure Django's database layer, specify
+ either ``postgresql`` [for version 1] or ``postgresql_psycopg2`` [for version 2].)
+
If you're on Windows, check out the unofficial `compiled Windows version`_.
-
+
* If you're using MySQL, you'll need MySQLdb_, version 1.2.1p2 or higher.
+ You will also want to read the database-specific notes for the `MySQL backend`_.
* If you're using SQLite, you'll need pysqlite_. Use version 2.0.3 or higher.
@@ -69,6 +70,34 @@ installed.
.. _MySQLdb: http://sourceforge.net/projects/mysql-python
.. _SQLite: http://www.sqlite.org/
.. _pysqlite: http://initd.org/tracker/pysqlite
+.. _MySQL backend: ../databases/
+
+Remove any old versions of Django
+=================================
+
+If you are upgrading your installation of Django from a previous version,
+you will need to uninstall the old Django version before installing the
+new version.
+
+If you installed Django using ``setup.py install``, uninstalling
+is as simple as deleting the ``django`` directory from your Python
+``site-packages``.
+
+If you installed Django from a Python Egg, remove the Django ``.egg`` file,
+and remove the reference to the egg in the file named ``easy-install.pth``.
+This file should also be located in your ``site-packages`` directory.
+
+.. admonition:: Where are my ``site-packages`` stored?
+
+ The location of the ``site-packages`` directory depends on the operating
+ system, and the location in which Python was installed. However, the
+ following locations are common:
+
+ * If you're using Linux: ``/usr/lib/python2.X/site-packages``
+
+ * If you're using Windows: ``C:\Python2.X\lib\site-packages``
+
+ * If you're using MacOSX: ``/Library/Python2.X/site-packages``
Install the Django code
=======================
diff --git a/docs/legacy_databases.txt b/docs/legacy_databases.txt
index 8230c11f61..ca3927e52f 100644
--- a/docs/legacy_databases.txt
+++ b/docs/legacy_databases.txt
@@ -9,7 +9,7 @@ utilities to automate as much of this process as possible.
This document assumes you know the Django basics, as covered in the
`official tutorial`_.
-.. _official tutorial: ../tutorial1/
+.. _official tutorial: ../tutorial01/
Give Django your database parameters
====================================
@@ -39,11 +39,11 @@ Auto-generate the models
Django comes with a utility that can create models by introspecting an existing
database. You can view the output by running this command::
- django-admin.py inspectdb --settings=path.to.settings
+ python manage.py inspectdb
Save this as a file by using standard Unix output redirection::
- django-admin.py inspectdb --settings=path.to.settings > models.py
+ python manage.py inspectdb > models.py
This feature is meant as a shortcut, not as definitive model generation. See
the `django-admin.py documentation`_ for more information.
@@ -52,7 +52,7 @@ Once you've cleaned up your models, name the file ``models.py`` and put it in
the Python package that holds your app. Then add the app to your
``INSTALLED_APPS`` setting.
-.. _django-admin.py documentation: ../django_admin/
+.. _django-admin.py documentation: ../django-admin/
Install the core Django tables
==============================
@@ -60,7 +60,7 @@ Install the core Django tables
Next, run the ``manage.py syncdb`` command to install any extra needed database
records such as admin permissions and content types::
- django-admin.py init --settings=path.to.settings
+ python manage.py syncdb
See whether it worked
=====================
diff --git a/docs/model-api.txt b/docs/model-api.txt
index a03ed09eb2..961269aebd 100644
--- a/docs/model-api.txt
+++ b/docs/model-api.txt
@@ -21,7 +21,7 @@ A companion to this document is the `official repository of model examples`_.
(In the Django source distribution, these examples are in the
``tests/modeltests`` directory.)
-.. _Database API reference: http://www.djangoproject.com/documentation/db_api/
+.. _Database API reference: ../db-api/
.. _official repository of model examples: http://www.djangoproject.com/documentation/models/
Quick example
@@ -57,7 +57,7 @@ Some technical notes:
syntax, but it's worth noting Django uses SQL tailored to the database
backend specified in your `settings file`_.
-.. _settings file: http://www.djangoproject.com/documentation/settings/
+.. _settings file: ../settings/
Fields
======
@@ -194,14 +194,23 @@ This doesn't accept ``maxlength``; its ``maxlength`` is automatically set to
``FileField``
~~~~~~~~~~~~~
-A file-upload field.
+A file-upload field. Has one **required** argument:
-Has an extra required argument, ``upload_to``, a local filesystem path to
-which files should be upload. This path may contain `strftime formatting`_,
-which will be replaced by the date/time of the file upload (so that
-uploaded files don't fill up the given directory).
+ ====================== ===================================================
+ Argument Description
+ ====================== ===================================================
+ ``upload_to`` A local filesystem path that will be appended to
+ your ``MEDIA_ROOT`` setting to determine the
+ output of the ``get_<fieldname>_url()`` helper
+ function.
+ ====================== ===================================================
+
+This path may contain `strftime formatting`_, which will be replaced by the
+date/time of the file upload (so that uploaded files don't fill up the given
+directory).
-The admin represents this as an ``<input type="file">`` (a file-upload widget).
+The admin represents this field as an ``<input type="file">`` (a file-upload
+widget).
Using a ``FileField`` or an ``ImageField`` (see below) in a model takes a few
steps:
@@ -246,7 +255,7 @@ visiting its URL on your site. Don't allow that.
A field whose choices are limited to the filenames in a certain directory
on the filesystem. Has three special arguments, of which the first is
-required:
+**required**:
====================== ===================================================
Argument Description
@@ -450,7 +459,7 @@ string, not ``NULL``.
``blank``
~~~~~~~~~
-If ``True``, the field is allowed to be blank.
+If ``True``, the field is allowed to be blank. Default is ``False``.
Note that this is different than ``null``. ``null`` is purely
database-related, whereas ``blank`` is validation-related. If a field has
@@ -501,7 +510,7 @@ 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
`get_FOO_display`_ in the database API documentation.
-.. _get_FOO_display: ../db_api/#get-foo-display
+.. _get_FOO_display: ../db-api/#get-foo-display
Finally, note that choices can be any iterable object -- not necessarily a
list or tuple. This lets you construct choices dynamically. But if you find
@@ -626,7 +635,7 @@ that takes the parameters ``field_data, all_data`` and raises
Django comes with quite a few validators. They're in ``django.core.validators``.
-.. _validator docs: http://www.djangoproject.com/documentation/forms/#validators
+.. _validator docs: ../forms/#validators
Verbose field names
-------------------
@@ -734,10 +743,10 @@ relationship should work. All are optional:
``limit_choices_to`` A dictionary of lookup arguments and values (see
the `Database API reference`_) that limit the
available admin choices for this object. Use this
- with ``models.LazyDate`` to limit choices of objects
- by date. For example::
+ with functions from the Python ``datetime`` module
+ to limit choices of objects by date. For example::
- limit_choices_to = {'pub_date__lte': models.LazyDate()}
+ limit_choices_to = {'pub_date__lte': datetime.now}
only allows the choice of related objects with a
``pub_date`` before the current date/time to be
@@ -792,8 +801,8 @@ relationship should work. All are optional:
the related object.
======================= ============================================================
-.. _`Database API reference`: http://www.djangoproject.com/documentation/db_api/
-.. _related objects documentation: http://www.djangoproject.com/documentation/db_api/#related-objects
+.. _`Database API reference`: ../db-api/
+.. _related objects documentation: ../db-api/#related-objects
Many-to-many relationships
~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -963,7 +972,7 @@ Example::
See the `docs for latest()`_ for more.
-.. _docs for latest(): http://www.djangoproject.com/documentation/db_api/#latest-field-name-none
+.. _docs for latest(): ../db-api/#latest-field-name-none
``order_with_respect_to``
-------------------------
@@ -1397,7 +1406,7 @@ if one of the ``list_display`` fields is a ``ForeignKey``.
For more on ``select_related()``, see `the select_related() docs`_.
-.. _the select_related() docs: http://www.djangoproject.com/documentation/db_api/#select-related
+.. _the select_related() docs: ../db-api/#select-related
``ordering``
------------
@@ -1502,7 +1511,7 @@ The way ``Manager`` classes work is documented in the `Retrieving objects`_
section of the database API docs, but this section specifically touches on
model options that customize ``Manager`` behavior.
-.. _Retrieving objects: http://www.djangoproject.com/documentation/db_api/#retrieving-objects
+.. _Retrieving objects: ../db-api/#retrieving-objects
Manager names
-------------
@@ -1825,7 +1834,7 @@ just the ``where``, ``tables`` and ``params`` arguments to the standard lookup
API. See `Other lookup options`_.
.. _Python DB-API: http://www.python.org/peps/pep-0249.html
-.. _Other lookup options: http://www.djangoproject.com/documentation/db_api/#extra-params-select-where-tables
+.. _Other lookup options: ../db-api/#extra-params-select-where-tables
Overriding default model methods
--------------------------------
@@ -1858,7 +1867,7 @@ You can also prevent saving::
else:
super(Blog, self).save() # Call the "real" save() method.
-.. _database API docs: http://www.djangoproject.com/documentation/db_api/
+.. _database API docs: ../db-api/
Models across files
===================
@@ -1915,7 +1924,7 @@ Each SQL file, if given, is expected to contain valid SQL. The SQL files are
piped directly into the database after all of the models' table-creation
statements have been executed.
-The SQL files are read by the ``sqlinitialdata``, ``sqlreset``, ``sqlall`` and
+The SQL files are read by the ``sqlcustom``, ``sqlreset``, ``sqlall`` and
``reset`` commands in ``manage.py``. Refer to the `manage.py documentation`_
for more information.
@@ -1924,7 +1933,7 @@ order in which they're executed. The only thing you can assume is that, by the
time your custom data files are executed, all the database tables already will
have been created.
-.. _`manage.py documentation`: http://www.djangoproject.com/documentation/django_admin/#sqlinitialdata-appname-appname
+.. _`manage.py documentation`: ../django-admin/#sqlcustom-appname-appname
Database-backend-specific SQL data
----------------------------------
diff --git a/docs/overview.txt b/docs/overview.txt
index 35af75bf05..7b3559663a 100644
--- a/docs/overview.txt
+++ b/docs/overview.txt
@@ -297,5 +297,5 @@ 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/tutorial1/
+.. _the tutorial: http://www.djangoproject.com/documentation/tutorial01/
.. _the community: http://www.djangoproject.com/community/
diff --git a/docs/redirects.txt b/docs/redirects.txt
index 5f84f28097..4df60d473f 100644
--- a/docs/redirects.txt
+++ b/docs/redirects.txt
@@ -66,6 +66,6 @@ Redirects are represented by a standard `Django model`_, which lives in
`django/contrib/redirects/models.py`_. You can access redirect
objects via the `Django database API`_.
-.. _Django model: ../model_api/
+.. _Django model: ../model-api/
.. _django/contrib/redirects/models.py: http://code.djangoproject.com/browser/django/trunk/django/contrib/redirects/models.py
-.. _Django database API: ../db_api/
+.. _Django database API: ../db-api/
diff --git a/docs/request_response.txt b/docs/request_response.txt
index c0272461ca..0b985d563b 100644
--- a/docs/request_response.txt
+++ b/docs/request_response.txt
@@ -93,6 +93,7 @@ All attributes except ``session`` should be considered read-only.
* ``CONTENT_TYPE``
* ``HTTP_ACCEPT_ENCODING``
* ``HTTP_ACCEPT_LANGUAGE``
+ * ``HTTP_HOST`` -- The HTTP Host header sent by the client.
* ``HTTP_REFERER`` -- The referring page, if any.
* ``HTTP_USER_AGENT`` -- The client's user-agent string.
* ``QUERY_STRING`` -- The query string, as a single (unparsed) string.
diff --git a/docs/serialization.txt b/docs/serialization.txt
index 48ab46f0f9..3216cb061e 100644
--- a/docs/serialization.txt
+++ b/docs/serialization.txt
@@ -27,7 +27,7 @@ data to (see `Serialization formats`_) and a QuerySet_ to serialize.
(Actually, the second argument can be any iterator that yields Django objects,
but it'll almost always be a QuerySet).
-.. _QuerySet: ../db_api/#retrieving-objects
+.. _QuerySet: ../db-api/#retrieving-objects
You can also use a serializer object directly::
@@ -109,7 +109,7 @@ serializer, you must pass ``ensure_ascii=False`` as a parameter to the
For example::
- json_serializer = serializers.get_serializer("json")
+ json_serializer = serializers.get_serializer("json")()
json_serializer.serialize(queryset, ensure_ascii=False, stream=response)
Writing custom serializers
diff --git a/docs/sessions.txt b/docs/sessions.txt
index 55fbc2c3da..c7124ba703 100644
--- a/docs/sessions.txt
+++ b/docs/sessions.txt
@@ -107,7 +107,7 @@ posts a comment. It doesn't let a user post a comment more than once::
This simplistic view logs in a "member" of the site::
def login(request):
- m = members.get_object(username__exact=request.POST['username'])
+ m = Member.objects.get(username=request.POST['username'])
if m.password == request.POST['password']:
request.session['member_id'] = m.id
return HttpResponse("You're logged in.")
diff --git a/docs/settings.txt b/docs/settings.txt
index 63b5cceef9..72c6e4ce54 100644
--- a/docs/settings.txt
+++ b/docs/settings.txt
@@ -59,7 +59,7 @@ Use the ``--settings`` command-line argument to specify the settings manually::
django-admin.py runserver --settings=mysite.settings
-.. _django-admin.py: ../django_admin/
+.. _django-admin.py: ../django-admin/
On the server (mod_python)
--------------------------
@@ -102,7 +102,7 @@ between the current settings file and Django's default settings.
For more, see the `diffsettings documentation`_.
-.. _diffsettings documentation: ../django_admin/#diffsettings
+.. _diffsettings documentation: ../django-admin/#diffsettings
Using settings in Python code
=============================
@@ -395,8 +395,10 @@ EMAIL_HOST_PASSWORD
Default: ``''`` (Empty string)
-Username to use for the SMTP server defined in ``EMAIL_HOST``. If empty,
-Django won't attempt authentication.
+Password to use for the SMTP server defined in ``EMAIL_HOST``. This setting is
+used in conjunction with ``EMAIL_HOST_USER`` when authenticating to the SMTP
+server. If either of these settings is empty, Django won't attempt
+authenticaion.
See also ``EMAIL_HOST_USER``.
@@ -426,6 +428,15 @@ Subject-line prefix for e-mail messages sent with ``django.core.mail.mail_admins
or ``django.core.mail.mail_managers``. You'll probably want to include the
trailing space.
+EMAIL_USE_TLS
+-------------
+
+**New in Django development version**
+
+Default: ``False``
+
+Whether to use a TLS (secure) connection when talking to the SMTP server.
+
FIXTURE_DIRS
-------------
@@ -462,7 +473,7 @@ A tuple of strings designating all applications that are enabled in this Django
installation. Each string should be a full Python path to a Python package that
contains a Django application, as created by `django-admin.py startapp`_.
-.. _django-admin.py startapp: ../django_admin/#startapp-appname
+.. _django-admin.py startapp: ../django-admin/#startapp-appname
INTERNAL_IPS
------------
@@ -498,44 +509,17 @@ in standard language format. For example, U.S. English is ``"en-us"``. See the
LANGUAGES
---------
-Default: A tuple of all available languages. Currently, this is::
+Default: A tuple of all available languages. This list is continually growing
+and including a copy here would inevitably become rapidly out of date. You can
+see the current list of translated languages by looking in
+``django/conf/global_settings.py`` (or view the `online source`_).
- LANGUAGES = (
- ('ar', _('Arabic')),
- ('bn', _('Bengali')),
- ('cs', _('Czech')),
- ('cy', _('Welsh')),
- ('da', _('Danish')),
- ('de', _('German')),
- ('el', _('Greek')),
- ('en', _('English')),
- ('es', _('Spanish')),
- ('es_AR', _('Argentinean Spanish')),
- ('fr', _('French')),
- ('gl', _('Galician')),
- ('hu', _('Hungarian')),
- ('he', _('Hebrew')),
- ('is', _('Icelandic')),
- ('it', _('Italian')),
- ('ja', _('Japanese')),
- ('nl', _('Dutch')),
- ('no', _('Norwegian')),
- ('pt-br', _('Brazilian')),
- ('ro', _('Romanian')),
- ('ru', _('Russian')),
- ('sk', _('Slovak')),
- ('sl', _('Slovenian')),
- ('sr', _('Serbian')),
- ('sv', _('Swedish')),
- ('ta', _('Tamil')),
- ('uk', _('Ukrainian')),
- ('zh-cn', _('Simplified Chinese')),
- ('zh-tw', _('Traditional Chinese')),
- )
+.. _online source: http://code.djangoproject.com/browser/django/trunk/django/conf/global_settings.py
-A tuple of two-tuples in the format (language code, language name). This
-specifies which languages are available for language selection. See the
-`internationalization docs`_ for details.
+The list is a tuple of two-tuples in the format (language code, language
+name) -- for example, ``('ja', 'Japanese')``. This specifies which languages
+are available for language selection. See the `internationalization docs`_ for
+details.
Generally, the default value should suffice. Only set this setting if you want
to restrict language selection to a subset of the Django-provided languages.
@@ -562,6 +546,37 @@ 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.
+LOGIN_REDIRECT_URL
+------------------
+
+**New in Django development version**
+
+Default: ``'/accounts/profile/'``
+
+The URL where requests are redirected after login when the
+``contrib.auth.login`` view gets no ``next`` parameter.
+
+This is used by the `@login_required`_ decorator, for example.
+
+LOGIN_URL
+---------
+
+**New in Django development version**
+
+Default: ``'/accounts/login/'``
+
+The URL where requests are redirected for login, specially when using the
+`@login_required`_ decorator.
+
+LOGOUT_URL
+----------
+
+**New in Django development version**
+
+Default: ``'/accounts/logout/'``
+
+LOGIN_URL counterpart.
+
MANAGERS
--------
@@ -874,7 +889,7 @@ Default: ``Django/<version> (http://www.djangoproject.com/)``
The string to use as the ``User-Agent`` header when checking to see if URLs
exist (see the ``verify_exists`` option on URLField_).
-.. _URLField: ../model_api/#urlfield
+.. _URLField: ../model-api/#urlfield
USE_ETAGS
---------
@@ -1012,6 +1027,8 @@ Also, it's an error to call ``configure()`` more than once, or to call
It boils down to this: Use exactly one of either ``configure()`` or
``DJANGO_SETTINGS_MODULE``. Not both, and not neither.
+.. _@login_required: ../authentication/#the-login-required-decorator
+
Error reporting via e-mail
==========================
diff --git a/docs/sitemaps.txt b/docs/sitemaps.txt
index dafc009859..550f448de1 100644
--- a/docs/sitemaps.txt
+++ b/docs/sitemaps.txt
@@ -2,8 +2,6 @@
The sitemap framework
=====================
-**New in Django development version**.
-
Django comes with a high-level sitemap-generating framework that makes
creating sitemap_ XML files easy.
diff --git a/docs/sites.txt b/docs/sites.txt
index 7497d7dd80..12259b04c3 100644
--- a/docs/sites.txt
+++ b/docs/sites.txt
@@ -276,8 +276,8 @@ you want your admin site to have access to all objects (not just site-specific
ones), put ``objects = models.Manager()`` in your model, before you define
``CurrentSiteManager``.
-.. _manager: ../model_api/#managers
-.. _manager documentation: ../model_api/#managers
+.. _manager: ../model-api/#managers
+.. _manager documentation: ../model-api/#managers
How Django uses the sites framework
===================================
diff --git a/docs/syndication_feeds.txt b/docs/syndication_feeds.txt
index a64914de3f..d9d4f53b88 100644
--- a/docs/syndication_feeds.txt
+++ b/docs/syndication_feeds.txt
@@ -114,6 +114,9 @@ Note:
`object-relational mapper`_, ``items()`` doesn't have to return model
instances. Although you get a few bits of functionality "for free" by
using Django models, ``items()`` can return any type of object you want.
+ * If you're creating an Atom feed, rather than an RSS feed, set the
+ ``subtitle`` attribute instead of the ``description`` attribute. See
+ `Publishing Atom and RSS feeds in tandem`_, later, for an example.
One thing's left to do. In an RSS feed, each ``<item>`` has a ``<title>``,
``<link>`` and ``<description>``. We need to tell the framework what data to
@@ -156,7 +159,7 @@ put into those elements.
{{ obj.description }}
.. _chicagocrime.org: http://www.chicagocrime.org/
-.. _object-relational mapper: ../db_api/
+.. _object-relational mapper: ../db-api/
.. _Django templates: ../templates/
A complex example
@@ -298,7 +301,7 @@ Publishing Atom and RSS feeds in tandem
---------------------------------------
Some developers like to make available both Atom *and* RSS versions of their
-feeds. That's easy to do with Django: Just create a subclass of your ``feed``
+feeds. That's easy to do with Django: Just create a subclass of your ``Feed``
class and set the ``feed_type`` to something different. Then update your
URLconf to add the extra versions.
@@ -318,6 +321,20 @@ Here's a full example::
class AtomSiteNewsFeed(RssSiteNewsFeed):
feed_type = Atom1Feed
+ subtitle = RssSiteNewsFeed.description
+
+.. Note::
+ In this example, the RSS feed uses a ``description`` while the Atom feed
+ uses a ``subtitle``. That's because Atom feeds don't provide for a
+ feed-level "description," but they *do* provide for a "subtitle."
+
+ If you provide a ``description`` in your ``Feed`` class, Django will *not*
+ automatically put that into the ``subtitle`` element, because a subtitle
+ and description are not necessarily the same thing. Instead, you should
+ define a ``subtitle`` attribute.
+
+ In the above example, we simply set the Atom feed's ``subtitle`` to the
+ RSS feed's ``description``, because it's quite short already.
And the accompanying URLconf::
@@ -629,15 +646,15 @@ This example illustrates all possible attributes and methods for a ``Feed`` clas
def item_enclosure_mime_type(self, item):
"""
Takes an item, as returned by items(), and returns the item's
- enclosure mime type.
+ enclosure MIME type.
"""
def item_enclosure_mime_type(self):
"""
- Returns the enclosure length, in bytes, for every item in the feed.
+ Returns the enclosure MIME type for every item in the feed.
"""
- item_enclosure_mime_type = "audio/mpeg" # Hard-coded enclosure mime-type.
+ item_enclosure_mime_type = "audio/mpeg" # Hard-coded enclosure MIME type.
# ITEM PUBDATE -- It's optional to use one of these three. This is a
# hook that specifies how to get the pubdate for a given item.
diff --git a/docs/templates.txt b/docs/templates.txt
index d93ee49ac1..2f9f769b96 100644
--- a/docs/templates.txt
+++ b/docs/templates.txt
@@ -702,11 +702,11 @@ Example::
Note that you can backslash-escape a format string if you want to use the
"raw" value. In this example, "f" is backslash-escaped, because otherwise
"f" is a format string that displays the time. The "o" doesn't need to be
-escaped, because it's not a format character.::
+escaped, because it's not a format character::
It is the {% now "jS o\f F" %}
-(Displays "It is the 4th of September" %}
+This would display as "It is the 4th of September".
regroup
~~~~~~~
@@ -1293,3 +1293,11 @@ A collection of template filters that implement these common markup languages:
* Textile
* Markdown
* ReST (ReStructured Text)
+
+django.contrib.webdesign
+------------------------
+
+A collection of template tags that can be useful while designing a website,
+such as a generator of Lorem Ipsum text. See the `webdesign documentation`_.
+
+.. _webdesign documentation: ../webdesign/
diff --git a/docs/templates_python.txt b/docs/templates_python.txt
index 5dd8e4fde0..08a287f572 100644
--- a/docs/templates_python.txt
+++ b/docs/templates_python.txt
@@ -212,21 +212,24 @@ template tags. If an invalid variable is provided to one of these template
tags, the variable will be interpreted as ``None``. Filters are always
applied to invalid variables within these template tags.
+If ``TEMPLATE_STRING_IF_INVALID`` contains a ``'%s'``, the format marker will
+be replaced with the name of the invalid variable.
+
.. admonition:: For debug purposes only!
- While ``TEMPLATE_STRING_IF_INVALID`` can be a useful debugging tool,
- it is a bad idea to turn it on as a 'development default'.
+ While ``TEMPLATE_STRING_IF_INVALID`` can be a useful debugging tool,
+ it is a bad idea to turn it on as a 'development default'.
- Many templates, including those in the Admin site, rely upon the
- silence of the template system when a non-existent variable is
+ Many templates, including those in the Admin site, rely upon the
+ silence of the template system when a non-existent variable is
encountered. If you assign a value other than ``''`` to
- ``TEMPLATE_STRING_IF_INVALID``, you will experience rendering
+ ``TEMPLATE_STRING_IF_INVALID``, you will experience rendering
problems with these templates and sites.
- Generally, ``TEMPLATE_STRING_IF_INVALID`` should only be enabled
- in order to debug a specific template problem, then cleared
+ Generally, ``TEMPLATE_STRING_IF_INVALID`` should only be enabled
+ in order to debug a specific template problem, then cleared
once debugging is complete.
-
+
Playing with Context objects
----------------------------
@@ -345,7 +348,7 @@ If ``TEMPLATE_CONTEXT_PROCESSORS`` contains this processor, every
``request.user.get_and_delete_messages()`` for every request. That method
collects the user's messages and deletes them from the database.
- Note that messages are set with ``user.add_message()``. See the
+ Note that messages are set with ``user.message_set.create``. See the
`message docs`_ for more.
* ``perms`` -- An instance of
@@ -714,7 +717,7 @@ object::
# split_contents() knows not to split quoted strings.
tag_name, format_string = token.split_contents()
except ValueError:
- raise template.TemplateSyntaxError, "%r tag requires a single argument" % token.contents[0]
+ raise template.TemplateSyntaxError, "%r tag requires a single argument" % token.contents.split()[0]
if not (format_string[0] == format_string[-1] and format_string[0] in ('"', "'")):
raise template.TemplateSyntaxError, "%r tag's argument should be in quotes" % tag_name
return CurrentTimeNode(format_string[1:-1])
@@ -843,7 +846,7 @@ Now your tag should begin to look like this::
# split_contents() knows not to split quoted strings.
tag_name, date_to_be_formatted, format_string = token.split_contents()
except ValueError:
- raise template.TemplateSyntaxError, "%r tag requires exactly two arguments" % token.contents[0]
+ raise template.TemplateSyntaxError, "%r tag requires exactly two arguments" % token.contents.split()[0]
if not (format_string[0] == format_string[-1] and format_string[0] in ('"', "'")):
raise template.TemplateSyntaxError, "%r tag's argument should be in quotes" % tag_name
return FormatTimeNode(date_to_be_formatted, format_string[1:-1])
@@ -866,7 +869,7 @@ current context, available in the ``render`` method::
try:
actual_date = resolve_variable(self.date_to_be_formatted, context)
return actual_date.strftime(self.format_string)
- except VariableDoesNotExist:
+ except template.VariableDoesNotExist:
return ''
``resolve_variable`` will try to resolve ``blog_entry.date_updated`` and then
@@ -1020,7 +1023,7 @@ The ``takes_context`` parameter defaults to ``False``. When it's set to *True*,
the tag is passed the context object, as in this example. That's the only
difference between this case and the previous ``inclusion_tag`` example.
-.. _tutorials: ../tutorial1/#creating-models
+.. _tutorials: ../tutorial01/#creating-models
Setting a variable in the context
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -1077,7 +1080,7 @@ class, like so::
# Splitting by None == splitting by spaces.
tag_name, arg = token.contents.split(None, 1)
except ValueError:
- raise template.TemplateSyntaxError, "%r tag requires arguments" % token.contents[0]
+ raise template.TemplateSyntaxError, "%r tag requires arguments" % token.contents.split()[0]
m = re.search(r'(.*?) as (\w+)', arg)
if not m:
raise template.TemplateSyntaxError, "%r tag had invalid arguments" % tag_name
diff --git a/docs/testing.txt b/docs/testing.txt
index 5b27ae6484..b44b67c20a 100644
--- a/docs/testing.txt
+++ b/docs/testing.txt
@@ -2,19 +2,29 @@
Testing Django applications
===========================
-Automated testing is an extremely useful weapon in the bug-killing arsenal
-of the modern developer. When initially writing code, a test suite can be
-used to validate that code behaves as expected. When refactoring or
-modifying code, tests serve as a guide to ensure that behavior hasn't
-changed unexpectedly as a result of the refactor.
+Automated testing is an extremely useful bug-killing tool for the modern
+Web developer. You can use a collection of tests -- a **test suite** -- to
+to solve, or avoid, a number of problems:
-Testing a web application is a complex task, as there are many
-components of a web application that must be validated and tested. To
-help you test your application, Django provides a test execution
-framework, and range of utilities that can be used to simulate and
-inspect various facets of a web application.
+ * When you're writing new code, you can use tests to validate your code
+ works as expected.
- This testing framework is currently under development, and may change
+ * When you're refactoring or modifying old code, you can use tests to
+ ensure your changes haven't affected your application's behavior
+ unexpectedly.
+
+Testing a Web application is a complex task, because a Web application is made
+of several layers of logic -- from HTTP-level request handling, to form
+validation and processing, to template rendering. With Django's test-execution
+framework and assorted utilities, you can simulate requests, insert test data,
+inspect your application's output and generally verify your code is doing what
+it should be doing.
+
+The best part is, it's really easy.
+
+.. admonition:: Note
+
+ This testing framework is currently under development. It may change
slightly before the next official Django release.
(That's *no* excuse not to write tests, though!)
@@ -166,7 +176,8 @@ To assist in testing various features of your application, Django provides
tools that can be used to establish tests and test conditions.
* `Test Client`_
-* Fixtures_
+* `TestCase`_
+* `Email services`_
Test Client
-----------
@@ -216,21 +227,21 @@ can be invoked on the ``Client`` instance.
``post(path, data={}, content_type=MULTIPART_CONTENT)``
Make a POST request on the provided ``path``. If you provide a content type
- (e.g., ``text/xml`` for an XML payload), the contents of ``data`` will be
- sent as-is in the POST request, using the content type in the HTTP
+ (e.g., ``text/xml`` for an XML payload), the contents of ``data`` will be
+ sent as-is in the POST request, using the content type in the HTTP
``Content-Type`` header.
-
- If you do not provide a value for ``content_type``, the values in
+
+ If you do not provide a value for ``content_type``, the values in
``data`` will be transmitted with a content type of ``multipart/form-data``.
The key-value pairs in the data dictionary will be encoded as a multipart
message and used to create the POST data payload.
-
- To submit multiple values for a given key (for example, to specify
- the selections for a multiple selection list), provide the values as a
+
+ To submit multiple values for a given key (for example, to specify
+ the selections for a multiple selection list), provide the values as a
list or tuple for the required key. For example, a data dictionary of
``{'choices': ('a','b','d')}`` would submit three selected rows for the
field named ``choices``.
-
+
Submitting files is a special case. To POST a file, you need only
provide the file field name as a key, and a file handle to the file you wish to
upload as a value. The Test Client will populate the two POST fields (i.e.,
@@ -246,29 +257,42 @@ can be invoked on the ``Client`` instance.
file name), and `attachment_file` (containing the file data). Note that you
need to manually close the file after it has been provided to the POST.
-``login(path, username, password)``
- In a production site, it is likely that some views will be protected with
- the @login_required decorator provided by ``django.contrib.auth``. Interacting
- with a URL that has been login protected is a slightly complex operation,
- so the Test Client provides a simple method to automate the login process. A
- call to ``login()`` stimulates the series of GET and POST calls required
- to log a user into a @login_required protected view.
+``login(**credentials)``
+ **New in Django development version**
+
+ On a production site, it is likely that some views will be protected from
+ anonymous access through the use of the @login_required decorator, or some
+ other login checking mechanism. The ``login()`` method can be used to
+ simulate the effect of a user logging into the site. As a result of calling
+ this method, the Client will have all the cookies and session data required
+ to pass any login-based tests that may form part of a view.
+
+ In most cases, the ``credentials`` required by this method are the username
+ and password of the user that wants to log in, provided as keyword
+ arguments::
+
+ c = Client()
+ c.login(username='fred', password='secret')
+ # Now you can access a login protected view
+
+ If you are using a different authentication backend, this method may
+ require different credentials.
- If login is possible, the final return value of ``login()`` is the response
- that is generated by issuing a GET request on the protected URL. If login
- is not possible, ``login()`` returns False.
+ ``login()`` returns ``True`` if it the credentials were accepted and login
+ was successful.
Note that since the test suite will be executed using the test database,
- which contains no users by default. As a result, logins for your production
- site will not work. You will need to create users as part of the test suite
- to be able to test logins to your application.
+ which contains no users by default. As a result, logins that are valid
+ on your production site will not work under test conditions. You will
+ need to create users as part of the test suite (either manually, or
+ using a test fixture).
Testing Responses
~~~~~~~~~~~~~~~~~
-The ``get()``, ``post()`` and ``login()`` methods all return a Response
-object. This Response object has the following properties that can be used
-for testing purposes:
+The ``get()`` and ``post()`` methods both return a Response object. This
+Response object has the following properties that can be used for testing
+purposes:
=============== ==========================================================
Property Description
@@ -357,9 +381,31 @@ The following is a simple unit test using the Test Client::
# Check that the rendered context contains 5 customers
self.failUnlessEqual(len(response.context['customers']), 5)
-Fixtures
+TestCase
--------
+Normal python unit tests extend a base class of ``unittest.testCase``.
+Django provides an extension of this base class - ``django.test.TestCase``
+- that provides some additional capabilities that can be useful for
+testing web sites.
+
+Moving from a normal unittest TestCase to a Django TestCase is easy - just
+change the base class of your test from ``unittest.TestCase`` to
+``django.test.TestCase``. All of the standard Python unit test facilities
+will continue to be available, but they will be augmented with some useful
+extra facilities.
+
+Default Test Client
+~~~~~~~~~~~~~~~~~~~
+**New in Django development version**
+
+Every test case in a ``django.test.TestCase`` instance has access to an
+instance of a Django `Test Client`_. This Client can be accessed as
+``self.client``. This client is recreated for each test.
+
+Fixture loading
+~~~~~~~~~~~~~~~
+
A test case for a database-backed website isn't much use if there isn't any
data in the database. To make it easy to put test data into the database,
Django provides a fixtures framework.
@@ -370,22 +416,20 @@ comprise the fixture can be distributed over multiple directories, in
multiple applications.
.. note::
- If you have synchronized a Django project, you have already experienced
+ If you have synchronized a Django project, you have already experienced
the use of one fixture -- the ``initial_data`` fixture. Every time you
synchronize the database, Django installs the ``initial_data`` fixture.
This provides a mechanism to populate a new database with any initial
data (such as a default set of categories). Fixtures with other names
- can be installed manually using ``django-admin.py loaddata``.
-
+ can be installed manually using ``django-admin.py loaddata``.
-However, for the purposes of unit testing, each test must be able to
+However, for the purposes of unit testing, each test must be able to
guarantee the contents of the database at the start of each and every
-test. To do this, Django provides a TestCase baseclass that can integrate
-with fixtures.
+test.
-Moving from a normal unittest TestCase to a Django TestCase is easy - just
-change the base class of your test, and define a list of fixtures
-to be used. For example, the test case from `Writing unittests`_ would
+To define a fixture for a test, all you need to do is add a class
+attribute to your test describing the fixtures you want the test to use.
+For example, the test case from `Writing unittests`_ would
look like::
from django.test import TestCase
@@ -393,23 +437,115 @@ look like::
class AnimalTestCase(TestCase):
fixtures = ['mammals.json', 'birds']
-
+
def setUp(self):
# test definitions as before
At the start of each test case, before ``setUp()`` is run, Django will
-flush the database, returning the database the state it was in directly
-after ``syncdb`` was called. Then, all the named fixtures are installed.
+flush the database, returning the database the state it was in directly
+after ``syncdb`` was called. Then, all the named fixtures are installed.
In this example, any JSON fixture called ``mammals``, and any fixture
-named ``birds`` will be installed. See the documentation on
+named ``birds`` will be installed. See the documentation on
`loading fixtures`_ for more details on defining and installing fixtures.
-.. _`loading fixtures`: ../django_admin/#loaddata-fixture-fixture
+.. _`loading fixtures`: ../django-admin/#loaddata-fixture-fixture
-This flush/load procedure is repeated for each test in the test case, so you
-can be certain that the outcome of a test will not be affected by
+This flush/load procedure is repeated for each test in the test case, so you
+can be certain that the outcome of a test will not be affected by
another test, or the order of test execution.
+Emptying the test outbox
+~~~~~~~~~~~~~~~~~~~~~~~~
+**New in Django development version**
+
+At the start of each test case, in addition to installing fixtures,
+Django clears the contents of the test email outbox.
+
+For more detail on email services during tests, see `Email services`_.
+
+Assertions
+~~~~~~~~~~
+**New in Django development version**
+
+Normal Python unit tests have a wide range of assertions, such as
+``assertTrue`` and ``assertEquals`` that can be used to validate behavior.
+``django.TestCase`` adds to these, providing some assertions
+that can be useful in testing the behavior of web sites.
+
+``assertContains(response, text, count=1, status_code=200)``
+ Assert that a response indicates that a page could be retrieved and
+ produced the nominated status code, and that ``text`` occurs ``count``
+ times in the content of the response.
+
+``assertFormError(response, form, field, errors)``
+ Assert that a field on a form raised the provided list of errors when
+ rendered on the form.
+
+ ``form`` is the name the form object was given in the template context.
+
+ ``field`` is the name of the field on the form to check. If ``field``
+ has a value of ``None``, non-field errors will be checked.
+
+ ``errors`` is an error string, or a list of error strings, that are
+ expected as a result of form validation.
+
+``assertTemplateNotUsed(response, template_name)``
+ Assert that the template with the given name was *not* used in rendering
+ the response.
+
+``assertRedirects(response, expected_path, status_code=302, target_status_code=200)``
+ Assert that the response received produced the nominated status code,
+ redirects the browser to the provided path, and that retrieving the provided
+ path yields a response with the target status code.
+
+``assertTemplateUsed(response, template_name)``
+ Assert that the template with the given name was used in rendering the
+ response.
+
+Email services
+--------------
+**New in Django development version**
+
+If your view makes use of the `Django email services`_, you don't really
+want email to be sent every time you run a test using that view.
+
+When the Django test framework is initialized, it transparently replaces the
+normal `SMTPConnection`_ class with a dummy implementation that redirects all
+email to a dummy outbox. This outbox, stored as ``django.core.mail.outbox``,
+is a simple list of all `EmailMessage`_ instances that have been sent.
+For example, during test conditions, it would be possible to run the following
+code::
+
+ from django.core import mail
+
+ # Send message
+ mail.send_mail('Subject here', 'Here is the message.', 'from@example.com',
+ ['to@example.com'], fail_silently=False)
+
+ # One message has been sent
+ self.assertEqual(len(mail.outbox), 1)
+ # Subject of first message is correct
+ self.assertEqual(mail.outbox[0].subject, 'Subject here')
+
+The ``mail.outbox`` object does not exist under normal execution conditions.
+The outbox is created during test setup, along with the dummy `SMTPConnection`_.
+When the test framework is torn down, the standard `SMTPConnection`_ class
+is restored, and the test outbox is destroyed.
+
+As noted `previously`_, the test outbox is emptied at the start of every
+test in a Django TestCase. To empty the outbox manually, assign the empty list
+to mail.outbox::
+
+ from django.core import mail
+
+ # Empty the test outbox
+ mail.outbox = []
+
+.. _`Django email services`: ../email/
+.. _`SMTPConnection`: ../email/#the-emailmessage-and-smtpconnection-classes
+.. _`EmailMessage`: ../email/#the-emailmessage-and-smtpconnection-classes
+.. _`previously`: #emptying-the-test-outbox
+
Running tests
=============
@@ -434,6 +570,10 @@ database settings will the same as they would be for the project normally.
If you wish to use a name other than the default for the test database,
you can use the ``TEST_DATABASE_NAME`` setting to provide a name.
+The test database is created by the user in the ``DATABASE_USER`` setting.
+This user needs to have sufficient privileges to create a new database on the
+system.
+
Once the test database has been established, Django will run your tests.
If everything goes well, at the end you'll see::
@@ -468,11 +608,11 @@ failed::
FAILED (failures=1)
-The return code for the script is the total number of failed and erroneous
+The return code for the script is the total number of failed and erroneous
tests. If all the tests pass, the return code is 0.
Regardless of whether the tests pass or fail, the test database is destroyed when
-all the tests have been executed.
+all the tests have been executed.
Using a different testing framework
===================================
@@ -483,7 +623,7 @@ it does provide a mechanism to allow you to invoke tests constructed for
an alternative framework as if they were normal Django tests.
When you run ``./manage.py test``, Django looks at the ``TEST_RUNNER``
-setting to determine what to do. By default, ``TEST_RUNNER`` points to
+setting to determine what to do. By default, ``TEST_RUNNER`` points to
``django.test.simple.run_tests``. This method defines the default Django
testing behavior. This behavior involves:
@@ -513,7 +653,7 @@ arguments:
Verbosity determines the amount of notification and debug information that
will be printed to the console; `0` is no output, `1` is normal output,
and `2` is verbose output.
-
+
This method should return the number of tests that failed.
Testing utilities
@@ -524,11 +664,12 @@ a number of utility methods in the ``django.test.utils`` module.
``setup_test_environment()``
Performs any global pre-test setup, such as the installing the
- instrumentation of the template rendering system.
+ instrumentation of the template rendering system and setting up
+ the dummy SMTPConnection.
``teardown_test_environment()``
Performs any global post-test teardown, such as removing the instrumentation
- of the template rendering system.
+ of the template rendering system and restoring normal email services.
``create_test_db(verbosity=1, autoclobber=False)``
Creates a new test database, and run ``syncdb`` against it.
diff --git a/docs/tutorial01.txt b/docs/tutorial01.txt
index 0e857d09ca..c40b051b19 100644
--- a/docs/tutorial01.txt
+++ b/docs/tutorial01.txt
@@ -124,7 +124,7 @@ It worked!
Full docs for the development server are at `django-admin documentation`_.
-.. _django-admin documentation: ../django_admin/
+.. _django-admin documentation: ../django-admin/
Database setup
--------------
@@ -382,7 +382,7 @@ If you're interested, also run the following commands:
statements for this app.
* ``python manage.py sqlall polls`` -- A combination of all the SQL from
- the 'sql', 'sqlinitialdata', and 'sqlindexes' commands.
+ the 'sql', 'sqlcustom', and 'sqlindexes' commands.
Looking at the output of those commands can help you understand what's actually
happening under the hood.
@@ -400,7 +400,7 @@ as you like, and it will only ever create the tables that don't exist.
Read the `django-admin.py documentation`_ for full information on what the
``manage.py`` utility can do.
-.. _django-admin.py documentation: ../django_admin/
+.. _django-admin.py documentation: ../django-admin/
Playing with the API
====================
@@ -577,5 +577,5 @@ For full details on the database API, see our `Database API reference`_.
When you're comfortable with the API, read `part 2 of this tutorial`_ to get
Django's automatic admin working.
-.. _Database API reference: ../db_api/
-.. _part 2 of this tutorial: ../tutorial2/
+.. _Database API reference: ../db-api/
+.. _part 2 of this tutorial: ../tutorial02/
diff --git a/docs/tutorial02.txt b/docs/tutorial02.txt
index 2eabae96f0..6e4b0ea35e 100644
--- a/docs/tutorial02.txt
+++ b/docs/tutorial02.txt
@@ -5,7 +5,7 @@ Writing your first Django app, part 2
This tutorial begins where `Tutorial 1`_ left off. We're continuing the Web-poll
application and will focus on Django's automatically-generated admin site.
-.. _Tutorial 1: ../tutorial1/
+.. _Tutorial 1: ../tutorial01/
.. admonition:: Philosophy
@@ -61,8 +61,8 @@ tutorial, remember?) You should see the Django admin index page:
:alt: Django admin index page
:target: http://media.djangoproject.com/img/doc/tutorial/admin02.png
-By default, you should see two types of editable content: groups and users.
-These are core features Django ships with by default.
+You should see a few other types of editable content, including groups, users
+and sites. These are core features Django ships with by default.
.. _"I can't log in" questions: ../faq/#the-admin-site
@@ -434,4 +434,4 @@ When you're comfortable with the admin site, read `part 3 of this tutorial`_ to
start working on public poll views.
.. _Django admin CSS guide: ../admin_css/
-.. _part 3 of this tutorial: ../tutorial3/
+.. _part 3 of this tutorial: ../tutorial03/
diff --git a/docs/tutorial03.txt b/docs/tutorial03.txt
index 17b6ec0c68..8bb63791aa 100644
--- a/docs/tutorial03.txt
+++ b/docs/tutorial03.txt
@@ -5,7 +5,7 @@ Writing your first Django app, part 3
This tutorial begins where `Tutorial 2`_ left off. We're continuing the Web-poll
application and will focus on creating the public interface -- "views."
-.. _Tutorial 2: ../tutorial2/
+.. _Tutorial 2: ../tutorial02/
Philosophy
==========
@@ -463,4 +463,4 @@ All the poll app cares about is its relative URLs, not its absolute URLs.
When you're comfortable with writing views, read `part 4 of this tutorial`_ to
learn about simple form processing and generic views.
-.. _part 4 of this tutorial: ../tutorial4/
+.. _part 4 of this tutorial: ../tutorial04/
diff --git a/docs/tutorial04.txt b/docs/tutorial04.txt
index b1c8c7d4fc..6fee842f8b 100644
--- a/docs/tutorial04.txt
+++ b/docs/tutorial04.txt
@@ -219,7 +219,7 @@ template. Note that we use ``dict()`` to return an altered dictionary in place.
If you'd like to know more about how that works, The Django database API
documentation `explains the lazy nature of QuerySet objects`_.
-.. _explains the lazy nature of QuerySet objects: ../db_api/#querysets-are-lazy
+.. _explains the lazy nature of QuerySet objects: ../db-api/#querysets-are-lazy
In previous parts of the tutorial, the templates have been provided with a context
that contains the ``poll`` and ``latest_poll_list`` context variables. However,
@@ -256,4 +256,4 @@ installments:
* Advanced admin features: Permissions
* Advanced admin features: Custom JavaScript
-.. _Tutorial 3: ../tutorial3/
+.. _Tutorial 3: ../tutorial03/
diff --git a/docs/url_dispatch.txt b/docs/url_dispatch.txt
index e6e1cb6cbf..39eed0625b 100644
--- a/docs/url_dispatch.txt
+++ b/docs/url_dispatch.txt
@@ -192,10 +192,11 @@ The remaining arguments should be tuples in this format::
url
---
-**New in development version**
-The ``url()`` function can be used instead of a tuple as an argument to
-``patterns()``. This is convenient if you wish to specify a name without the
+**New in Django development version**
+
+You can use the ``url()`` function, instead of a tuple, as an argument to
+``patterns()``. This is convenient if you want to specify a name without the
optional extra arguments dictionary. For example::
urlpatterns = patterns('',
@@ -498,26 +499,40 @@ the view prefix (as explained in "The view prefix" above) will have no effect.
Naming URL patterns
===================
-**New in development version**
+**New in Django development version**
+
+It's fairly common to use the same view function in multiple URL patterns in
+your URLconf. For example, these two URL patterns both point to the ``archive``
+view::
+
+ urlpatterns = patterns('',
+ (r'/archive/(\d{4})/$', archive),
+ (r'/archive-summary/(\d{4})/$', archive, {'summary': True}),
+ )
+
+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
+the ``archive`` view, Django's reverse URL matcher would get confused, because
+*two* URLpatterns point at that view.
-It is fairly common to use the same view function in multiple URL patterns in
-your URLConf. This leads to problems when you come to do reverse URL matching,
-because the ``permalink()`` decorator and ``{% url %}`` template tag use the
-name of the view function to find a match.
+To solve this problem, Django supports **named URL patterns**. That is, you can
+give a name to a URL pattern in order to distinguish it from other patterns
+using the same view and parameters. Then, you can use this name in reverse URL
+matching.
-To solve this problem, you can give a name to each of your URL patterns in
-order to distinguish them from other patterns using the same views and
-parameters. You can then use this name wherever you would otherwise use the
-name of the view function. For example, if you URLConf contains::
+Here's the above example, rewritten to used named URL patterns::
urlpatterns = patterns('',
url(r'/archive/(\d{4})/$', archive, name="full-archive"),
url(r'/archive-summary/(\d{4})/$', archive, {'summary': True}, "arch-summary"),
)
-...you could refer to either the summary archive view in a template as::
+With these names in place (``full-archive`` and ``arch-summary``), you can
+target each pattern individually by using its name::
{% url arch-summary 1945 %}
+ {% url full-archive 2007 %}
Even though both URL patterns refer to the ``archive`` view here, using the
``name`` parameter to ``url()`` allows you to tell them apart in templates.
@@ -527,11 +542,12 @@ not restricted to valid Python names.
.. note::
- Make sure that when you name your URLs, you use names that are unlikely to
- clash with any other application's choice of names. If you call your URL
- pattern *comment* and another application does the same thing, there is no
- guarantee which URL will be inserted into your template when you use this
- name. Putting a prefix on your URL names, perhaps derived from
- the application name, will decrease the chances of collision. Something
- like *myapp-comment* is recommended over simply *comment*.
+ When you name your URL patterns, make sure you use names that are unlikely
+ to clash with any other application's choice of names. If you call your URL
+ pattern ``comment``, and another application does the same thing, there's
+ no guarantee which URL will be inserted into your template when you use
+ this name.
+ Putting a prefix on your URL names, perhaps derived from the application
+ name, will decrease the chances of collision. We recommend something like
+ ``myapp-comment`` instead of ``comment``.