summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorAndrew Godwin <andrew@aeracode.org>2012-09-17 20:00:14 +0100
committerAndrew Godwin <andrew@aeracode.org>2012-09-17 20:00:14 +0100
commit9313dea7006ab77d54735fdd5825a812684e7144 (patch)
tree3c4e67806b8805e41889d8f078d7c0cb2030a85d /docs
parentdbf8b93c527733fb5e3ea101a67bd94db745888e (diff)
parentd21f3d9b171a3cbff4c8ce7a9dbb8b8be3f21bac (diff)
Merge remote-tracking branch 'core/master' into schema-alteration
Conflicts: django/db/backends/mysql/base.py django/db/backends/postgresql_psycopg2/base.py
Diffstat (limited to 'docs')
-rw-r--r--docs/README5
-rw-r--r--docs/contents.txt11
-rw-r--r--docs/faq/admin.txt5
-rw-r--r--docs/faq/install.txt38
-rw-r--r--docs/faq/models.txt2
-rw-r--r--docs/howto/custom-model-fields.txt8
-rw-r--r--docs/index.txt2
-rw-r--r--docs/internals/committers.txt38
-rw-r--r--docs/internals/deprecation.txt3
-rw-r--r--docs/intro/install.txt8
-rw-r--r--docs/intro/overview.txt8
-rw-r--r--docs/intro/tutorial03.txt5
-rw-r--r--docs/intro/tutorial04.txt4
-rw-r--r--docs/intro/whatsnext.txt3
-rw-r--r--docs/obsolete/_images/formrow.pngbin16601 -> 0 bytes
-rw-r--r--docs/obsolete/_images/module.pngbin10072 -> 0 bytes
-rw-r--r--docs/obsolete/_images/objecttools_01.pngbin1398 -> 0 bytes
-rw-r--r--docs/obsolete/_images/objecttools_02.pngbin2268 -> 0 bytes
-rw-r--r--docs/obsolete/admin-css.txt186
-rw-r--r--docs/obsolete/index.txt12
-rw-r--r--docs/ref/class-based-views/base.txt65
-rw-r--r--docs/ref/class-based-views/generic-date-based.txt128
-rw-r--r--docs/ref/class-based-views/generic-display.txt57
-rw-r--r--docs/ref/class-based-views/index.txt9
-rw-r--r--docs/ref/class-based-views/mixins-date-based.txt173
-rw-r--r--docs/ref/class-based-views/mixins-multiple-object.txt3
-rw-r--r--docs/ref/class-based-views/mixins-simple.txt25
-rw-r--r--docs/ref/contrib/comments/moderation.txt8
-rw-r--r--docs/ref/contrib/contenttypes.txt8
-rw-r--r--docs/ref/contrib/formtools/form-wizard.txt62
-rw-r--r--docs/ref/contrib/gis/install.txt12
-rw-r--r--docs/ref/contrib/gis/tutorial.txt4
-rw-r--r--docs/ref/contrib/markup.txt3
-rw-r--r--docs/ref/contrib/messages.txt96
-rw-r--r--docs/ref/forms/fields.txt61
-rw-r--r--docs/ref/forms/widgets.txt236
-rw-r--r--docs/ref/models/fields.txt12
-rw-r--r--docs/ref/models/instances.txt2
-rw-r--r--docs/ref/models/querysets.txt57
-rw-r--r--docs/ref/settings.txt36
-rw-r--r--docs/releases/1.5.txt14
-rw-r--r--docs/releases/index.txt1
-rw-r--r--docs/topics/auth.txt37
-rw-r--r--docs/topics/class-based-views/index.txt44
-rw-r--r--docs/topics/db/examples/many_to_one.txt8
-rw-r--r--docs/topics/db/multi-db.txt128
-rw-r--r--docs/topics/db/queries.txt23
-rw-r--r--docs/topics/forms/media.txt24
-rw-r--r--docs/topics/forms/modelforms.txt6
-rw-r--r--docs/topics/http/urls.txt102
-rw-r--r--docs/topics/i18n/translation.txt5
-rw-r--r--docs/topics/install.txt13
-rw-r--r--docs/topics/logging.txt12
-rw-r--r--docs/topics/python3.txt11
54 files changed, 1102 insertions, 721 deletions
diff --git a/docs/README b/docs/README
index b02499d738..05133d8917 100644
--- a/docs/README
+++ b/docs/README
@@ -1,9 +1,8 @@
The documentation in this tree is in plain text files and can be viewed using
any text file viewer.
-Technically speaking, it uses ReST (reStructuredText) [1], and the Sphinx
-documentation system [2]. This allows it to be built into other forms for
-easier viewing and browsing.
+It uses ReST (reStructuredText) [1], and the Sphinx documentation system [2].
+This allows it to be built into other forms for easier viewing and browsing.
To create an HTML version of the docs:
diff --git a/docs/contents.txt b/docs/contents.txt
index 9bf0d685c4..736e1f62bf 100644
--- a/docs/contents.txt
+++ b/docs/contents.txt
@@ -28,14 +28,3 @@ Indices, glossary and tables
* :ref:`genindex`
* :ref:`modindex`
* :ref:`glossary`
-
-Deprecated/obsolete documentation
-=================================
-
-The following documentation covers features that have been deprecated or that
-have been replaced in newer versions of Django.
-
-.. toctree::
- :maxdepth: 2
-
- obsolete/index
diff --git a/docs/faq/admin.txt b/docs/faq/admin.txt
index 8ec7491903..ea6aa2e74e 100644
--- a/docs/faq/admin.txt
+++ b/docs/faq/admin.txt
@@ -91,8 +91,7 @@ The dynamically-generated admin site is ugly! How can I change it?
We like it, but if you don't agree, you can modify the admin site's
presentation by editing the CSS stylesheet and/or associated image files. The
site is built using semantic HTML and plenty of CSS hooks, so any changes you'd
-like to make should be possible by editing the stylesheet. We've got a
-:doc:`guide to the CSS used in the admin </obsolete/admin-css>` to get you started.
+like to make should be possible by editing the stylesheet.
What browsers are supported for using the admin?
------------------------------------------------
@@ -104,5 +103,5 @@ There *may* be minor stylistic differences between supported browsers—for
example, some browsers may not support rounded corners. These are considered
acceptable variations in rendering.
-.. _YUI's A-grade: http://yuilibrary.com/yui/docs/tutorials/gbs/
+.. _YUI's A-grade: http://yuilibrary.com/yui/docs/tutorials/gbs/
diff --git a/docs/faq/install.txt b/docs/faq/install.txt
index a14615e47c..a772a379d5 100644
--- a/docs/faq/install.txt
+++ b/docs/faq/install.txt
@@ -16,8 +16,9 @@ How do I get started?
What are Django's prerequisites?
--------------------------------
-Django requires Python_, specifically Python 2.6.5 - 2.7.x. No other Python
-libraries are required for basic Django usage.
+Django requires Python, specifically Python 2.6.5 - 2.7.x. No other Python
+libraries are required for basic Django usage. Django 1.5 also has
+experimental support for Python 3.2 and above.
For a development environment -- if you just want to experiment with Django --
you don't need to have a separate Web server installed; Django comes with its
@@ -50,15 +51,12 @@ aren't available under older versions of Python.
Third-party applications for use with Django are, of course, free to set their
own version requirements.
-Over the next year or two Django will begin dropping support for older Python
-versions as part of a migration which will end with Django running on Python 3
-(see below for details).
-
All else being equal, we recommend that you use the latest 2.x release
(currently Python 2.7). This will let you take advantage of the numerous
-improvements and optimizations to the Python language since version 2.6, and
-will help ease the process of dropping support for older Python versions on
-the road to Python 3.
+improvements and optimizations to the Python language since version 2.6.
+
+Generally speaking, we don't recommend running Django on Python 3 yet; see
+below for more.
What Python version can I use with Django?
------------------------------------------
@@ -71,25 +69,21 @@ Django version Python versions
1.2 2.4, 2.5, 2.6, 2.7
1.3 2.4, 2.5, 2.6, 2.7
**1.4** **2.5, 2.6, 2.7**
-*1.5 (future)* *2.6, 2.7, 3.x (experimental)*
+*1.5 (future)* *2.6, 2.7* and *3.2, 3.3 (experimental)*
============== ===============
Can I use Django with Python 3?
-------------------------------
-Not at the moment. Python 3.0 introduced a number of
-backwards-incompatible changes to the Python language, and although
-these changes are generally a good thing for Python's future, it will
-be a while before most Python software catches up and is able to run
-on Python 3.0. For larger Python-based software like Django, the
-transition is expected to take at least a year or two (since it
-involves dropping support for older Python releases and so must be
-done gradually).
+Django 1.5 introduces experimental support for Python 3.2 and 3.3. However, we
+don't yet suggest that you use Django and Python 3 in production.
+
+Python 3 support should be considered a "preview". It's offered to bootstrap
+the transition of the Django ecosystem to Python 3, and to help you start
+porting your apps for future Python 3 compatibility. But we're not yet
+confident enough to promise stability in production.
-In the meantime, Python 2.x releases will be supported and provided
-with bug fixes and security updates by the Python development team, so
-continuing to use a Python 2.x release during the transition should
-not present any risk.
+Our current plan is to make Django 1.6 suitable for general use with Python 3.
Will Django run under shared hosting (like TextDrive or Dreamhost)?
-------------------------------------------------------------------
diff --git a/docs/faq/models.txt b/docs/faq/models.txt
index 4a83aa9f2c..69965b66e1 100644
--- a/docs/faq/models.txt
+++ b/docs/faq/models.txt
@@ -11,7 +11,7 @@ Then, just do this::
>>> from django.db import connection
>>> connection.queries
- [{'sql': 'SELECT polls_polls.id,polls_polls.question,polls_polls.pub_date FROM polls_polls',
+ [{'sql': 'SELECT polls_polls.id, polls_polls.question, polls_polls.pub_date FROM polls_polls',
'time': '0.002'}]
``connection.queries`` is only available if :setting:`DEBUG` is ``True``.
diff --git a/docs/howto/custom-model-fields.txt b/docs/howto/custom-model-fields.txt
index e73ef9aa42..9ff06479c6 100644
--- a/docs/howto/custom-model-fields.txt
+++ b/docs/howto/custom-model-fields.txt
@@ -181,10 +181,10 @@ card values plus their suits; 104 characters in total.
Many of Django's model fields accept options that they don't do anything
with. For example, you can pass both
:attr:`~django.db.models.Field.editable` and
- :attr:`~django.db.models.Field.auto_now` to a
+ :attr:`~django.db.models.DateField.auto_now` to a
:class:`django.db.models.DateField` and it will simply ignore the
:attr:`~django.db.models.Field.editable` parameter
- (:attr:`~django.db.models.Field.auto_now` being set implies
+ (:attr:`~django.db.models.DateField.auto_now` being set implies
``editable=False``). No error is raised in this case.
This behavior simplifies the field classes, because they don't need to
@@ -516,8 +516,8 @@ for the first time, the ``add`` parameter will be ``True``, otherwise it will be
You only need to override this method if you want to preprocess the value
somehow, just before saving. For example, Django's
:class:`~django.db.models.DateTimeField` uses this method to set the attribute
-correctly in the case of :attr:`~django.db.models.Field.auto_now` or
-:attr:`~django.db.models.Field.auto_now_add`.
+correctly in the case of :attr:`~django.db.models.DateField.auto_now` or
+:attr:`~django.db.models.DateField.auto_now_add`.
If you do override this method, you must return the value of the attribute at
the end. You should also update the model's attribute if you make any changes
diff --git a/docs/index.txt b/docs/index.txt
index 3f4e30385c..8b29c95fa2 100644
--- a/docs/index.txt
+++ b/docs/index.txt
@@ -5,7 +5,7 @@
Django documentation
====================
-.. rubric:: Everything you need to know about Django (and then some).
+.. rubric:: Everything you need to know about Django.
Getting help
============
diff --git a/docs/internals/committers.txt b/docs/internals/committers.txt
index 2faace99a5..ca56d36880 100644
--- a/docs/internals/committers.txt
+++ b/docs/internals/committers.txt
@@ -379,6 +379,34 @@ Florian Apolloner
.. _Graz University of Technology: http://tugraz.at/
.. _Ubuntuusers webteam: http://wiki.ubuntuusers.de/ubuntuusers/Webteam
+Jeremy Dunck
+ Jeremy was rescued from corporate IT drudgery by Free Software and, in part,
+ Django. Many of Jeremy's interests center around access to information.
+
+ Jeremy was the lead developer of Pegasus News, one of the first uses of
+ Django outside World Online, and has since joined Votizen, a startup intent
+ on reducing the influence of money in politics.
+
+ He serves as DSF Secretary, organizes and helps organize sprints, cares
+ about the health and equity of the Django community. He has gone an
+ embarrassingly long time without a working blog.
+
+ Jeremy lives in Mountain View, CA, USA.
+
+`Bryan Veloso`_
+ Bryan found Django 0.96 through a fellow designer who was evangelizing
+ its use. It was his first foray outside of the land that was PHP-based
+ templating. Although he has only ever used Django for personal projects,
+ it is the very reason he considers himself a designer/developer
+ hybrid and is working to further design within the Django community.
+
+ Bryan works as a designer at GitHub by day, and masquerades as a `vlogger`_
+ and `shoutcaster`_ in the after-hours. Bryan lives in Los Angeles, CA, USA.
+
+.. _bryan veloso: http://avalonstar.com/
+.. _vlogger: http://youtube.com/bryanveloso/
+.. _shoutcaster: http://twitch.tv/vlogalonstar/
+
Specialists
-----------
@@ -403,16 +431,6 @@ Ian Kelly
Matt Boersma
Matt is also responsible for Django's Oracle support.
-Jeremy Dunck
- Jeremy is the lead developer of Pegasus News, a personalized local site based
- in Dallas, Texas. An early contributor to Greasemonkey and Django, he sees
- technology as a tool for communication and access to knowledge.
-
- Jeremy helped kick off GeoDjango development, and is mostly responsible for
- the serious speed improvements that signals received in Django 1.0.
-
- Jeremy lives in Dallas, Texas, USA.
-
`Simon Meers`_
Simon discovered Django 0.96 during his Computer Science PhD research and
has been developing with it full-time ever since. His core code
diff --git a/docs/internals/deprecation.txt b/docs/internals/deprecation.txt
index 9359c82e46..4add751912 100644
--- a/docs/internals/deprecation.txt
+++ b/docs/internals/deprecation.txt
@@ -264,6 +264,9 @@ these changes.
in 1.4. The backward compatibility will be removed --
``HttpRequest.raw_post_data`` will no longer work.
+* ``django.contrib.markup`` will be removed following an accelerated
+ deprecation.
+
1.7
---
diff --git a/docs/intro/install.txt b/docs/intro/install.txt
index 70c8034c5d..f9b122e62d 100644
--- a/docs/intro/install.txt
+++ b/docs/intro/install.txt
@@ -10,11 +10,9 @@ Install Python
--------------
Being a Python Web framework, Django requires Python. It works with any Python
-version from 2.6.5 to 2.7 (due to backwards incompatibilities in Python 3.0,
-Django does not currently work with Python 3.0; see :doc:`the Django FAQ
-</faq/install>` for more information on supported Python versions and the 3.0
-transition), these versions of Python include a lightweight database called
-SQLite_ so you won't need to set up a database just yet.
+version from 2.6.5 to 2.7. It also features experimental support for versions
+3.2 and 3.3. All these versions of Python include a lightweight database
+called SQLite_ so you won't need to set up a database just yet.
.. _sqlite: http://sqlite.org/
diff --git a/docs/intro/overview.txt b/docs/intro/overview.txt
index 49233fb8a7..4d5a86f82b 100644
--- a/docs/intro/overview.txt
+++ b/docs/intro/overview.txt
@@ -31,7 +31,7 @@ the file ``mysite/news/models.py``::
return self.full_name
class Article(models.Model):
- pub_date = models.DateTimeField()
+ pub_date = models.DateField()
headline = models.CharField(max_length=200)
content = models.TextField()
reporter = models.ForeignKey(Reporter)
@@ -96,8 +96,8 @@ access your data. The API is created on the fly, no code generation necessary::
DoesNotExist: Reporter matching query does not exist. Lookup parameters were {'id': 2}
# Create an article.
- >>> from datetime import datetime
- >>> a = Article(pub_date=datetime.now(), headline='Django is cool',
+ >>> from datetime import date
+ >>> a = Article(pub_date=date.today(), headline='Django is cool',
... content='Yeah.', reporter=r)
>>> a.save()
@@ -140,7 +140,7 @@ as registering your model in the admin site::
from django.db import models
class Article(models.Model):
- pub_date = models.DateTimeField()
+ pub_date = models.DateField()
headline = models.CharField(max_length=200)
content = models.TextField()
reporter = models.ForeignKey(Reporter)
diff --git a/docs/intro/tutorial03.txt b/docs/intro/tutorial03.txt
index 2430bc3a2d..03d4bf68b3 100644
--- a/docs/intro/tutorial03.txt
+++ b/docs/intro/tutorial03.txt
@@ -513,8 +513,9 @@ Here's what happens if a user goes to "/polls/34/" in this system:
further processing.
Now that we've decoupled that, we need to decouple the ``polls.urls``
-URLconf by removing the leading "polls/" from each line, and removing the
-lines registering the admin site. Your ``polls/urls.py`` file should now look like
+URLconf by removing the leading "polls/" from each line, removing the
+lines registering the admin site, and removing the ``include`` import which
+is no longer used. Your ``polls/urls.py`` file should now look like
this::
from django.conf.urls import patterns, url
diff --git a/docs/intro/tutorial04.txt b/docs/intro/tutorial04.txt
index 31680ea5e5..49e597ca29 100644
--- a/docs/intro/tutorial04.txt
+++ b/docs/intro/tutorial04.txt
@@ -218,7 +218,7 @@ Read on for details.
First, open the ``polls/urls.py`` URLconf. It looks like this, according to the
tutorial so far::
- from django.conf.urls import patterns, include, url
+ from django.conf.urls import patterns, url
urlpatterns = patterns('polls.views',
url(r'^$', 'index'),
@@ -229,7 +229,7 @@ tutorial so far::
Change it like so::
- from django.conf.urls import patterns, include, url
+ from django.conf.urls import patterns, url
from django.views.generic import DetailView, ListView
from polls.models import Poll
diff --git a/docs/intro/whatsnext.txt b/docs/intro/whatsnext.txt
index cc793c8129..ea4b18de03 100644
--- a/docs/intro/whatsnext.txt
+++ b/docs/intro/whatsnext.txt
@@ -67,8 +67,7 @@ different needs:
whathaveyou.
* Finally, there's some "specialized" documentation not usually relevant to
- most developers. This includes the :doc:`release notes </releases/index>`,
- :doc:`documentation of obsolete features </obsolete/index>`,
+ most developers. This includes the :doc:`release notes </releases/index>` and
:doc:`internals documentation </internals/index>` for those who want to add
code to Django itself, and a :doc:`few other things that simply don't fit
elsewhere </misc/index>`.
diff --git a/docs/obsolete/_images/formrow.png b/docs/obsolete/_images/formrow.png
deleted file mode 100644
index 164dd262b5..0000000000
--- a/docs/obsolete/_images/formrow.png
+++ /dev/null
Binary files differ
diff --git a/docs/obsolete/_images/module.png b/docs/obsolete/_images/module.png
deleted file mode 100644
index 6acda97809..0000000000
--- a/docs/obsolete/_images/module.png
+++ /dev/null
Binary files differ
diff --git a/docs/obsolete/_images/objecttools_01.png b/docs/obsolete/_images/objecttools_01.png
deleted file mode 100644
index 0aba8163d6..0000000000
--- a/docs/obsolete/_images/objecttools_01.png
+++ /dev/null
Binary files differ
diff --git a/docs/obsolete/_images/objecttools_02.png b/docs/obsolete/_images/objecttools_02.png
deleted file mode 100644
index 06a854009b..0000000000
--- a/docs/obsolete/_images/objecttools_02.png
+++ /dev/null
Binary files differ
diff --git a/docs/obsolete/admin-css.txt b/docs/obsolete/admin-css.txt
deleted file mode 100644
index f4cca549b4..0000000000
--- a/docs/obsolete/admin-css.txt
+++ /dev/null
@@ -1,186 +0,0 @@
-======================================
-Customizing the Django admin interface
-======================================
-
-.. warning::
-
- The design of the admin has changed somewhat since this document was
- written, and parts may not apply any more. This document is no longer
- maintained since an official API for customizing the Django admin interface
- is in development.
-
-Django's dynamic admin interface gives you a fully-functional admin for free
-with no hand-coding required. The dynamic admin is designed to be
-production-ready, not just a starting point, so you can use it as-is on a real
-site. While the underlying format of the admin pages is built in to Django, you
-can customize the look and feel by editing the admin stylesheet and images.
-
-Here's a quick and dirty overview some of the main styles and classes used in
-the Django admin CSS.
-
-Modules
-=======
-
-The ``.module`` class is a basic building block for grouping content in the
-admin. It's generally applied to a ``div`` or a ``fieldset``. It wraps the content
-group in a box and applies certain styles to the elements within. An ``h2``
-within a ``div.module`` will align to the top of the ``div`` as a header for the
-whole group.
-
-.. image:: _images/module.png
- :alt: Example use of module class on admin homepage
-
-Column Types
-============
-
-.. note::
-
- All admin pages (except the dashboard) are fluid-width. All fixed-width
- classes from previous Django versions have been removed.
-
-The base template for each admin page has a block that defines the column
-structure for the page. This sets a class on the page content area
-(``div#content``) so everything on the page knows how wide it should be. There
-are three column types available.
-
-colM
- This is the default column setting for all pages. The "M" stands for "main".
- Assumes that all content on the page is in one main column
- (``div#content-main``).
-colMS
- This is for pages with one main column and a sidebar on the right. The "S"
- stands for "sidebar". Assumes that main content is in ``div#content-main``
- and sidebar content is in ``div#content-related``. This is used on the main
- admin page.
-colSM
- Same as above, with the sidebar on the left. The source order of the columns
- doesn't matter.
-
-For instance, you could stick this in a template to make a two-column page with
-the sidebar on the right:
-
-.. code-block:: html+django
-
- {% block coltype %}colMS{% endblock %}
-
-Text Styles
-===========
-
-Font Sizes
-----------
-
-Most HTML elements (headers, lists, etc.) have base font sizes in the stylesheet
-based on context. There are three classes are available for forcing text to a
-certain size in any context.
-
-small
- 11px
-tiny
- 10px
-mini
- 9px (use sparingly)
-
-Font Styles and Alignment
--------------------------
-
-There are also a few styles for styling text.
-
-.quiet
- Sets font color to light gray. Good for side notes in instructions. Combine
- with ``.small`` or ``.tiny`` for sheer excitement.
-.help
- This is a custom class for blocks of inline help text explaining the
- function of form elements. It makes text smaller and gray, and when applied
- to ``p`` elements within ``.form-row`` elements (see Form Styles below),
- it will offset the text to align with the form field. Use this for help
- text, instead of ``small quiet``. It works on other elements, but try to
- put the class on a ``p`` whenever you can.
-.align-left
- It aligns the text left. Only works on block elements containing inline
- elements.
-.align-right
- Are you paying attention?
-.nowrap
- Keeps text and inline objects from wrapping. Comes in handy for table
- headers you want to stay on one line.
-
-Floats and Clears
------------------
-
-float-left
- floats left
-float-right
- floats right
-clear
- clears all
-
-Object Tools
-============
-
-Certain actions which apply directly to an object are used in form and
-changelist pages. These appear in a "toolbar" row above the form or changelist,
-to the right of the page. The tools are wrapped in a ``ul`` with the class
-``object-tools``. There are two custom tool types which can be defined with an
-additional class on the ``a`` for that tool. These are ``.addlink`` and
-``.viewsitelink``.
-
-Example from a changelist page:
-
-.. code-block:: html+django
-
- <ul class="object-tools">
- <li><a href="/stories/add/" class="addlink">Add redirect</a></li>
- </ul>
-
-.. image:: _images/objecttools_01.png
- :alt: Object tools on a changelist page
-
-and from a form page:
-
-.. code-block:: html+django
-
- <ul class="object-tools">
- <li><a href="/history/303/152383/">History</a></li>
- <li><a href="/r/303/152383/" class="viewsitelink">View on site</a></li>
- </ul>
-
-.. image:: _images/objecttools_02.png
- :alt: Object tools on a form page
-
-Form Styles
-===========
-
-Fieldsets
----------
-
-Admin forms are broken up into groups by ``fieldset`` elements. Each form fieldset
-should have a class ``.module``. Each fieldset should have a header ``h2`` within the
-fieldset at the top (except the first group in the form, and in some cases where the
-group of fields doesn't have a logical label).
-
-Each fieldset can also take extra classes in addition to ``.module`` to apply
-appropriate formatting to the group of fields.
-
-.aligned
- This will align the labels and inputs side by side on the same line.
-.wide
- Used in combination with ``.aligned`` to widen the space available for the
- labels.
-
-Form Rows
----------
-
-Each row of the form (within the ``fieldset``) should be enclosed in a ``div``
-with class ``form-row``. If the field in the row is required, a class of
-``required`` should also be added to the ``div.form-row``.
-
-.. image:: _images/formrow.png
- :alt: Example use of form-row class
-
-Labels
-------
-
-Form labels should always precede the field, except in the case
-of checkboxes and radio buttons, where the ``input`` should come first. Any
-explanation or help text should follow the ``label`` in a ``p`` with class
-``.help``.
diff --git a/docs/obsolete/index.txt b/docs/obsolete/index.txt
deleted file mode 100644
index ddc86237cc..0000000000
--- a/docs/obsolete/index.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-Deprecated/obsolete documentation
-=================================
-
-These documents cover features that have been deprecated or that have been
-replaced in newer versions of Django. They're preserved here for folks using old
-versions of Django or those still using deprecated APIs. No new code based on
-these APIs should be written.
-
-.. toctree::
- :maxdepth: 1
-
- admin-css \ No newline at end of file
diff --git a/docs/ref/class-based-views/base.txt b/docs/ref/class-based-views/base.txt
index 3f82b44f46..cc9aa852f1 100644
--- a/docs/ref/class-based-views/base.txt
+++ b/docs/ref/class-based-views/base.txt
@@ -8,6 +8,11 @@ themselves or inherited from. They may not provide all the capabilities
required for projects, in which case there are Mixins and Generic class-based
views.
+Many of Django's built-in class-based views inherit from other class-based
+views or various mixins. Because this inheritence chain is very important, the
+ancestor classes are documented under the section title of **Ancestors (MRO)**.
+MRO is an acronym for Method Resolution Order.
+
View
----
@@ -20,6 +25,7 @@ View
1. :meth:`dispatch()`
2. :meth:`http_method_not_allowed()`
+ 3. :meth:`options()`
**Example views.py**::
@@ -41,8 +47,20 @@ View
url(r'^mine/$', MyView.as_view(), name='my-view'),
)
+ **Attributes**
+
+ .. attribute:: http_method_names = ['get', 'post', 'put', 'delete', 'head', 'options', 'trace']
+
+ The default list of HTTP method names that this view will accept.
+
**Methods**
+ .. classmethod:: as_view(**initkwargs)
+
+ Returns a callable view that takes a request and returns a response::
+
+ response = MyView.as_view()(request)
+
.. method:: dispatch(request, *args, **kwargs)
The ``view`` part of the view -- the method that accepts a ``request``
@@ -53,6 +71,11 @@ View
delegated to :meth:`~View.get()`, a ``POST`` to :meth:`~View.post()`,
and so on.
+ By default, a ``HEAD`` request will be delegated to :meth:`~View.get()`.
+ If you need to handle ``HEAD`` requests in a different way than ``GET``,
+ you can override the :meth:`~View.head()` method. See
+ :ref:`supporting-other-http-methods` for an example.
+
The default implementation also sets ``request``, ``args`` and
``kwargs`` as instance variables, so any method on the view can know
the full details of the request that was made to invoke the view.
@@ -62,14 +85,13 @@ View
If the view was called with a HTTP method it doesn't support, this
method is called instead.
- The default implementation returns ``HttpResponseNotAllowed`` with list
- of allowed methods in plain text.
+ The default implementation returns ``HttpResponseNotAllowed`` with a
+ list of allowed methods in plain text.
- .. note::
+ .. method:: options(request, *args, **kwargs)
- Documentation on class-based views is a work in progress. As yet, only the
- methods defined directly on the class are documented here, not methods
- defined on superclasses.
+ Handles responding to requests for the OPTIONS HTTP verb. Returns a
+ list of the allowed HTTP method names for the view.
TemplateView
------------
@@ -81,6 +103,8 @@ TemplateView
**Ancestors (MRO)**
+ This view inherits methods and attributes from the following views:
+
* :class:`django.views.generic.base.TemplateView`
* :class:`django.views.generic.base.TemplateResponseMixin`
* :class:`django.views.generic.base.View`
@@ -116,28 +140,11 @@ TemplateView
url(r'^$', HomePageView.as_view(), name='home'),
)
- **Methods and Attributes**
-
- .. attribute:: template_name
-
- The full name of a template to use.
-
- .. method:: get_context_data(**kwargs)
-
- Return a context data dictionary consisting of the contents of
- ``kwargs`` stored in the context variable ``params``.
-
**Context**
* ``params``: The dictionary of keyword arguments captured from the URL
pattern that served the view.
- .. note::
-
- Documentation on class-based views is a work in progress. As yet, only the
- methods defined directly on the class are documented here, not methods
- defined on superclasses.
-
RedirectView
------------
@@ -156,6 +163,8 @@ RedirectView
**Ancestors (MRO)**
+ This view inherits methods and attributes from the following view:
+
* :class:`django.views.generic.base.View`
**Method Flowchart**
@@ -194,7 +203,7 @@ RedirectView
url(r'^go-to-django/$', RedirectView.as_view(url='http://djangoproject.com'), name='go-to-django'),
)
- **Methods and Attributes**
+ **Attributes**
.. attribute:: url
@@ -215,6 +224,8 @@ RedirectView
then the query string is discarded. By default, ``query_string`` is
``False``.
+ **Methods**
+
.. method:: get_redirect_url(**kwargs)
Constructs the target URL for redirection.
@@ -225,9 +236,3 @@ RedirectView
:attr:`~RedirectView.query_string`. Subclasses may implement any
behavior they wish, as long as the method returns a redirect-ready URL
string.
-
- .. note::
-
- Documentation on class-based views is a work in progress. As yet, only the
- methods defined directly on the class are documented here, not methods
- defined on superclasses.
diff --git a/docs/ref/class-based-views/generic-date-based.txt b/docs/ref/class-based-views/generic-date-based.txt
index 12776cbb94..64b269f514 100644
--- a/docs/ref/class-based-views/generic-date-based.txt
+++ b/docs/ref/class-based-views/generic-date-based.txt
@@ -2,13 +2,15 @@
Generic date views
==================
-Date-based generic views (in the module :mod:`django.views.generic.dates`)
-are views for displaying drilldown pages for date-based data.
+.. module:: django.views.generic.dates
+
+Date-based generic views, provided in :mod:`django.views.generic.dates`, are
+views for displaying drilldown pages for date-based data.
ArchiveIndexView
----------------
-.. class:: django.views.generic.dates.ArchiveIndexView
+.. class:: ArchiveIndexView
A top-level index page showing the "latest" objects, by date. Objects with
a date in the *future* are not included unless you set ``allow_future`` to
@@ -36,7 +38,7 @@ ArchiveIndexView
YearArchiveView
---------------
-.. class:: django.views.generic.dates.YearArchiveView
+.. class:: YearArchiveView
A yearly archive page showing all available months in a given year. Objects
with a date in the *future* are not displayed unless you set
@@ -58,13 +60,15 @@ YearArchiveView
A boolean specifying whether to retrieve the full list of objects for
this year and pass those to the template. If ``True``, the list of
- objects will be made available to the context. By default, this is
+ objects will be made available to the context. If ``False``, the
+ ``None`` queryset will be used as the object list. By default, this is
``False``.
.. method:: get_make_object_list()
- Determine if an object list will be returned as part of the context. If
- ``False``, the ``None`` queryset will be used as the object list.
+ Determine if an object list will be returned as part of the context.
+ Returns :attr:`~YearArchiveView.make_object_list` by default.
+
**Context**
@@ -80,16 +84,18 @@ YearArchiveView
:class:`datetime.datetime<python:datetime.datetime>` objects, in
ascending order.
- * ``year``: A :class:`datetime.date<python:datetime.date>` object
+ * ``year``: A :class:`~datetime.date` object
representing the given year.
- * ``next_year``: A :class:`datetime.date<python:datetime.date>` object
- representing the first day of the next year. If the next year is in the
- future, this will be ``None``.
+ * ``next_year``: A :class:`~datetime.date` object
+ representing the first day of the next year, according to
+ :attr:`~BaseDateListView.allow_empty` and
+ :attr:`~DateMixin.allow_future`.
- * ``previous_year``: A :class:`datetime.date<python:datetime.date>` object
- representing the first day of the previous year. Unlike ``next_year``,
- this will never be ``None``.
+ * ``previous_year``: A :class:`~datetime.date` object
+ representing the first day of the previous year, according to
+ :attr:`~BaseDateListView.allow_empty` and
+ :attr:`~DateMixin.allow_future`.
**Notes**
@@ -98,7 +104,7 @@ YearArchiveView
MonthArchiveView
----------------
-.. class:: django.views.generic.dates.MonthArchiveView
+.. class:: MonthArchiveView
A monthly archive page showing all objects in a given month. Objects with a
date in the *future* are not displayed unless you set ``allow_future`` to
@@ -131,16 +137,18 @@ MonthArchiveView
:class:`datetime.datetime<python:datetime.datetime>` objects, in
ascending order.
- * ``month``: A :class:`datetime.date<python:datetime.date>` object
+ * ``month``: A :class:`~datetime.date` object
representing the given month.
- * ``next_month``: A :class:`datetime.date<python:datetime.date>` object
- representing the first day of the next month. If the next month is in the
- future, this will be ``None``.
+ * ``next_month``: A :class:`~datetime.date` object
+ representing the first day of the next month, according to
+ :attr:`~BaseDateListView.allow_empty` and
+ :attr:`~DateMixin.allow_future`.
- * ``previous_month``: A :class:`datetime.date<python:datetime.date>` object
- representing the first day of the previous month. Unlike ``next_month``,
- this will never be ``None``.
+ * ``previous_month``: A :class:`~datetime.date` object
+ representing the first day of the previous month, according to
+ :attr:`~BaseDateListView.allow_empty` and
+ :attr:`~DateMixin.allow_future`.
**Notes**
@@ -149,7 +157,7 @@ MonthArchiveView
WeekArchiveView
---------------
-.. class:: django.views.generic.dates.WeekArchiveView
+.. class:: WeekArchiveView
A weekly archive page showing all objects in a given week. Objects with a
date in the *future* are not displayed unless you set ``allow_future`` to
@@ -175,16 +183,18 @@ WeekArchiveView
:class:`~django.views.generic.dates.BaseDateListView`), the template's
context will be:
- * ``week``: A :class:`datetime.date<python:datetime.date>` object
+ * ``week``: A :class:`~datetime.date` object
representing the first day of the given week.
- * ``next_week``: A :class:`datetime.date<python:datetime.date>` object
- representing the first day of the next week. If the next week is in the
- future, this will be ``None``.
+ * ``next_week``: A :class:`~datetime.date` object
+ representing the first day of the next week, according to
+ :attr:`~BaseDateListView.allow_empty` and
+ :attr:`~DateMixin.allow_future`.
- * ``previous_week``: A :class:`datetime.date<python:datetime.date>` object
- representing the first day of the previous week. Unlike ``next_week``,
- this will never be ``None``.
+ * ``previous_week``: A :class:`~datetime.date` object
+ representing the first day of the previous week, according to
+ :attr:`~BaseDateListView.allow_empty` and
+ :attr:`~DateMixin.allow_future`.
**Notes**
@@ -193,7 +203,7 @@ WeekArchiveView
DayArchiveView
--------------
-.. class:: django.views.generic.dates.DayArchiveView
+.. class:: DayArchiveView
A day archive page showing all objects in a given day. Days in the future
throw a 404 error, regardless of whether any objects exist for future days,
@@ -220,24 +230,28 @@ DayArchiveView
:class:`~django.views.generic.dates.BaseDateListView`), the template's
context will be:
- * ``day``: A :class:`datetime.date<python:datetime.date>` object
+ * ``day``: A :class:`~datetime.date` object
representing the given day.
- * ``next_day``: A :class:`datetime.date<python:datetime.date>` object
- representing the next day. If the next day is in the future, this will be
- ``None``.
+ * ``next_day``: A :class:`~datetime.date` object
+ representing the next day, according to
+ :attr:`~BaseDateListView.allow_empty` and
+ :attr:`~DateMixin.allow_future`.
- * ``previous_day``: A :class:`datetime.date<python:datetime.date>` object
- representing the previous day. Unlike ``next_day``, this will never be
- ``None``.
+ * ``previous_day``: A :class:`~datetime.date` object
+ representing the previous day, according to
+ :attr:`~BaseDateListView.allow_empty` and
+ :attr:`~DateMixin.allow_future`.
- * ``next_month``: A :class:`datetime.date<python:datetime.date>` object
- representing the first day of the next month. If the next month is in the
- future, this will be ``None``.
+ * ``next_month``: A :class:`~datetime.date` object
+ representing the first day of the next month, according to
+ :attr:`~BaseDateListView.allow_empty` and
+ :attr:`~DateMixin.allow_future`.
- * ``previous_month``: A :class:`datetime.date<python:datetime.date>` object
- representing the first day of the previous month. Unlike ``next_month``,
- this will never be ``None``.
+ * ``previous_month``: A :class:`~datetime.date` object
+ representing the first day of the previous month, according to
+ :attr:`~BaseDateListView.allow_empty` and
+ :attr:`~DateMixin.allow_future`.
**Notes**
@@ -246,7 +260,7 @@ DayArchiveView
TodayArchiveView
----------------
-.. class:: django.views.generic.dates.TodayArchiveView
+.. class:: TodayArchiveView
A day archive page showing all objects for *today*. This is exactly the
same as :class:`django.views.generic.dates.DayArchiveView`, except today's
@@ -271,7 +285,7 @@ TodayArchiveView
DateDetailView
--------------
-.. class:: django.views.generic.dates.DateDetailView
+.. class:: DateDetailView
A page representing an individual object. If the object has a date value in
the future, the view will throw a 404 error by default, unless you set
@@ -293,6 +307,22 @@ DateDetailView
.. note::
- All of the generic views listed above have matching Base* views that only
- differ in that the they do not include the
- :class:`~django.views.generic.detail.SingleObjectTemplateResponseMixin`.
+ All of the generic views listed above have matching ``Base`` views that
+ only differ in that the they do not include the
+ :class:`~django.views.generic.detail.SingleObjectTemplateResponseMixin`:
+
+ .. class:: BaseArchiveIndexView
+
+ .. class:: BaseYearArchiveView
+
+ .. class:: BaseMonthArchiveView
+
+ .. class:: BaseWeekArchiveView
+
+ .. class:: BaseDayArchiveView
+
+ .. class:: BaseTodayArchiveView
+
+ .. class:: BaseDateDetailView
+
+
diff --git a/docs/ref/class-based-views/generic-display.txt b/docs/ref/class-based-views/generic-display.txt
index ef3bc179ee..12603ff0df 100644
--- a/docs/ref/class-based-views/generic-display.txt
+++ b/docs/ref/class-based-views/generic-display.txt
@@ -15,6 +15,8 @@ DetailView
**Ancestors (MRO)**
+ This view inherits methods and attributes from the following views:
+
* :class:`django.views.generic.detail.SingleObjectTemplateResponseMixin`
* :class:`django.views.generic.base.TemplateResponseMixin`
* :class:`django.views.generic.detail.BaseDetailView`
@@ -71,7 +73,9 @@ ListView
objects (usually, but not necessarily a queryset) that the view is
operating upon.
- **Mixins**
+ **Ancestors (MRO)**
+
+ This view inherits methods and attributes from the following views:
* :class:`django.views.generic.list.ListView`
* :class:`django.views.generic.list.MultipleObjectTemplateResponseMixin`
@@ -90,3 +94,54 @@ ListView
6. :meth:`get_context_data()`
7. :meth:`get()`
8. :meth:`render_to_response()`
+
+
+ **Example views.py**::
+
+ from django.views.generic.list import ListView
+ from django.utils import timezone
+
+ from articles.models import Article
+
+ class ArticleListView(ListView):
+
+ model = Article
+
+ def get_context_data(self, **kwargs):
+ context = super(ArticleListView, self).get_context_data(**kwargs)
+ context['now'] = timezone.now()
+ return context
+
+ **Example urls.py**::
+
+ from django.conf.urls import patterns, url
+
+ from article.views import ArticleListView
+
+ urlpatterns = patterns('',
+ url(r'^$', ArticleListView.as_view(), name='article-list'),
+ )
+
+.. class:: django.views.generic.list.BaseListView
+
+ A base view for displaying a list of objects. It is not intended to be used
+ directly, but rather as a parent class of the
+ :class:`django.views.generic.list.ListView` or other views representing
+ lists of objects.
+
+ **Ancestors (MRO)**
+
+ This view inherits methods and attributes from the following views:
+
+ * :class:`django.views.generic.list.MultipleObjectMixin`
+ * :class:`django.views.generic.base.View`
+
+ **Methods**
+
+ .. method:: get(request, *args, **kwargs)
+
+ Adds :attr:`object_list` to the context. If
+ :attr:`~django.views.generic.list.MultipleObjectMixin.allow_empty`
+ is True then display an empty list. If
+ :attr:`~django.views.generic.list.MultipleObjectMixin.allow_empty` is
+ False then raise a 404 error.
diff --git a/docs/ref/class-based-views/index.txt b/docs/ref/class-based-views/index.txt
index f0e7bbc6c1..c4b632604a 100644
--- a/docs/ref/class-based-views/index.txt
+++ b/docs/ref/class-based-views/index.txt
@@ -23,7 +23,7 @@ it is safe to store state variables on the instance (i.e., ``self.foo = 3`` is
a thread-safe operation).
A class-based view is deployed into a URL pattern using the
-:meth:`~View.as_view()` classmethod::
+:meth:`~django.views.generic.base.View.as_view()` classmethod::
urlpatterns = patterns('',
(r'^view/$', MyView.as_view(size=42)),
@@ -37,9 +37,10 @@ A class-based view is deployed into a URL pattern using the
is modified, the actions of one user visiting your view could have an
effect on subsequent users visiting the same view.
-Any argument passed into :meth:`~View.as_view()` will be assigned onto the
-instance that is used to service a request. Using the previous example,
-this means that every request on ``MyView`` is able to use ``self.size``.
+Any argument passed into :meth:`~django.views.generic.base.View.as_view()` will
+be assigned onto the instance that is used to service a request. Using the
+previous example, this means that every request on ``MyView`` is able to use
+``self.size``.
Base vs Generic views
---------------------
diff --git a/docs/ref/class-based-views/mixins-date-based.txt b/docs/ref/class-based-views/mixins-date-based.txt
index 6bf6f10b5d..01181ebb6c 100644
--- a/docs/ref/class-based-views/mixins-date-based.txt
+++ b/docs/ref/class-based-views/mixins-date-based.txt
@@ -2,11 +2,12 @@
Date-based mixins
=================
+.. currentmodule:: django.views.generic.dates
YearMixin
---------
-.. class:: django.views.generic.dates.YearMixin
+.. class:: YearMixin
A mixin that can be used to retrieve and provide parsing information for a
year component of a date.
@@ -20,29 +21,45 @@ YearMixin
.. attribute:: year
- **Optional** The value for the year (as a string). By default, set to
+ **Optional** The value for the year, as a string. By default, set to
``None``, which means the year will be determined using other means.
.. method:: get_year_format()
- Returns the :func:`~time.strftime` format to use when parsing the year. Returns
- :attr:`YearMixin.year_format` by default.
+ Returns the :func:`~time.strftime` format to use when parsing the
+ year. Returns :attr:`~YearMixin.year_format` by default.
.. method:: get_year()
- Returns the year for which this view will display data. Tries the
- following sources, in order:
+ Returns the year for which this view will display data, as a string.
+ Tries the following sources, in order:
* The value of the :attr:`YearMixin.year` attribute.
- * The value of the `year` argument captured in the URL pattern
+ * The value of the `year` argument captured in the URL pattern.
* The value of the `year` GET query argument.
Raises a 404 if no valid year specification can be found.
+ .. method:: get_next_year(date)
+
+ Returns a date object containing the first day of the year after the
+ date provided. This function can also return ``None`` or raise an
+ :class:`~django.http.Http404` exception, depending on the values of
+ :attr:`~BaseDateListView.allow_empty` and
+ :attr:`~DateMixin.allow_future`.
+
+ .. method:: get_previous_year(date)
+
+ Returns a date object containing the first day of the year before the
+ date provided. This function can also return ``None`` or raise an
+ :class:`~django.http.Http404` exception, depending on the values of
+ :attr:`~BaseDateListView.allow_empty` and
+ :attr:`~DateMixin.allow_future`.
+
MonthMixin
----------
-.. class:: django.views.generic.dates.MonthMixin
+.. class:: MonthMixin
A mixin that can be used to retrieve and provide parsing information for a
month component of a date.
@@ -51,26 +68,26 @@ MonthMixin
.. attribute:: month_format
- The :func:`~time.strftime` format to use when parsing the month. By default, this is
- ``'%b'``.
+ The :func:`~time.strftime` format to use when parsing the month. By
+ default, this is ``'%b'``.
.. attribute:: month
- **Optional** The value for the month (as a string). By default, set to
+ **Optional** The value for the month, as a string. By default, set to
``None``, which means the month will be determined using other means.
.. method:: get_month_format()
- Returns the :func:`~time.strftime` format to use when parsing the month. Returns
- :attr:`MonthMixin.month_format` by default.
+ Returns the :func:`~time.strftime` format to use when parsing the
+ month. Returns :attr:`~MonthMixin.month_format` by default.
.. method:: get_month()
- Returns the month for which this view will display data. Tries the
- following sources, in order:
+ Returns the month for which this view will display data, as a string.
+ Tries the following sources, in order:
* The value of the :attr:`MonthMixin.month` attribute.
- * The value of the `month` argument captured in the URL pattern
+ * The value of the `month` argument captured in the URL pattern.
* The value of the `month` GET query argument.
Raises a 404 if no valid month specification can be found.
@@ -78,20 +95,23 @@ MonthMixin
.. method:: get_next_month(date)
Returns a date object containing the first day of the month after the
- date provided. Returns ``None`` if mixed with a view that sets
- ``allow_future = False``, and the next month is in the future. If
- ``allow_empty = False``, returns the next month that contains data.
+ date provided. This function can also return ``None`` or raise an
+ :class:`~django.http.Http404` exception, depending on the values of
+ :attr:`~BaseDateListView.allow_empty` and
+ :attr:`~DateMixin.allow_future`.
.. method:: get_prev_month(date)
Returns a date object containing the first day of the month before the
- date provided. If ``allow_empty = False``, returns the previous month
- that contained data.
+ date provided. This function can also return ``None`` or raise an
+ :class:`~django.http.Http404` exception, depending on the values of
+ :attr:`~BaseDateListView.allow_empty` and
+ :attr:`~DateMixin.allow_future`.
DayMixin
--------
-.. class:: django.views.generic.dates.DayMixin
+.. class:: DayMixin
A mixin that can be used to retrieve and provide parsing information for a
day component of a date.
@@ -100,46 +120,50 @@ DayMixin
.. attribute:: day_format
- The :func:`~time.strftime` format to use when parsing the day. By default, this is
- ``'%d'``.
+ The :func:`~time.strftime` format to use when parsing the day. By
+ default, this is ``'%d'``.
.. attribute:: day
- **Optional** The value for the day (as a string). By default, set to
+ **Optional** The value for the day, as a string. By default, set to
``None``, which means the day will be determined using other means.
.. method:: get_day_format()
- Returns the :func:`~time.strftime` format to use when parsing the day. Returns
- :attr:`DayMixin.day_format` by default.
+ Returns the :func:`~time.strftime` format to use when parsing the day.
+ Returns :attr:`~DayMixin.day_format` by default.
.. method:: get_day()
- Returns the day for which this view will display data. Tries the
- following sources, in order:
+ Returns the day for which this view will display data, as a string.
+ Tries the following sources, in order:
* The value of the :attr:`DayMixin.day` attribute.
- * The value of the `day` argument captured in the URL pattern
+ * The value of the `day` argument captured in the URL pattern.
* The value of the `day` GET query argument.
Raises a 404 if no valid day specification can be found.
.. method:: get_next_day(date)
- Returns a date object containing the next day after the date provided.
- Returns ``None`` if mixed with a view that sets ``allow_future = False``,
- and the next day is in the future. If ``allow_empty = False``, returns
- the next day that contains data.
+ Returns a date object containing the next valid day after the date
+ provided. This function can also return ``None`` or raise an
+ :class:`~django.http.Http404` exception, depending on the values of
+ :attr:`~BaseDateListView.allow_empty` and
+ :attr:`~DateMixin.allow_future`.
.. method:: get_prev_day(date)
- Returns a date object containing the previous day. If
- ``allow_empty = False``, returns the previous day that contained data.
+ Returns a date object containing the previous valid day. This function
+ can also return ``None`` or raise an :class:`~django.http.Http404`
+ exception, depending on the values of
+ :attr:`~BaseDateListView.allow_empty` and
+ :attr:`~DateMixin.allow_future`.
WeekMixin
---------
-.. class:: django.views.generic.dates.WeekMixin
+.. class:: WeekMixin
A mixin that can be used to retrieve and provide parsing information for a
week component of a date.
@@ -148,23 +172,24 @@ WeekMixin
.. attribute:: week_format
- The :func:`~time.strftime` format to use when parsing the week. By default, this is
- ``'%U'``.
+ The :func:`~time.strftime` format to use when parsing the week. By
+ default, this is ``'%U'``, which means the week starts on Sunday. Set
+ it to ``'%W'`` if your week starts on Monday.
.. attribute:: week
- **Optional** The value for the week (as a string). By default, set to
+ **Optional** The value for the week, as a string. By default, set to
``None``, which means the week will be determined using other means.
.. method:: get_week_format()
- Returns the :func:`~time.strftime` format to use when parsing the week. Returns
- :attr:`WeekMixin.week_format` by default.
+ Returns the :func:`~time.strftime` format to use when parsing the
+ week. Returns :attr:`~WeekMixin.week_format` by default.
.. method:: get_week()
- Returns the week for which this view will display data. Tries the
- following sources, in order:
+ Returns the week for which this view will display data, as a string.
+ Tries the following sources, in order:
* The value of the :attr:`WeekMixin.week` attribute.
* The value of the `week` argument captured in the URL pattern
@@ -172,11 +197,26 @@ WeekMixin
Raises a 404 if no valid week specification can be found.
+ .. method:: get_next_week(date)
+
+ Returns a date object containing the first day of the week after the
+ date provided. This function can also return ``None`` or raise an
+ :class:`~django.http.Http404` exception, depending on the values of
+ :attr:`~BaseDateListView.allow_empty` and
+ :attr:`~DateMixin.allow_future`.
+
+ .. method:: get_prev_week(date)
+
+ Returns a date object containing the first day of the week before the
+ date provided. This function can also return ``None`` or raise an
+ :class:`~django.http.Http404` exception, depending on the values of
+ :attr:`~BaseDateListView.allow_empty` and
+ :attr:`~DateMixin.allow_future`.
DateMixin
---------
-.. class:: django.views.generic.dates.DateMixin
+.. class:: DateMixin
A mixin class providing common behavior for all date-based views.
@@ -186,7 +226,7 @@ DateMixin
The name of the ``DateField`` or ``DateTimeField`` in the
``QuerySet``'s model that the date-based archive should use to
- determine the objects on the page.
+ determine the list of objects to display on the page.
When :doc:`time zone support </topics/i18n/timezones>` is enabled and
``date_field`` is a ``DateTimeField``, dates are assumed to be in the
@@ -210,26 +250,26 @@ DateMixin
.. method:: get_date_field()
Returns the name of the field that contains the date data that this
- view will operate on. Returns :attr:`DateMixin.date_field` by default.
+ view will operate on. Returns :attr:`~DateMixin.date_field` by default.
.. method:: get_allow_future()
Determine whether to include "future" objects on this page, where
"future" means objects in which the field specified in ``date_field``
is greater than the current date/time. Returns
- :attr:`DateMixin.allow_future` by default.
+ :attr:`~DateMixin.allow_future` by default.
BaseDateListView
----------------
-.. class:: django.views.generic.dates.BaseDateListView
+.. class:: BaseDateListView
A base class that provides common behavior for all date-based views. There
won't normally be a reason to instantiate
:class:`~django.views.generic.dates.BaseDateListView`; instantiate one of
the subclasses instead.
- While this view (and it's subclasses) are executing, ``self.object_list``
+ While this view (and its subclasses) are executing, ``self.object_list``
will contain the list of objects that the view is operating upon, and
``self.date_list`` will contain the list of dates for which data is
available.
@@ -245,10 +285,18 @@ BaseDateListView
A boolean specifying whether to display the page if no objects are
available. If this is ``True`` and no objects are available, the view
- will display an empty page instead of raising a 404. By default, this
- is ``False``.
+ will display an empty page instead of raising a 404.
+
+ This is identical to :attr:`MultipleObjectMixin.allow_empty`, except
+ for the default value, which is ``False``.
+
+ .. attribute:: date_list_period
- .. method:: get_dated_items():
+ **Optional** A string defining the aggregation period for
+ ``date_list``. It must be one of ``'year'`` (default), ``'month'``, or
+ ``'day'``.
+
+ .. method:: get_dated_items()
Returns a 3-tuple containing (``date_list``, ``object_list``,
``extra_context``).
@@ -265,10 +313,17 @@ BaseDateListView
``lookup``. Enforces any restrictions on the queryset, such as
``allow_empty`` and ``allow_future``.
- .. method:: get_date_list(queryset, date_type)
+ .. method:: get_date_list_period()
+
+ Returns the aggregation period for ``date_list``. Returns
+ :attr:`~BaseDateListView.date_list_period` by default.
+
+ .. method:: get_date_list(queryset, date_type=None)
- Returns the list of dates of type ``date_type`` for which
- ``queryset`` contains entries. For example, ``get_date_list(qs,
- 'year')`` will return the list of years for which ``qs`` has entries.
- See :meth:`~django.db.models.query.QuerySet.dates()` for the
- ways that the ``date_type`` argument can be used.
+ Returns the list of dates of type ``date_type`` for which ``queryset``
+ contains entries. For example, ``get_date_list(qs, 'year')`` will
+ return the list of years for which ``qs`` has entries. If
+ ``date_type`` isn't provided, the result of
+ :meth:`BaseDateListView.get_date_list_period` is used. See
+ :meth:`~django.db.models.query.QuerySet.dates()` for the ways that the
+ ``date_type`` argument can be used.
diff --git a/docs/ref/class-based-views/mixins-multiple-object.txt b/docs/ref/class-based-views/mixins-multiple-object.txt
index 8bc613b887..cdb743fcbd 100644
--- a/docs/ref/class-based-views/mixins-multiple-object.txt
+++ b/docs/ref/class-based-views/mixins-multiple-object.txt
@@ -86,7 +86,8 @@ MultipleObjectMixin
.. method:: get_queryset()
- Returns the queryset that represents the data this view will display.
+ Get the list of items for this view. This must be an iterable and may
+ be a queryset (in which queryset-specific behavior will be enabled).
.. method:: paginate_queryset(queryset, page_size)
diff --git a/docs/ref/class-based-views/mixins-simple.txt b/docs/ref/class-based-views/mixins-simple.txt
index 61fc945cd3..d2f0df241e 100644
--- a/docs/ref/class-based-views/mixins-simple.txt
+++ b/docs/ref/class-based-views/mixins-simple.txt
@@ -9,16 +9,17 @@ ContextMixin
.. versionadded:: 1.5
- **classpath**
-
- ``django.views.generic.base.ContextMixin``
-
**Methods**
.. method:: get_context_data(**kwargs)
Returns a dictionary representing the template context. The keyword
- arguments provided will make up the returned context.
+ arguments provided will make up the returned context. Example usage::
+
+ def get_context_data(self, **kwargs):
+ context = super(RandomNumberView, self).get_context_data(**kwargs)
+ context['number'] = random.randrange(1, 100)
+ return context
The template context of all class-based generic views include a
``view`` variable that points to the ``View`` instance.
@@ -42,7 +43,13 @@ TemplateResponseMixin
suitable context. The template to use is configurable and can be
further customized by subclasses.
- **Methods and Attributes**
+ **Attributes**
+
+ .. attribute:: template_name
+
+ The full name of a template to use as defined by a string. Not defining
+ a template_name will raise a
+ :class:`django.core.exceptions.ImproperlyConfigured` exception.
.. attribute:: response_class
@@ -57,12 +64,14 @@ TemplateResponseMixin
instantiation, create a ``TemplateResponse`` subclass and assign it to
``response_class``.
+ **Methods**
+
.. method:: render_to_response(context, **response_kwargs)
Returns a ``self.response_class`` instance.
- If any keyword arguments are provided, they will be
- passed to the constructor of the response class.
+ If any keyword arguments are provided, they will be passed to the
+ constructor of the response class.
Calls :meth:`~TemplateResponseMixin.get_template_names()` to obtain the
list of template names that will be searched looking for an existent
diff --git a/docs/ref/contrib/comments/moderation.txt b/docs/ref/contrib/comments/moderation.txt
index 4f4b326cb2..f03c7fda0d 100644
--- a/docs/ref/contrib/comments/moderation.txt
+++ b/docs/ref/contrib/comments/moderation.txt
@@ -32,11 +32,11 @@ A simple example is the best illustration of this. Suppose we have the
following model, which would represent entries in a Weblog::
from django.db import models
-
+
class Entry(models.Model):
title = models.CharField(maxlength=250)
body = models.TextField()
- pub_date = models.DateTimeField()
+ pub_date = models.DateField()
enable_comments = models.BooleanField()
Now, suppose that we want the following steps to be applied whenever a
@@ -55,11 +55,11 @@ Accomplishing this is fairly straightforward and requires very little
code::
from django.contrib.comments.moderation import CommentModerator, moderator
-
+
class EntryModerator(CommentModerator):
email_notification = True
enable_field = 'enable_comments'
-
+
moderator.register(Entry, EntryModerator)
The :class:`CommentModerator` class pre-defines a number of useful moderation
diff --git a/docs/ref/contrib/contenttypes.txt b/docs/ref/contrib/contenttypes.txt
index 0226435159..e98da6e429 100644
--- a/docs/ref/contrib/contenttypes.txt
+++ b/docs/ref/contrib/contenttypes.txt
@@ -187,6 +187,14 @@ The ``ContentTypeManager``
probably won't ever need to call this method yourself; Django will call
it automatically when it's needed.
+ .. method:: get_for_id(id)
+
+ Lookup a :class:`~django.contrib.contenttypes.models.ContentType` by ID.
+ Since this method uses the same shared cache as
+ :meth:`~django.contrib.contenttypes.models.ContentTypeManager.get_for_model`,
+ it's preferred to use this method over the usual
+ ``ContentType.objects.get(pk=id)``
+
.. method:: get_for_model(model[, for_concrete_model=True])
Takes either a model class or an instance of a model, and returns the
diff --git a/docs/ref/contrib/formtools/form-wizard.txt b/docs/ref/contrib/formtools/form-wizard.txt
index b8e585a4d2..d5231de3e5 100644
--- a/docs/ref/contrib/formtools/form-wizard.txt
+++ b/docs/ref/contrib/formtools/form-wizard.txt
@@ -155,7 +155,8 @@ or the
:meth:`~django.views.generic.base.TemplateResponseMixin.get_template_names()`
method, which are documented in the
:class:`~django.views.generic.base.TemplateResponseMixin` documentation. The
-latter one allows you to use a different template for each form.
+latter one allows you to use a different template for each form (:ref:`see the
+example below <wizard-template-for-each-form>`).
This template expects a ``wizard`` object that has various items attached to
it:
@@ -238,6 +239,65 @@ wizard's :meth:`as_view` method takes a list of your
(r'^contact/$', ContactWizard.as_view([ContactForm1, ContactForm2])),
)
+.. _wizard-template-for-each-form:
+
+Using a different template for each form
+----------------------------------------
+
+As mentioned above, you may specify a different template for each form.
+Consider an example using a form wizard to implement a multi-step checkout
+process for an online store. In the first step, the user specifies a billing
+and shipping address. In the second step, the user chooses payment type. If
+they chose to pay by credit card, they will enter credit card information in
+the next step. In the final step, they will confirm the purchase.
+
+Here's what the view code might look like::
+
+ from django.http import HttpResponseRedirect
+ from django.contrib.formtools.wizard.views import SessionWizardView
+
+ FORMS = [("address", myapp.forms.AddressForm),
+ ("paytype", myapp.forms.PaymentChoiceForm),
+ ("cc", myapp.forms.CreditCardForm),
+ ("confirmation", myapp.forms.OrderForm)]
+
+ TEMPLATES = {"address": "checkout/billingaddress.html",
+ "paytype": "checkout/paymentmethod.html",
+ "cc": "checkout/creditcard.html",
+ "confirmation": "checkout/confirmation.html"}
+
+ def pay_by_credit_card(wizard):
+ """Return true if user opts to pay by credit card"""
+ # Get cleaned data from payment step
+ cleaned_data = wizard.get_cleaned_data_for_step('paytype') or {'method': 'none'}
+ # Return true if the user selected credit card
+ return cleaned_data['method'] == 'cc'
+
+
+ class OrderWizard(SessionWizardView):
+ def get_template_names(self):
+ return [TEMPLATES[self.steps.current]]
+
+ def done(self, form_list, **kwargs):
+ do_something_with_the_form_data(form_list)
+ return HttpResponseRedirect('/page-to-redirect-to-when-done/')
+ ...
+
+The ``urls.py`` file would contain something like::
+
+ urlpatterns = patterns('',
+ (r'^checkout/$', OrderWizard.as_view(FORMS, condition_dict={'cc': pay_by_credit_card})),
+ )
+
+Note that the ``OrderWizard`` object is initialized with a list of pairs.
+The first element in the pair is a string that corresponds to the name of the
+step and the second is the form class.
+
+In this example, the
+:meth:`~django.views.generic.base.TemplateResponseMixin.get_template_names()`
+method returns a list containing a single template, which is selected based on
+the name of the current step.
+
.. _wizardview-advanced-methods:
Advanced ``WizardView`` methods
diff --git a/docs/ref/contrib/gis/install.txt b/docs/ref/contrib/gis/install.txt
index 5dc3726ad1..b815973202 100644
--- a/docs/ref/contrib/gis/install.txt
+++ b/docs/ref/contrib/gis/install.txt
@@ -959,15 +959,15 @@ Ubuntu & Debian GNU/Linux
Ubuntu
^^^^^^
-11.10
-~~~~~
+11.10 through 12.04
+~~~~~~~~~~~~~~~~~~~
-In Ubuntu 11.10, PostgreSQL was upgraded to 9.1. The installation commands are:
+In Ubuntu 11.10, PostgreSQL was upgraded to 9.1. The installation command is:
.. code-block:: bash
- $ sudo apt-get install binutils gdal-bin libproj-dev postgresql-9.1-postgis \
- postgresql-server-dev-9.1 python-psycopg2
+ $ sudo apt-get install binutils gdal-bin libproj-dev \
+ postgresql-9.1-postgis postgresql-server-dev-9.1 python-psycopg2
.. _ubuntu10:
@@ -976,7 +976,7 @@ In Ubuntu 11.10, PostgreSQL was upgraded to 9.1. The installation commands are:
In Ubuntu 10.04, PostgreSQL was upgraded to 8.4 and GDAL was upgraded to 1.6.
Ubuntu 10.04 uses PostGIS 1.4, while Ubuntu 10.10 uses PostGIS 1.5 (with
-geography support). The installation commands are:
+geography support). The installation command is:
.. code-block:: bash
diff --git a/docs/ref/contrib/gis/tutorial.txt b/docs/ref/contrib/gis/tutorial.txt
index 15863aee7b..ec265342b3 100644
--- a/docs/ref/contrib/gis/tutorial.txt
+++ b/docs/ref/contrib/gis/tutorial.txt
@@ -674,8 +674,8 @@ __ http://spatialreference.org/ref/epsg/32140/
.. admonition:: Raw queries
When using :doc:`raw queries </topics/db/sql>`, you should generally wrap
- your geometry fields with the ``asText()`` SQL function so as the field
- value will be recognized by GEOS::
+ your geometry fields with the ``asText()`` SQL function (or ``ST_AsText``
+ for PostGIS) so as the field value will be recognized by GEOS::
City.objects.raw('SELECT id, name, asText(point) from myapp_city')
diff --git a/docs/ref/contrib/markup.txt b/docs/ref/contrib/markup.txt
index 8f3e0a95f9..9215c64f93 100644
--- a/docs/ref/contrib/markup.txt
+++ b/docs/ref/contrib/markup.txt
@@ -5,6 +5,9 @@ django.contrib.markup
.. module:: django.contrib.markup
:synopsis: A collection of template filters that implement common markup languages.
+.. deprecated:: 1.5
+ This module has been deprecated.
+
Django provides template filters that implement the following markup
languages:
diff --git a/docs/ref/contrib/messages.txt b/docs/ref/contrib/messages.txt
index 4cf90ee381..bc921a9d33 100644
--- a/docs/ref/contrib/messages.txt
+++ b/docs/ref/contrib/messages.txt
@@ -5,14 +5,16 @@ The messages framework
.. module:: django.contrib.messages
:synopsis: Provides cookie- and session-based temporary message storage.
-Quite commonly in web applications, you may need to display a one-time
-notification message (also know as "flash message") to the user after
-processing a form or some other types of user input. For this, Django provides
-full support for cookie- and session-based messaging, for both anonymous and
-authenticated users. The messages framework allows you to temporarily store
-messages in one request and retrieve them for display in a subsequent request
-(usually the next one). Every message is tagged with a specific ``level`` that
-determines its priority (e.g., ``info``, ``warning``, or ``error``).
+Quite commonly in web applications, you need to display a one-time
+notification message (also known as "flash message") to the user after
+processing a form or some other types of user input.
+
+For this, Django provides full support for cookie- and session-based
+messaging, for both anonymous and authenticated users. The messages framework
+allows you to temporarily store messages in one request and retrieve them for
+display in a subsequent request (usually the next one). Every message is
+tagged with a specific ``level`` that determines its priority (e.g., ``info``,
+``warning``, or ``error``).
Enabling messages
=================
@@ -20,32 +22,27 @@ Enabling messages
Messages are implemented through a :doc:`middleware </ref/middleware>`
class and corresponding :doc:`context processor </ref/templates/api>`.
-To enable message functionality, do the following:
-
-* Edit the :setting:`MIDDLEWARE_CLASSES` setting and make sure
- it contains ``'django.contrib.messages.middleware.MessageMiddleware'``.
+The default ``settings.py`` created by ``django-admin.py startproject``
+already contains all the settings required to enable message functionality:
- If you are using a :ref:`storage backend <message-storage-backends>` that
- relies on :doc:`sessions </topics/http/sessions>` (the default),
- ``'django.contrib.sessions.middleware.SessionMiddleware'`` must be
- enabled and appear before ``MessageMiddleware`` in your
- :setting:`MIDDLEWARE_CLASSES`.
+* ``'django.contrib.messages'`` is in :setting:`INSTALLED_APPS`.
-* Edit the :setting:`TEMPLATE_CONTEXT_PROCESSORS` setting and make sure
- it contains ``'django.contrib.messages.context_processors.messages'``.
+* :setting:`MIDDLEWARE_CLASSES` contains
+ ``'django.contrib.sessions.middleware.SessionMiddleware'`` and
+ ``'django.contrib.messages.middleware.MessageMiddleware'``.
-* Add ``'django.contrib.messages'`` to your :setting:`INSTALLED_APPS`
- setting
+ The default :ref:`storage backend <message-storage-backends>` relies on
+ :doc:`sessions </topics/http/sessions>`. That's why ``SessionMiddleware``
+ must be enabled and appear before ``MessageMiddleware`` in
+ :setting:`MIDDLEWARE_CLASSES`.
-The default ``settings.py`` created by ``django-admin.py startproject`` has
-``MessageMiddleware`` activated and the ``django.contrib.messages`` app
-installed. Also, the default value for :setting:`TEMPLATE_CONTEXT_PROCESSORS`
-contains ``'django.contrib.messages.context_processors.messages'``.
+* :setting:`TEMPLATE_CONTEXT_PROCESSORS` contains
+ ``'django.contrib.messages.context_processors.messages'``.
-If you don't want to use messages, you can remove the
-``MessageMiddleware`` line from :setting:`MIDDLEWARE_CLASSES`, the ``messages``
-context processor from :setting:`TEMPLATE_CONTEXT_PROCESSORS` and
-``'django.contrib.messages'`` from your :setting:`INSTALLED_APPS`.
+If you don't want to use messages, you can remove
+``'django.contrib.messages'`` from your :setting:`INSTALLED_APPS`, the
+``MessageMiddleware`` line from :setting:`MIDDLEWARE_CLASSES`, and the
+``messages`` context processor from :setting:`TEMPLATE_CONTEXT_PROCESSORS`.
Configuring the message engine
==============================
@@ -56,34 +53,35 @@ Storage backends
----------------
The messages framework can use different backends to store temporary messages.
-If the default FallbackStorage isn't suitable to your needs, you can change
-which backend is being used by adding a `MESSAGE_STORAGE`_ to your
-settings, referencing the module and class of the storage class. For
-example::
- MESSAGE_STORAGE = 'django.contrib.messages.storage.cookie.CookieStorage'
+Django provides three built-in storage classes:
-The value should be the full path of the desired storage class.
+.. class:: django.contrib.messages.storage.session.SessionStorage
-Three storage classes are available:
+ This class stores all messages inside of the request's session. Therefore
+ it requires Django's ``contrib.sessions`` application.
-``'django.contrib.messages.storage.session.SessionStorage'``
- This class stores all messages inside of the request's session. It
- requires Django's ``contrib.sessions`` application.
+.. class:: django.contrib.messages.storage.cookie.CookieStorage
-``'django.contrib.messages.storage.cookie.CookieStorage'``
This class stores the message data in a cookie (signed with a secret hash
to prevent manipulation) to persist notifications across requests. Old
- messages are dropped if the cookie data size would exceed 4096 bytes.
+ messages are dropped if the cookie data size would exceed 2048 bytes.
+
+.. class:: django.contrib.messages.storage.fallback.FallbackStorage
-``'django.contrib.messages.storage.fallback.FallbackStorage'``
- This is the default storage class.
+ This class first uses ``CookieStorage``, and falls back to using
+ ``SessionStorage`` for the messages that could not fit in a single cookie.
+ It also requires Django's ``contrib.sessions`` application.
- This class first uses CookieStorage for all messages, falling back to using
- SessionStorage for the messages that could not fit in a single cookie.
+ This behavior avoids writing to the session whenever possible. It should
+ provide the best performance in the general case.
- Since it is uses SessionStorage, it also requires Django's
- ``contrib.sessions`` application.
+:class:`~django.contrib.messages.storage.fallback.FallbackStorage` is the
+default storage class. If it isn't suitable to your needs, you can select
+another storage class by setting `MESSAGE_STORAGE`_ to its full import path,
+for example::
+
+ MESSAGE_STORAGE = 'django.contrib.messages.storage.cookie.CookieStorage'
To write your own storage class, subclass the ``BaseStorage`` class in
``django.contrib.messages.storage.base`` and implement the ``_get`` and
@@ -97,8 +95,8 @@ to that of the Python logging module. Message levels allow you to group
messages by type so they can be filtered or displayed differently in views and
templates.
-The built-in levels (which can be imported from ``django.contrib.messages``
-directly) are:
+The built-in levels, which can be imported from ``django.contrib.messages``
+directly, are:
=========== ========
Constant Purpose
diff --git a/docs/ref/forms/fields.txt b/docs/ref/forms/fields.txt
index 082ec17a35..7c06bf97ee 100644
--- a/docs/ref/forms/fields.txt
+++ b/docs/ref/forms/fields.txt
@@ -398,11 +398,21 @@ For each field, we describe the default widget used if you don't specify
If no ``input_formats`` argument is provided, the default input formats are::
- '%Y-%m-%d', '%m/%d/%Y', '%m/%d/%y', # '2006-10-25', '10/25/2006', '10/25/06'
- '%b %d %Y', '%b %d, %Y', # 'Oct 25 2006', 'Oct 25, 2006'
- '%d %b %Y', '%d %b, %Y', # '25 Oct 2006', '25 Oct, 2006'
- '%B %d %Y', '%B %d, %Y', # 'October 25 2006', 'October 25, 2006'
- '%d %B %Y', '%d %B, %Y', # '25 October 2006', '25 October, 2006'
+ '%Y-%m-%d', # '2006-10-25'
+ '%m/%d/%Y', # '10/25/2006'
+ '%m/%d/%y', # '10/25/06'
+
+ Additionally, if you specify :setting:`USE_L10N=False<USE_L10N>` in your settings, the
+ following will also be included in the default input formats::
+
+ '%b %m %d', # 'Oct 25 2006'
+ '%b %d, %Y', # 'Oct 25, 2006'
+ '%d %b %Y', # '25 Oct 2006'
+ '%d %b, %Y', # '25 Oct, 2006'
+ '%B %d %Y', # 'October 25 2006'
+ '%B %d, %Y', # 'October 25, 2006'
+ '%d %B %Y', # '25 October 2006'
+ '%d %B, %Y', # '25 October, 2006'
``DateTimeField``
~~~~~~~~~~~~~~~~~
@@ -842,7 +852,7 @@ Slightly complex built-in ``Field`` classes
``MultiValueField``
~~~~~~~~~~~~~~~~~~~
-.. class:: MultiValueField(**kwargs)
+.. class:: MultiValueField(fields=(), **kwargs)
* Default widget: ``TextInput``
* Empty value: ``''`` (an empty string)
@@ -851,22 +861,39 @@ Slightly complex built-in ``Field`` classes
as an argument to the ``MultiValueField``.
* Error message keys: ``required``, ``invalid``
- This abstract field (must be subclassed) aggregates the logic of multiple
- fields. Subclasses should not have to implement clean(). Instead, they must
- implement compress(), which takes a list of valid values and returns a
- "compressed" version of those values -- a single value. For example,
- :class:`SplitDateTimeField` is a subclass which combines a time field and
- a date field into a datetime object.
+ Aggregates the logic of multiple fields that together produce a single
+ value.
+
+ This field is abstract and must be subclassed. In contrast with the
+ single-value fields, subclasses of :class:`MultiValueField` must not
+ implement :meth:`~django.forms.Field.clean` but instead - implement
+ :meth:`~MultiValueField.compress`.
Takes one extra required argument:
.. attribute:: fields
- A list of fields which are cleaned into a single field. Each value in
- ``clean`` is cleaned by the corresponding field in ``fields`` -- the first
- value is cleaned by the first field, the second value is cleaned by
- the second field, etc. Once all fields are cleaned, the list of clean
- values is "compressed" into a single value.
+ A tuple of fields whose values are cleaned and subsequently combined
+ into a single value. Each value of the field is cleaned by the
+ corresponding field in ``fields`` -- the first value is cleaned by the
+ first field, the second value is cleaned by the second field, etc.
+ Once all fields are cleaned, the list of clean values is combined into
+ a single value by :meth:`~MultiValueField.compress`.
+
+ .. attribute:: MultiValueField.widget
+
+ Must be a subclass of :class:`django.forms.MultiWidget`.
+ Default value is :class:`~django.forms.widgets.TextInput`, which
+ probably is not very useful in this case.
+
+ .. method:: compress(data_list)
+
+ Takes a list of valid values and returns a "compressed" version of
+ those values -- in a single value. For example,
+ :class:`SplitDateTimeField` is a subclass which combines a time field
+ and a date field into a ``datetime`` object.
+
+ This method must be implemented in the subclasses.
``SplitDateTimeField``
~~~~~~~~~~~~~~~~~~~~~~
diff --git a/docs/ref/forms/widgets.txt b/docs/ref/forms/widgets.txt
index eab314a4cd..4724cbdec2 100644
--- a/docs/ref/forms/widgets.txt
+++ b/docs/ref/forms/widgets.txt
@@ -11,6 +11,16 @@ 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.
+.. tip::
+
+ Widgets should not be confused with the :doc:`form fields </ref/forms/fields>`.
+ Form fields deal with the logic of input validation and are used directly
+ in templates. Widgets deal with rendering of HTML form input elements on
+ the web page and extraction of raw submitted data. However, widgets do
+ need to be :ref:`assigned <widget-to-field>` to form fields.
+
+.. _widget-to-field:
+
Specifying widgets
------------------
@@ -95,15 +105,23 @@ choices are inherent to the model and not just the representational 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 :class:`TextInput` widgets will appear the same
-on your Web page.
+When Django renders a widget as HTML, it only renders very minimal markup -
+Django doesn't add class names, or any other widget-specific attributes. This
+means, for example, that all :class:`TextInput` widgets will appear the same
+on your Web pages.
+
+There are two ways to customize widgets: :ref:`per widget instance
+<styling-widget-instances>` and :ref:`per widget class <styling-widget-classes>`.
-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.
+.. _styling-widget-instances:
+
+Styling widget instances
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+If you want to make one widget instance look different from another, you will
+need to specify additional attributes at the time when the widget object is
+instantiated and assigned to a form field (and perhaps add some rules to your
+CSS files).
For example, take the following simple form::
@@ -126,10 +144,9 @@ provided for each widget will be rendered exactly the same::
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 use the
-:attr:`Widget.attrs` argument when creating the widget:
-
-For example::
+'name' widget to have some special CSS class. It is also possible to specify
+the 'type' attribute to take advantage of the new HTML5 input types. To do
+this, you use the :attr:`Widget.attrs` argument when creating the widget::
class CommentForm(forms.Form):
name = forms.CharField(
@@ -146,24 +163,41 @@ Django will then include the extra attributes in the rendered output:
<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>
-.. _built-in widgets:
+.. _styling-widget-classes:
-Built-in widgets
-----------------
+Styling widget classes
+^^^^^^^^^^^^^^^^^^^^^^
-Django provides a representation of all the basic HTML widgets, plus some
-commonly used groups of widgets:
+With widgets, it is possible to add media (``css`` and ``javascript``)
+and more deeply customize their appearance and behavior.
-``Widget``
-~~~~~~~~~~
+In a nutshell, you will need to subclass the widget and either
+:ref:`define a class "Media" <media-as-a-static-definition>` as a member of the
+subclass, or :ref:`create a property "media" <dynamic-property>`, returning an
+instance of that class.
+
+These methods involve somewhat advanced Python programming and are described in
+detail in the :doc:`Form Media </topics/forms/media>` topic guide.
+
+.. _base-widget-classes:
+
+Base Widget classes
+-------------------
-.. class:: Widget
+Base widget classes :class:`Widget` and :class:`MultiWidget` are subclassed by
+all the :ref:`built-in widgets <built-in widgets>` and may serve as a
+foundation for custom widgets.
- This abstract class cannot be rendered, but provides the basic attribute :attr:`~Widget.attrs`.
+.. class:: Widget(attrs=None)
+
+ This abstract class cannot be rendered, but provides the basic attribute
+ :attr:`~Widget.attrs`. You may also implement or override the
+ :meth:`~Widget.render()` method on custom widgets.
.. attribute:: Widget.attrs
- A dictionary containing HTML attributes to be set on the rendered widget.
+ A dictionary containing HTML attributes to be set on the rendered
+ widget.
.. code-block:: python
@@ -171,6 +205,74 @@ commonly used groups of widgets:
>>> name.render('name', 'A name')
u'<input title="Your name" type="text" name="name" value="A name" size="10" />'
+ .. method:: render(name, value, attrs=None)
+
+ Returns HTML for the widget, as a Unicode string. This method must be
+ implemented by the subclass, otherwise ``NotImplementedError`` will be
+ raised.
+
+ The 'value' given is not guaranteed to be valid input, therefore
+ subclass implementations should program defensively.
+
+.. class:: MultiWidget(widgets, attrs=None)
+
+ A widget that is composed of multiple widgets.
+ :class:`~django.forms.widgets.MultiWidget` works hand in hand with the
+ :class:`~django.forms.MultiValueField`.
+
+ .. method:: render(name, value, attrs=None)
+
+ Argument `value` is handled differently in this method from the
+ subclasses of :class:`~Widget`.
+
+ If `value` is a list, output of :meth:`~MultiWidget.render` will be a
+ concatenation of rendered child widgets. If `value` is not a list, it
+ will be first processed by the method :meth:`~MultiWidget.decompress()`
+ to create the list and then processed as above.
+
+ Unlike in the single value widgets, method :meth:`~MultiWidget.render`
+ need not be implemented in the subclasses.
+
+ .. method:: decompress(value)
+
+ Returns a list of "decompressed" values for the given value of the
+ multi-value field that makes use of the widget. The input value can be
+ assumed as valid, but not necessarily non-empty.
+
+ This method **must be implemented** by the subclass, and since the
+ value may be empty, the implementation must be defensive.
+
+ The rationale behind "decompression" is that it is necessary to "split"
+ the combined value of the form field into the values of the individual
+ field encapsulated within the multi-value field (e.g. when displaying
+ the partially or fully filled-out form).
+
+ .. tip::
+
+ Note that :class:`~django.forms.MultiValueField` has a
+ complementary method :meth:`~django.forms.MultiValueField.compress`
+ with the opposite responsibility - to combine cleaned values of
+ all member fields into one.
+
+
+.. _built-in widgets:
+
+Built-in widgets
+----------------
+
+Django provides a representation of all the basic HTML widgets, plus some
+commonly used groups of widgets in the ``django.forms.widgets`` module,
+including :ref:`the input of text <text-widgets>`, :ref:`various checkboxes
+and selectors <selector-widgets>`, :ref:`uploading files <file-upload-widgets>`,
+and :ref:`handling of multi-valued input <composite-widgets>`.
+
+.. _text-widgets:
+
+Widgets handling input of text
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+These widgets make use of the HTML elements ``input`` and ``textarea``.
+
``TextInput``
~~~~~~~~~~~~~
@@ -204,39 +306,8 @@ commonly used groups of widgets:
Hidden input: ``<input type='hidden' ...>``
-``MultipleHiddenInput``
-~~~~~~~~~~~~~~~~~~~~~~~
-
-.. class:: MultipleHiddenInput
-
- Multiple ``<input type='hidden' ...>`` widgets.
-
- A widget that handles multiple hidden widgets for fields that have a list
- of values.
-
- .. attribute:: MultipleHiddenInput.choices
-
- This attribute is optional when the field does not have a
- :attr:`~Field.choices` attribute. If it does, it will override anything
- you set here when the attribute is updated on the :class:`Field`.
-
-``FileInput``
-~~~~~~~~~~~~~
-
-.. class:: FileInput
-
- File upload input: ``<input type='file' ...>``
-
-``ClearableFileInput``
-~~~~~~~~~~~~~~~~~~~~~~
-
-.. class:: ClearableFileInput
-
- .. versionadded:: 1.3
-
- File upload input: ``<input type='file' ...>``, with an additional checkbox
- input to clear the field's value, if the field is not required and has
- initial data.
+ Note that there also is a :class:`MultipleHiddenInput` widget that
+ encapsulates a set of hidden input elements.
``DateInput``
~~~~~~~~~~~~~
@@ -245,7 +316,7 @@ commonly used groups of widgets:
Date input as a simple text box: ``<input type='text' ...>``
- Takes one optional argument:
+ Takes same arguments as :class:`TextInput`, with one more optional argument:
.. attribute:: DateInput.format
@@ -262,7 +333,7 @@ commonly used groups of widgets:
Date/time input as a simple text box: ``<input type='text' ...>``
- Takes one optional argument:
+ Takes same arguments as :class:`TextInput`, with one more optional argument:
.. attribute:: DateTimeInput.format
@@ -279,7 +350,7 @@ commonly used groups of widgets:
Time input as a simple text box: ``<input type='text' ...>``
- Takes one optional argument:
+ Takes same arguments as :class:`TextInput`, with one more optional argument:
.. attribute:: TimeInput.format
@@ -296,6 +367,11 @@ commonly used groups of widgets:
Text area: ``<textarea>...</textarea>``
+.. _selector-widgets:
+
+Selector and checkbox widgets
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
``CheckboxInput``
~~~~~~~~~~~~~~~~~
@@ -439,6 +515,50 @@ commonly used groups of widgets:
...
</ul>
+.. _file-upload-widgets:
+
+File upload widgets
+^^^^^^^^^^^^^^^^^^^
+
+``FileInput``
+~~~~~~~~~~~~~
+
+.. class:: FileInput
+
+ File upload input: ``<input type='file' ...>``
+
+``ClearableFileInput``
+~~~~~~~~~~~~~~~~~~~~~~
+
+.. class:: ClearableFileInput
+
+ .. versionadded:: 1.3
+
+ File upload input: ``<input type='file' ...>``, with an additional checkbox
+ input to clear the field's value, if the field is not required and has
+ initial data.
+
+.. _composite-widgets:
+
+Composite widgets
+^^^^^^^^^^^^^^^^^
+
+``MultipleHiddenInput``
+~~~~~~~~~~~~~~~~~~~~~~~
+
+.. class:: MultipleHiddenInput
+
+ Multiple ``<input type='hidden' ...>`` widgets.
+
+ A widget that handles multiple hidden widgets for fields that have a list
+ of values.
+
+ .. attribute:: MultipleHiddenInput.choices
+
+ This attribute is optional when the field does not have a
+ :attr:`~Field.choices` attribute. If it does, it will override anything
+ you set here when the attribute is updated on the :class:`Field`.
+
``MultiWidget``
~~~~~~~~~~~~~~~
diff --git a/docs/ref/models/fields.txt b/docs/ref/models/fields.txt
index 275c696230..8b3c31f029 100644
--- a/docs/ref/models/fields.txt
+++ b/docs/ref/models/fields.txt
@@ -195,6 +195,14 @@ support tablespaces for indexes, this option is ignored.
The default value for the field. This can be a value or a callable object. If
callable it will be called every time a new object is created.
+The default cannot be a mutable object (model instance, list, set, etc.), as a
+reference to the same instance of that object would be used as the default
+value in all new model instances. Instead, wrap the desired default in a
+callable. For example, if you had a custom ``JSONField`` and wanted to specify
+a dictionary as the default, use a ``lambda`` as follows::
+
+ contact_info = JSONField("ContactInfo", default=lambda:{"email": "to1@example.com"})
+
``editable``
------------
@@ -983,10 +991,10 @@ define the details of how the relation works.
this with functions from the Python ``datetime`` module to limit choices of
objects by date. For example::
- limit_choices_to = {'pub_date__lte': datetime.now}
+ limit_choices_to = {'pub_date__lte': datetime.date.today}
only allows the choice of related objects with a ``pub_date`` before the
- current date/time to be chosen.
+ current date to be chosen.
Instead of a dictionary this can also be a :class:`~django.db.models.Q`
object for more :ref:`complex queries <complex-lookups-with-q>`. However,
diff --git a/docs/ref/models/instances.txt b/docs/ref/models/instances.txt
index 472ac96457..2fdc87df8c 100644
--- a/docs/ref/models/instances.txt
+++ b/docs/ref/models/instances.txt
@@ -135,7 +135,7 @@ access to more than a single field::
raise ValidationError('Draft entries may not have a publication date.')
# Set the pub_date for published items if it hasn't been set already.
if self.status == 'published' and self.pub_date is None:
- self.pub_date = datetime.datetime.now()
+ self.pub_date = datetime.date.today()
Any :exc:`~django.core.exceptions.ValidationError` exceptions raised by
``Model.clean()`` will be stored in a special key error dictionary key,
diff --git a/docs/ref/models/querysets.txt b/docs/ref/models/querysets.txt
index 4f5f8858b5..8ec7cfc791 100644
--- a/docs/ref/models/querysets.txt
+++ b/docs/ref/models/querysets.txt
@@ -31,6 +31,9 @@ You can evaluate a ``QuerySet`` in the following ways:
for e in Entry.objects.all():
print(e.headline)
+ Note: Don't use this if all you want to do is determine if at least one
+ result exists. It's more efficient to use :meth:`~QuerySet.exists`.
+
* **Slicing.** As explained in :ref:`limiting-querysets`, a ``QuerySet`` can
be sliced, using Python's array-slicing syntax. Slicing an unevaluated
``QuerySet`` usually returns another unevaluated ``QuerySet``, but Django
@@ -75,7 +78,7 @@ You can evaluate a ``QuerySet`` in the following ways:
Note: *Don't* use this if all you want to do is determine if at least one
result exists, and don't need the actual objects. It's more efficient to
- use :meth:`exists() <QuerySet.exists>` (see below).
+ use :meth:`~QuerySet.exists` (see below).
.. _pickling QuerySets:
@@ -1047,7 +1050,7 @@ defer
In some complex data-modeling situations, your models might contain a lot of
fields, some of which could contain a lot of data (for example, text fields),
or require expensive processing to convert them to Python objects. If you are
-using the results of a queryset in some situation where you know you don't know
+using the results of a queryset in some situation where you don't know
if you need those particular fields when you initially fetch the data, you can
tell Django not to retrieve them from the database.
@@ -1523,9 +1526,40 @@ exists
Returns ``True`` if the :class:`.QuerySet` contains any results, and ``False``
if not. This tries to perform the query in the simplest and fastest way
-possible, but it *does* execute nearly the same query. This means that calling
-:meth:`.QuerySet.exists` is faster than ``bool(some_query_set)``, but not by
-a large degree. If ``some_query_set`` has not yet been evaluated, but you know
+possible, but it *does* execute nearly the same query as a normal
+:class:`.QuerySet` query.
+
+:meth:`~.QuerySet.exists` is useful for searches relating to both
+object membership in a :class:`.QuerySet` and to the existence of any objects in
+a :class:`.QuerySet`, particularly in the context of a large :class:`.QuerySet`.
+
+The most efficient method of finding whether a model with a unique field
+(e.g. ``primary_key``) is a member of a :class:`.QuerySet` is::
+
+ entry = Entry.objects.get(pk=123)
+ if some_query_set.filter(pk=entry.pk).exists():
+ print("Entry contained in queryset")
+
+Which will be faster than the following which requires evaluating and iterating
+through the entire queryset::
+
+ if entry in some_query_set:
+ print("Entry contained in QuerySet")
+
+And to find whether a queryset contains any items::
+
+ if some_query_set.exists():
+ print("There is at least one object in some_query_set")
+
+Which will be faster than::
+
+ if some_query_set:
+ print("There is at least one object in some_query_set")
+
+... but not by a large degree (hence needing a large queryset for efficiency
+gains).
+
+Additionally, if a ``some_query_set`` has not yet been evaluated, but you know
that it will be at some point, then using ``some_query_set.exists()`` will do
more overall work (one query for the existence check plus an extra one to later
retrieve the results) than simply using ``bool(some_query_set)``, which
@@ -1945,6 +1979,17 @@ SQL equivalent::
You can use ``range`` anywhere you can use ``BETWEEN`` in SQL — for dates,
numbers and even characters.
+.. warning::
+
+ Filtering a ``DateTimeField`` with dates won't include items on the last
+ day, because the bounds are interpreted as "0am on the given date". If
+ ``pub_date`` was a ``DateTimeField``, the above expression would be turned
+ into this SQL::
+
+ SELECT ... WHERE pub_date BETWEEN '2005-01-01 00:00:00' and '2005-03-31 00:00:00';
+
+ Generally speaking, you can't mix dates and datetimes.
+
.. fieldlookup:: year
year
@@ -1958,7 +2003,7 @@ Example::
SQL equivalent::
- SELECT ... WHERE pub_date BETWEEN '2005-01-01' AND '2005-12-31 23:59:59.999999';
+ SELECT ... WHERE pub_date BETWEEN '2005-01-01' AND '2005-12-31';
(The exact SQL syntax varies for each database engine.)
diff --git a/docs/ref/settings.txt b/docs/ref/settings.txt
index 4729a2b6f1..16d067172d 100644
--- a/docs/ref/settings.txt
+++ b/docs/ref/settings.txt
@@ -1304,25 +1304,13 @@ The URL where requests are redirected after login when the
This is used by the :func:`~django.contrib.auth.decorators.login_required`
decorator, for example.
-.. _`note on LOGIN_REDIRECT_URL setting`:
-
-.. note::
- You can use :func:`~django.core.urlresolvers.reverse_lazy` to reference
- URLs by their name instead of providing a hardcoded value. Assuming a
- ``urls.py`` with an URLpattern named ``home``::
-
- urlpatterns = patterns('',
- url('^welcome/$', 'test_app.views.home', name='home'),
- )
-
- You can use :func:`~django.core.urlresolvers.reverse_lazy` like this::
-
- from django.core.urlresolvers import reverse_lazy
-
- LOGIN_REDIRECT_URL = reverse_lazy('home')
+.. versionchanged:: 1.5
- This also works fine with localized URLs using
- :func:`~django.conf.urls.i18n.i18n_patterns`.
+This setting now also accepts view function names and
+:ref:`named URL patterns <naming-url-patterns>` which can be used to reduce
+configuration duplication since you no longer have to define the URL in two
+places (``settings`` and URLconf).
+For backward compatibility reasons the default remains unchanged.
.. setting:: LOGIN_URL
@@ -1334,8 +1322,13 @@ Default: ``'/accounts/login/'``
The URL where requests are redirected for login, especially when using the
:func:`~django.contrib.auth.decorators.login_required` decorator.
-.. note::
- See the `note on LOGIN_REDIRECT_URL setting`_
+.. versionchanged:: 1.5
+
+This setting now also accepts view function names and
+:ref:`named URL patterns <naming-url-patterns>` which can be used to reduce
+configuration duplication since you no longer have to define the URL in two
+places (``settings`` and URLconf).
+For backward compatibility reasons the default remains unchanged.
.. setting:: LOGOUT_URL
@@ -1346,9 +1339,6 @@ Default: ``'/accounts/logout/'``
LOGIN_URL counterpart.
-.. note::
- See the `note on LOGIN_REDIRECT_URL setting`_
-
.. setting:: MANAGERS
MANAGERS
diff --git a/docs/releases/1.5.txt b/docs/releases/1.5.txt
index 5728d8559a..6420239f47 100644
--- a/docs/releases/1.5.txt
+++ b/docs/releases/1.5.txt
@@ -121,6 +121,12 @@ Django 1.5 also includes several smaller improvements worth noting:
argument. By default the batch_size is unlimited except for SQLite where
single batch is limited so that 999 parameters per query isn't exceeded.
+* The :setting:`LOGIN_URL` and :setting:`LOGIN_REDIRECT_URL` settings now also
+ accept view function names and
+ :ref:`named URL patterns <naming-url-patterns>`. This allows you to reduce
+ configuration duplication. More information can be found in the
+ :func:`~django.contrib.auth.decorators.login_required` documentation.
+
Backwards incompatible changes in 1.5
=====================================
@@ -358,3 +364,11 @@ the built-in :func:`itertools.product` instead.
The :class:`~django.utils.encoding.StrAndUnicode` mix-in has been deprecated.
Define a ``__str__`` method and apply the
:func:`~django.utils.encoding.python_2_unicode_compatible` decorator instead.
+
+``django.utils.markup``
+~~~~~~~~~~~~~~~~~~~~~~~
+
+The markup contrib module has been deprecated and will follow an accelerated
+deprecation schedule. Direct use of python markup libraries or 3rd party tag
+libraries is preferred to Django maintaining this functionality in the
+framework.
diff --git a/docs/releases/index.txt b/docs/releases/index.txt
index fa55a4d206..2329d1effa 100644
--- a/docs/releases/index.txt
+++ b/docs/releases/index.txt
@@ -14,6 +14,7 @@ up to and including the new version.
Final releases
==============
+.. _development_release_notes:
1.5 release
-----------
diff --git a/docs/topics/auth.txt b/docs/topics/auth.txt
index f8dbbb65a6..ef03d5479c 100644
--- a/docs/topics/auth.txt
+++ b/docs/topics/auth.txt
@@ -650,6 +650,36 @@ the handler, if ``created`` is ``True``, create the associated user profile::
.. seealso:: :doc:`/topics/signals` for more information on Django's signal
dispatcher.
+Adding UserProfile fields to the admin
+--------------------------------------
+
+To add the UserProfile fields to the user page in the admin, define an
+:class:`~django.contrib.admin.InlineModelAdmin` (for this example, we'll use a
+:class:`~django.contrib.admin.StackedInline`) in your app's ``admin.py`` and
+add it to a ``UserAdmin`` class which is registered with the
+:class:`~django.contrib.auth.models.User` class::
+
+ from django.contrib import admin
+ from django.contrib.auth.admin import UserAdmin
+ from django.contrib.auth.models import User
+
+ from my_user_profile_app.models import UserProfile
+
+ # Define an inline admin descriptor for UserProfile model
+ # which acts a bit like a singleton
+ class UserProfileInline(admin.StackedInline):
+ model = UserProfile
+ can_delete = False
+ verbose_name_plural = 'profile'
+
+ # Define a new User admin
+ class UserAdmin(UserAdmin):
+ inlines = (UserProfileInline, )
+
+ # Re-register UserAdmin
+ admin.site.unregister(User)
+ admin.site.register(User, UserAdmin)
+
Authentication in Web requests
==============================
@@ -947,6 +977,13 @@ The login_required decorator
(r'^accounts/login/$', 'django.contrib.auth.views.login'),
+ .. versionchanged:: 1.5
+
+ As of version 1.5 :setting:`settings.LOGIN_URL <LOGIN_URL>` now also accepts
+ view function names and :ref:`named URL patterns <naming-url-patterns>`.
+ This allows you to freely remap your login view within your URLconf
+ without having to update the setting.
+
.. function:: views.login(request, [template_name, redirect_field_name, authentication_form])
**URL name:** ``login``
diff --git a/docs/topics/class-based-views/index.txt b/docs/topics/class-based-views/index.txt
index 6637bd5fcb..2d3e00ab4c 100644
--- a/docs/topics/class-based-views/index.txt
+++ b/docs/topics/class-based-views/index.txt
@@ -84,6 +84,50 @@ function-like entry to class-based views::
For more information on how to use the built in generic views, consult the next
topic on :doc:`generic class based views</topics/class-based-views/generic-display>`.
+.. _supporting-other-http-methods:
+
+Supporting other HTTP methods
+-----------------------------
+
+Suppose somebody wants to access our book library over HTTP using the views
+as an API. The API client would connect every now and then and download book
+data for the books published since last visit. But if no new books appeared
+since then, it is a waste of CPU time and bandwidth to fetch the books from the
+database, render a full response and send it to the client. It might be
+preferable to ask the API when the most recent book was published.
+
+We map the URL to book list view in the URLconf::
+
+ from django.conf.urls import patterns
+ from books.views import BookListView
+
+ urlpatterns = patterns('',
+ (r'^books/$', BookListView.as_view()),
+ )
+
+And the view::
+
+ from django.http import HttpResponse
+ from django.views.generic import ListView
+ from books.models import Book
+
+ class BookListView(ListView):
+ model = Book
+
+ def head(self, *args, **kwargs):
+ last_book = self.get_queryset().latest('publication_date')
+ response = HttpResponse('')
+ # RFC 1123 date format
+ response['Last-Modified'] = last_book.publication_date.strftime('%a, %d %b %Y %H:%M:%S GMT')
+ return response
+
+If the view is accessed from a ``GET`` request, a plain-and-simple object
+list is returned in the response (using ``book_list.html`` template). But if
+the client issues a ``HEAD`` request, the response has an empty body and
+the ``Last-Modified`` header indicates when the most recent book was published.
+Based on this information, the client may or may not download the full object
+list.
+
Decorating class-based views
============================
diff --git a/docs/topics/db/examples/many_to_one.txt b/docs/topics/db/examples/many_to_one.txt
index 0a9978b8d1..c869362d16 100644
--- a/docs/topics/db/examples/many_to_one.txt
+++ b/docs/topics/db/examples/many_to_one.txt
@@ -42,8 +42,8 @@ Create a few Reporters::
Create an Article::
- >>> from datetime import datetime
- >>> a = Article(id=None, headline="This is a test", pub_date=datetime(2005, 7, 27), reporter=r)
+ >>> from datetime import date
+ >>> a = Article(id=None, headline="This is a test", pub_date=date(2005, 7, 27), reporter=r)
>>> a.save()
>>> a.reporter.id
@@ -65,7 +65,7 @@ database, which always returns unicode strings)::
Create an Article via the Reporter object::
- >>> new_article = r.article_set.create(headline="John's second story", pub_date=datetime(2005, 7, 29))
+ >>> new_article = r.article_set.create(headline="John's second story", pub_date=date(2005, 7, 29))
>>> new_article
<Article: John's second story>
>>> new_article.reporter
@@ -75,7 +75,7 @@ Create an Article via the Reporter object::
Create a new article, and add it to the article set::
- >>> new_article2 = Article(headline="Paul's story", pub_date=datetime(2006, 1, 17))
+ >>> new_article2 = Article(headline="Paul's story", pub_date=date(2006, 1, 17))
>>> r.article_set.add(new_article2)
>>> new_article2.reporter
<Reporter: John Smith>
diff --git a/docs/topics/db/multi-db.txt b/docs/topics/db/multi-db.txt
index 03a7d3b7cd..d2ff8645a9 100644
--- a/docs/topics/db/multi-db.txt
+++ b/docs/topics/db/multi-db.txt
@@ -201,73 +201,129 @@ An example
write to propagate to the slaves). It also doesn't consider the
interaction of transactions with the database utilization strategy.
-So - what does this mean in practice? Say you want ``myapp`` to
-exist on the ``other`` database, and you want all other models in a
-master/slave relationship between the databases ``master``, ``slave1`` and
-``slave2``. To implement this, you would need 2 routers::
+So - what does this mean in practice? Let's consider another sample
+configuration. This one will have several databases: one for the
+``auth`` application, and all other apps using a master/slave setup
+with two read slaves. Here are the settings specifying these
+databases::
- class MyAppRouter(object):
- """A router to control all database operations on models in
- the myapp application"""
+ DATABASES = {
+ 'auth_db': {
+ 'NAME': 'auth_db',
+ 'ENGINE': 'django.db.backends.mysql',
+ 'USER': 'mysql_user',
+ 'PASSWORD': 'swordfish',
+ },
+ 'master': {
+ 'NAME': 'master',
+ 'ENGINE': 'django.db.backends.mysql',
+ 'USER': 'mysql_user',
+ 'PASSWORD': 'spam',
+ },
+ 'slave1': {
+ 'NAME': 'slave1',
+ 'ENGINE': 'django.db.backends.mysql',
+ 'USER': 'mysql_user',
+ 'PASSWORD': 'eggs',
+ },
+ 'slave2': {
+ 'NAME': 'slave2',
+ 'ENGINE': 'django.db.backends.mysql',
+ 'USER': 'mysql_user',
+ 'PASSWORD': 'bacon',
+ },
+ }
+
+Now we'll need to handle routing. First we want a router that knows to
+send queries for the ``auth`` app to ``auth_db``::
+ class AuthRouter(object):
+ """
+ A router to control all database operations on models in the
+ auth application.
+ """
def db_for_read(self, model, **hints):
- "Point all operations on myapp models to 'other'"
- if model._meta.app_label == 'myapp':
- return 'other'
+ """
+ Attempts to read auth models go to auth_db.
+ """
+ if model._meta.app_label == 'auth':
+ return 'auth_db'
return None
def db_for_write(self, model, **hints):
- "Point all operations on myapp models to 'other'"
- if model._meta.app_label == 'myapp':
- return 'other'
+ """
+ Attempts to write auth models go to auth_db.
+ """
+ if model._meta.app_label == 'auth':
+ return 'auth_db'
return None
def allow_relation(self, obj1, obj2, **hints):
- "Allow any relation if a model in myapp is involved"
- if obj1._meta.app_label == 'myapp' or obj2._meta.app_label == 'myapp':
- return True
+ """
+ Allow relations if a model in the auth app is involved.
+ """
+ if obj1._meta.app_label == 'auth' or \
+ obj2._meta.app_label == 'auth':
+ return True
return None
def allow_syncdb(self, db, model):
- "Make sure the myapp app only appears on the 'other' db"
- if db == 'other':
- return model._meta.app_label == 'myapp'
- elif model._meta.app_label == 'myapp':
+ """
+ Make sure the auth app only appears in the 'auth_db'
+ database.
+ """
+ if db == 'auth_db':
+ return model._meta.app_label == 'auth'
+ elif model._meta.app_label == 'auth':
return False
return None
- class MasterSlaveRouter(object):
- """A router that sets up a simple master/slave configuration"""
+And we also want a router that sends all other apps to the
+master/slave configuration, and randomly chooses a slave to read
+from::
+ import random
+
+ class MasterSlaveRouter(object):
def db_for_read(self, model, **hints):
- "Point all read operations to a random slave"
- return random.choice(['slave1','slave2'])
+ """
+ Reads go to a randomly-chosen slave.
+ """
+ return random.choice(['slave1', 'slave2'])
def db_for_write(self, model, **hints):
- "Point all write operations to the master"
+ """
+ Writes always go to master.
+ """
return 'master'
def allow_relation(self, obj1, obj2, **hints):
- "Allow any relation between two objects in the db pool"
- db_list = ('master','slave1','slave2')
- if obj1._state.db in db_list and obj2._state.db in db_list:
+ """
+ Relations between objects are allowed if both objects are
+ in the master/slave pool.
+ """
+ db_list = ('master', 'slave1', 'slave2')
+ if obj1.state.db in db_list and obj2.state.db in db_list:
return True
return None
def allow_syncdb(self, db, model):
- "Explicitly put all models on all databases."
+ """
+ All non-auth models end up in this pool.
+ """
return True
-Then, in your settings file, add the following (substituting ``path.to.`` with
-the actual python path to the module where you define the routers)::
+Finally, in the settings file, we add the following (substituting
+``path.to.`` with the actual python path to the module(s) where the
+routers are defined)::
- DATABASE_ROUTERS = ['path.to.MyAppRouter', 'path.to.MasterSlaveRouter']
+ DATABASE_ROUTERS = ['path.to.AuthRouter', 'path.to.MasterSlaveRouter']
The order in which routers are processed is significant. Routers will
be queried in the order the are listed in the
:setting:`DATABASE_ROUTERS` setting . In this example, the
-``MyAppRouter`` is processed before the ``MasterSlaveRouter``, and as a
-result, decisions concerning the models in ``myapp`` are processed
+``AuthRouter`` is processed before the ``MasterSlaveRouter``, and as a
+result, decisions concerning the models in ``auth`` are processed
before any other decision is made. If the :setting:`DATABASE_ROUTERS`
setting listed the two routers in the other order,
``MasterSlaveRouter.allow_syncdb()`` would be processed first. The
@@ -276,11 +332,11 @@ that all models would be available on all databases.
With this setup installed, lets run some Django code::
- >>> # This retrieval will be performed on the 'credentials' database
+ >>> # This retrieval will be performed on the 'auth_db' database
>>> fred = User.objects.get(username='fred')
>>> fred.first_name = 'Frederick'
- >>> # This save will also be directed to 'credentials'
+ >>> # This save will also be directed to 'auth_db'
>>> fred.save()
>>> # These retrieval will be randomly allocated to a slave database
diff --git a/docs/topics/db/queries.txt b/docs/topics/db/queries.txt
index f87fa2920f..5385b2a72d 100644
--- a/docs/topics/db/queries.txt
+++ b/docs/topics/db/queries.txt
@@ -35,8 +35,8 @@ models, which comprise a Weblog application:
blog = models.ForeignKey(Blog)
headline = models.CharField(max_length=255)
body_text = models.TextField()
- pub_date = models.DateTimeField()
- mod_date = models.DateTimeField()
+ pub_date = models.DateField()
+ mod_date = models.DateField()
authors = models.ManyToManyField(Author)
n_comments = models.IntegerField()
n_pingbacks = models.IntegerField()
@@ -233,7 +233,7 @@ refinements together. For example::
>>> Entry.objects.filter(
... headline__startswith='What'
... ).exclude(
- ... pub_date__gte=datetime.now()
+ ... pub_date__gte=datetime.date.today()
... ).filter(
... pub_date__gte=datetime(2005, 1, 30)
... )
@@ -258,8 +258,8 @@ stored, used and reused.
Example::
>> q1 = Entry.objects.filter(headline__startswith="What")
- >> q2 = q1.exclude(pub_date__gte=datetime.now())
- >> q3 = q1.filter(pub_date__gte=datetime.now())
+ >> q2 = q1.exclude(pub_date__gte=datetime.date.today())
+ >> q3 = q1.filter(pub_date__gte=datetime.date.today())
These three ``QuerySets`` are separate. The first is a base
:class:`~django.db.models.query.QuerySet` containing all entries that contain a
@@ -282,7 +282,7 @@ actually run the query until the :class:`~django.db.models.query.QuerySet` is
*evaluated*. Take a look at this example::
>>> q = Entry.objects.filter(headline__startswith="What")
- >>> q = q.filter(pub_date__lte=datetime.now())
+ >>> q = q.filter(pub_date__lte=datetime.date.today())
>>> q = q.exclude(body_text__icontains="food")
>>> print(q)
@@ -968,11 +968,12 @@ Be aware that the ``update()`` method is converted directly to an SQL
statement. It is a bulk operation for direct updates. It doesn't run any
:meth:`~django.db.models.Model.save` methods on your models, or emit the
``pre_save`` or ``post_save`` signals (which are a consequence of calling
-:meth:`~django.db.models.Model.save`). If you want to save every item in a
-:class:`~django.db.models.query.QuerySet` and make sure that the
-:meth:`~django.db.models.Model.save` method is called on each instance, you
-don't need any special function to handle that. Just loop over them and call
-:meth:`~django.db.models.Model.save`::
+:meth:`~django.db.models.Model.save`), or honor the
+:attr:`~django.db.models.DateField.auto_now` field option.
+If you want to save every item in a :class:`~django.db.models.query.QuerySet`
+and make sure that the :meth:`~django.db.models.Model.save` method is called on
+each instance, you don't need any special function to handle that. Just loop
+over them and call :meth:`~django.db.models.Model.save`::
for item in my_queryset:
item.save()
diff --git a/docs/topics/forms/media.txt b/docs/topics/forms/media.txt
index 615dd7193c..29a7829799 100644
--- a/docs/topics/forms/media.txt
+++ b/docs/topics/forms/media.txt
@@ -38,6 +38,8 @@ in a form suitable for easy inclusion on your Web page.
whichever toolkit suits your requirements. Django is able to integrate
with any JavaScript toolkit.
+.. _media-as-a-static-definition:
+
Media as a static definition
----------------------------
@@ -78,10 +80,8 @@ A dictionary describing the CSS files required for various forms of output
media.
The values in the dictionary should be a tuple/list of file names. See
-`the section on media paths`_ for details of how to specify paths to media
-files.
-
-.. _the section on media paths: `Paths in media definitions`_
+:ref:`the section on media paths <form-media-paths>` for details of how to
+specify paths to media files.
The keys in the dictionary are the output media types. These are the same
types accepted by CSS files in media declarations: 'all', 'aural', 'braille',
@@ -117,8 +117,8 @@ If this last CSS definition were to be rendered, it would become the following H
``js``
~~~~~~
-A tuple describing the required JavaScript files. See
-`the section on media paths`_ for details of how to specify paths to media
+A tuple describing the required JavaScript files. See :ref:`the section on
+media paths <form-media-paths>` for details of how to specify paths to media
files.
``extend``
@@ -164,10 +164,10 @@ declaration to the media declaration::
<script type="text/javascript" src="http://static.example.com/whizbang.js"></script>
If you require even more control over media inheritance, define your media
-using a `dynamic property`_. Dynamic properties give you complete control over
-which media files are inherited, and which are not.
+using a :ref:`dynamic property <dynamic-property>`. Dynamic properties give
+you complete control over which media files are inherited, and which are not.
-.. _dynamic property: `Media as a dynamic property`_
+.. _dynamic-property:
Media as a dynamic property
---------------------------
@@ -198,9 +198,9 @@ Paths in media definitions
.. versionchanged:: 1.3
Paths used to specify media can be either relative or absolute. If a path
-starts with '/', 'http://' or 'https://', it will be interpreted as an absolute
-path, and left as-is. All other paths will be prepended with the value of
-the appropriate prefix.
+starts with ``/``, ``http://`` or ``https://``, it will be interpreted as an
+absolute path, and left as-is. All other paths will be prepended with the value
+of the appropriate prefix.
As part of the introduction of the
:doc:`staticfiles app </ref/contrib/staticfiles>` two new settings were added
diff --git a/docs/topics/forms/modelforms.txt b/docs/topics/forms/modelforms.txt
index 8159c8850c..caff03c581 100644
--- a/docs/topics/forms/modelforms.txt
+++ b/docs/topics/forms/modelforms.txt
@@ -311,18 +311,18 @@ model fields:
to exclude from the form.
For example, if you want a form for the ``Author`` model (defined
-above) that includes only the ``name`` and ``title`` fields, you would
+above) that includes only the ``name`` and ``birth_date`` fields, you would
specify ``fields`` or ``exclude`` like this::
class PartialAuthorForm(ModelForm):
class Meta:
model = Author
- fields = ('name', 'title')
+ fields = ('name', 'birth_date')
class PartialAuthorForm(ModelForm):
class Meta:
model = Author
- exclude = ('birth_date',)
+ exclude = ('title',)
Since the Author model has only 3 fields, 'name', 'title', and
'birth_date', the forms above will contain exactly the same fields.
diff --git a/docs/topics/http/urls.txt b/docs/topics/http/urls.txt
index 7297184ed3..4503bbd6ef 100644
--- a/docs/topics/http/urls.txt
+++ b/docs/topics/http/urls.txt
@@ -20,18 +20,18 @@ Overview
========
To design URLs for an app, you create a Python module informally called a
-**URLconf** (URL configuration). This module is pure Python code and
-is a simple mapping between URL patterns (as simple regular expressions) to
-Python callback functions (your views).
+**URLconf** (URL configuration). This module is pure Python code and is a
+simple mapping between URL patterns (simple regular expressions) to Python
+functions (your views).
This mapping can be as short or as long as needed. It can reference other
mappings. And, because it's pure Python code, it can be constructed
dynamically.
.. versionadded:: 1.4
- Django also allows to translate URLs according to the active language.
- This process is described in the
- :ref:`internationalization docs <url-internationalization>`.
+ Django also provides a way to translate URLs according to the active
+ language. See the :ref:`internationalization documentation
+ <url-internationalization>` for more information.
.. _how-django-processes-a-request:
@@ -154,11 +154,12 @@ The matching/grouping algorithm
Here's the algorithm the URLconf parser follows, with respect to named groups
vs. non-named groups in a regular expression:
-If there are any named arguments, it will use those, ignoring non-named arguments.
-Otherwise, it will pass all non-named arguments as positional arguments.
+1. If there are any named arguments, it will use those, ignoring non-named
+ arguments.
-In both cases, it will pass any extra keyword arguments as keyword arguments.
-See "Passing extra options to view functions" below.
+2. Otherwise, it will pass all non-named arguments as positional arguments.
+
+In both cases, any extra keyword arguments that have been given as per `Passing extra options to view functions`_ (below) will also be passed to the view.
What the URLconf searches against
=================================
@@ -176,6 +177,44 @@ The URLconf doesn't look at the request method. In other words, all request
methods -- ``POST``, ``GET``, ``HEAD``, etc. -- will be routed to the same
function for the same URL.
+Notes on capturing text in URLs
+===============================
+
+Each captured argument is sent to the view as a plain Python string, regardless
+of what sort of match the regular expression makes. For example, in this
+URLconf line::
+
+ (r'^articles/(?P<year>\d{4})/$', 'news.views.year_archive'),
+
+...the ``year`` argument to ``news.views.year_archive()`` will be a string, not
+an integer, even though the ``\d{4}`` will only match integer strings.
+
+A convenient trick is to specify default parameters for your views' arguments.
+Here's an example URLconf and view::
+
+ # URLconf
+ urlpatterns = patterns('',
+ (r'^blog/$', 'blog.views.page'),
+ (r'^blog/page(?P<num>\d+)/$', 'blog.views.page'),
+ )
+
+ # View (in blog/views.py)
+ def page(request, num="1"):
+ # Output the appropriate page of blog entries, according to num.
+
+In the above example, both URL patterns point to the same view --
+``blog.views.page`` -- but the first pattern doesn't capture anything from the
+URL. If the first pattern matches, the ``page()`` function will use its
+default argument for ``num``, ``"1"``. If the second pattern matches,
+``page()`` will use whatever ``num`` value was captured by the regex.
+
+Performance
+===========
+
+Each regular expression in a ``urlpatterns`` is compiled the first time it's
+accessed. This makes the system blazingly fast.
+
+
Syntax of the urlpatterns variable
==================================
@@ -209,10 +248,10 @@ The first argument to ``patterns()`` is a string ``prefix``. See
The remaining arguments should be tuples in this format::
- (regular expression, Python callback function [, optional dictionary [, optional name]])
+ (regular expression, Python callback function [, optional_dictionary [, optional_name]])
-...where ``optional dictionary`` and ``optional name`` are optional. (See
-`Passing extra options to view functions`_ below.)
+The ``optional_dictionary`` and ``optional_name`` parameters are described in
+`Passing extra options to view functions`_ below.
.. note::
Because `patterns()` is a function call, it accepts a maximum of 255
@@ -332,43 +371,6 @@ value should suffice.
See the documentation about :ref:`the 500 (HTTP Internal Server Error) view
<http_internal_server_error_view>` for more information.
-Notes on capturing text in URLs
-===============================
-
-Each captured argument is sent to the view as a plain Python string, regardless
-of what sort of match the regular expression makes. For example, in this
-URLconf line::
-
- (r'^articles/(?P<year>\d{4})/$', 'news.views.year_archive'),
-
-...the ``year`` argument to ``news.views.year_archive()`` will be a string, not
-an integer, even though the ``\d{4}`` will only match integer strings.
-
-A convenient trick is to specify default parameters for your views' arguments.
-Here's an example URLconf and view::
-
- # URLconf
- urlpatterns = patterns('',
- (r'^blog/$', 'blog.views.page'),
- (r'^blog/page(?P<num>\d+)/$', 'blog.views.page'),
- )
-
- # View (in blog/views.py)
- def page(request, num="1"):
- # Output the appropriate page of blog entries, according to num.
-
-In the above example, both URL patterns point to the same view --
-``blog.views.page`` -- but the first pattern doesn't capture anything from the
-URL. If the first pattern matches, the ``page()`` function will use its
-default argument for ``num``, ``"1"``. If the second pattern matches,
-``page()`` will use whatever ``num`` value was captured by the regex.
-
-Performance
-===========
-
-Each regular expression in a ``urlpatterns`` is compiled the first time it's
-accessed. This makes the system blazingly fast.
-
The view prefix
===============
diff --git a/docs/topics/i18n/translation.txt b/docs/topics/i18n/translation.txt
index 9bd53da2b9..a7f48fe1fd 100644
--- a/docs/topics/i18n/translation.txt
+++ b/docs/topics/i18n/translation.txt
@@ -1251,6 +1251,11 @@ As a convenience, Django comes with a view, :func:`django.views.i18n.set_languag
that sets a user's language preference and redirects to a given URL or, by default,
back to the previous page.
+Make sure that the following item is in your
+:setting:`TEMPLATE_CONTEXT_PROCESSORS` list in your settings file::
+
+ 'django.core.context_processors.i18n'
+
Activate this view by adding the following line to your URLconf::
(r'^i18n/', include('django.conf.urls.i18n')),
diff --git a/docs/topics/install.txt b/docs/topics/install.txt
index a11a44baa1..39b9a93c04 100644
--- a/docs/topics/install.txt
+++ b/docs/topics/install.txt
@@ -9,10 +9,8 @@ Install Python
Being a Python Web framework, Django requires Python.
-It works with any Python version from 2.6.5 to 2.7 (due to backwards
-incompatibilities in Python 3.0, Django does not currently work with
-Python 3.0; see :doc:`the Django FAQ </faq/install>` for more
-information on supported Python versions and the 3.0 transition).
+It works with any Python version from 2.6.5 to 2.7. It also features
+experimental support for versions 3.2 and 3.3.
Get Python at http://www.python.org. If you're running Linux or Mac OS X, you
probably already have it installed.
@@ -259,15 +257,14 @@ Installing the development version
If you decide to use the latest development version of Django,
you'll want to pay close attention to `the development timeline`_,
- and you'll want to keep an eye on `the list of
- backwards-incompatible changes`_. This will help you stay on top
- of any new features you might want to use, as well as any changes
+ and you'll want to keep an eye on the :ref:`release notes for the
+ upcoming release <development_release_notes>`. This will help you stay
+ on top of any new features you might want to use, as well as any changes
you'll need to make to your code when updating your copy of Django.
(For stable releases, any necessary changes are documented in the
release notes.)
.. _the development timeline: https://code.djangoproject.com/timeline
-.. _the list of backwards-incompatible changes: https://code.djangoproject.com/wiki/BackwardsIncompatibleChanges
If you'd like to be able to update your Django code occasionally with the
latest bug fixes and improvements, follow these instructions:
diff --git a/docs/topics/logging.txt b/docs/topics/logging.txt
index b54a9475ae..28baf87522 100644
--- a/docs/topics/logging.txt
+++ b/docs/topics/logging.txt
@@ -255,12 +255,12 @@ complex logging setup, configured using :meth:`logging.dictConfig`::
},
'handlers': {
'null': {
- 'level':'DEBUG',
- 'class':'django.utils.log.NullHandler',
+ 'level': 'DEBUG',
+ 'class': 'django.utils.log.NullHandler',
},
'console':{
- 'level':'DEBUG',
- 'class':'logging.StreamHandler',
+ 'level': 'DEBUG',
+ 'class': 'logging.StreamHandler',
'formatter': 'simple'
},
'mail_admins': {
@@ -271,9 +271,9 @@ complex logging setup, configured using :meth:`logging.dictConfig`::
},
'loggers': {
'django': {
- 'handlers':['null'],
+ 'handlers': ['null'],
'propagate': True,
- 'level':'INFO',
+ 'level': 'INFO',
},
'django.request': {
'handlers': ['mail_admins'],
diff --git a/docs/topics/python3.txt b/docs/topics/python3.txt
index d816db8046..f5749faaf2 100644
--- a/docs/topics/python3.txt
+++ b/docs/topics/python3.txt
@@ -324,8 +324,8 @@ Writing compatible code with six
six_ is the canonical compatibility library for supporting Python 2 and 3 in
a single codebase. Read its documentation!
-:mod`six` is bundled with Django as of version 1.4.2. You can import it as
-:mod`django.utils.six`.
+:mod:`six` is bundled with Django as of version 1.4.2. You can import it as
+:mod:`django.utils.six`.
Here are the most common changes required to write compatible code.
@@ -400,5 +400,12 @@ The version of six bundled with Django includes one extra function:
2 and :meth:`~django.utils.datastructures.MultiValueDict.lists()` on
Python 3.
+.. function:: assertRaisesRegex(testcase, *args, **kwargs)
+
+ This replaces ``testcase.assertRaisesRegexp`` on Python 2, and
+ ``testcase.assertRaisesRegex`` on Python 3. ``assertRaisesRegexp`` still
+ exists in current Python3 versions, but issues a warning.
+
+
In addition to six' defaults moves, Django's version provides ``thread`` as
``_thread`` and ``dummy_thread`` as ``_dummy_thread``.