summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorAndrew Godwin <andrew@aeracode.org>2013-08-09 14:17:30 +0100
committerAndrew Godwin <andrew@aeracode.org>2013-08-09 14:17:30 +0100
commitde64c4d6e97c980fb4c0ace045fc4070b3f763d9 (patch)
tree045c8af6a88fa964cf7e284970a6e93d53941a79 /docs
parentfddc5957c53bd654312c4a238a8cdcfe5f4ef4cc (diff)
parentb575d690bbc1c4cd7f575346132c09fca8c736a7 (diff)
Merge remote-tracking branch 'core/master' into schema-alteration
Conflicts: django/core/management/commands/flush.py django/core/management/commands/syncdb.py django/db/models/loading.py docs/internals/deprecation.txt docs/ref/django-admin.txt docs/releases/1.7.txt
Diffstat (limited to 'docs')
-rw-r--r--docs/Makefile10
-rw-r--r--docs/_ext/djangodocs.py6
-rw-r--r--docs/howto/custom-management-commands.txt6
-rw-r--r--docs/howto/deployment/checklist.txt15
-rw-r--r--docs/howto/deployment/fastcgi.txt3
-rw-r--r--docs/howto/deployment/index.txt8
-rw-r--r--docs/howto/error-reporting.txt8
-rw-r--r--docs/howto/initial-data.txt2
-rw-r--r--docs/index.txt2
-rw-r--r--docs/internals/contributing/writing-code/unit-tests.txt16
-rw-r--r--docs/internals/deprecation.txt14
-rw-r--r--docs/intro/tutorial02.txt6
-rw-r--r--docs/intro/tutorial03.txt45
-rw-r--r--docs/intro/tutorial05.txt2
-rw-r--r--docs/intro/whatsnext.txt5
-rw-r--r--docs/ref/class-based-views/base.txt2
-rw-r--r--docs/ref/class-based-views/mixins-date-based.txt2
-rw-r--r--docs/ref/class-based-views/mixins-multiple-object.txt8
-rw-r--r--docs/ref/class-based-views/mixins-single-object.txt8
-rw-r--r--docs/ref/contrib/admin/actions.txt2
-rw-r--r--docs/ref/contrib/admin/index.txt31
-rw-r--r--docs/ref/contrib/auth.txt14
-rw-r--r--docs/ref/contrib/comments/moderation.txt2
-rw-r--r--docs/ref/contrib/sitemaps.txt9
-rw-r--r--docs/ref/contrib/staticfiles.txt8
-rw-r--r--docs/ref/contrib/syndication.txt26
-rw-r--r--docs/ref/django-admin.txt26
-rw-r--r--docs/ref/exceptions.txt48
-rw-r--r--docs/ref/forms/api.txt15
-rw-r--r--docs/ref/forms/fields.txt41
-rw-r--r--docs/ref/forms/validation.txt16
-rw-r--r--docs/ref/forms/widgets.txt7
-rw-r--r--docs/ref/middleware.txt2
-rw-r--r--docs/ref/models/fields.txt22
-rw-r--r--docs/ref/models/instances.txt24
-rw-r--r--docs/ref/models/options.txt7
-rw-r--r--docs/ref/models/querysets.txt145
-rw-r--r--docs/ref/request-response.txt20
-rw-r--r--docs/ref/settings.txt4
-rw-r--r--docs/ref/templates/api.txt2
-rw-r--r--docs/ref/utils.txt62
-rw-r--r--docs/releases/1.2.1.txt2
-rw-r--r--docs/releases/1.3.txt4
-rw-r--r--docs/releases/1.5-beta-1.txt2
-rw-r--r--docs/releases/1.6.txt29
-rw-r--r--docs/releases/1.7.txt108
-rw-r--r--docs/topics/auth/default.txt143
-rw-r--r--docs/topics/cache.txt4
-rw-r--r--docs/topics/class-based-views/mixins.txt6
-rw-r--r--docs/topics/db/managers.txt123
-rw-r--r--docs/topics/db/queries.txt2
-rw-r--r--docs/topics/db/tablespaces.txt2
-rw-r--r--docs/topics/db/transactions.txt2
-rw-r--r--docs/topics/email.txt10
-rw-r--r--docs/topics/forms/formsets.txt34
-rw-r--r--docs/topics/forms/modelforms.txt11
-rw-r--r--docs/topics/http/middleware.txt3
-rw-r--r--docs/topics/http/sessions.txt2
-rw-r--r--docs/topics/http/urls.txt4
-rw-r--r--docs/topics/http/views.txt14
-rw-r--r--docs/topics/install.txt9
-rw-r--r--docs/topics/localflavor.txt78
-rw-r--r--docs/topics/templates.txt4
-rw-r--r--docs/topics/testing/advanced.txt2
-rw-r--r--docs/topics/testing/overview.txt6
65 files changed, 981 insertions, 324 deletions
diff --git a/docs/Makefile b/docs/Makefile
index a2c926c7ea..21b8a9cbe9 100644
--- a/docs/Makefile
+++ b/docs/Makefile
@@ -2,11 +2,11 @@
#
# You can set these variables from the command line.
-SPHINXOPTS =
-SPHINXBUILD = sphinx-build
-PAPER =
-BUILDDIR = _build
-LANGUAGE =
+SPHINXOPTS ?=
+SPHINXBUILD ?= sphinx-build
+PAPER ?=
+BUILDDIR ?= _build
+LANGUAGE ?=
# Internal variables.
PAPEROPT_a4 = -D latex_paper_size=a4
diff --git a/docs/_ext/djangodocs.py b/docs/_ext/djangodocs.py
index 833232a0c3..e7e316f58b 100644
--- a/docs/_ext/djangodocs.py
+++ b/docs/_ext/djangodocs.py
@@ -92,9 +92,15 @@ class DjangoHTMLTranslator(SmartyPantsHTMLTranslator):
# Don't use border=1, which docutils does by default.
def visit_table(self, node):
+ self.context.append(self.compact_p)
+ self.compact_p = True
self._table_row_index = 0 # Needed by Sphinx
self.body.append(self.starttag(node, 'table', CLASS='docutils'))
+ def depart_table(self, node):
+ self.compact_p = self.context.pop()
+ self.body.append('</table>\n')
+
# <big>? Really?
def visit_desc_parameterlist(self, node):
self.body.append('(')
diff --git a/docs/howto/custom-management-commands.txt b/docs/howto/custom-management-commands.txt
index 34e68d3700..2325e32ac2 100644
--- a/docs/howto/custom-management-commands.txt
+++ b/docs/howto/custom-management-commands.txt
@@ -193,7 +193,7 @@ Attributes
----------
All attributes can be set in your derived class and can be used in
-:class:`BaseCommand`'s :ref:`subclasses<ref-basecommand-subclasses>`.
+:class:`BaseCommand`’s :ref:`subclasses<ref-basecommand-subclasses>`.
.. attribute:: BaseCommand.args
@@ -245,7 +245,7 @@ All attributes can be set in your derived class and can be used in
Make sure you know what you are doing if you decide to change the value of
this option in your custom command if it creates database content that
is locale-sensitive and such content shouldn't contain any translations (like
- it happens e.g. with django.contrim.auth permissions) as making the locale
+ it happens e.g. with django.contrib.auth permissions) as making the locale
differ from the de facto default 'en-us' might cause unintended effects. See
the `Management commands and locales`_ section above for further details.
@@ -267,7 +267,7 @@ the :meth:`~BaseCommand.handle` method must be implemented.
.. admonition:: Implementing a constructor in a subclass
If you implement ``__init__`` in your subclass of :class:`BaseCommand`,
- you must call :class:`BaseCommand`'s ``__init__``.
+ you must call :class:`BaseCommand`’s ``__init__``.
.. code-block:: python
diff --git a/docs/howto/deployment/checklist.txt b/docs/howto/deployment/checklist.txt
index 7d382401a0..36c442fbe2 100644
--- a/docs/howto/deployment/checklist.txt
+++ b/docs/howto/deployment/checklist.txt
@@ -206,6 +206,21 @@ See :doc:`/howto/error-reporting` for details on error reporting by email.
.. _Sentry: http://sentry.readthedocs.org/en/latest/
+Customize the default error views
+---------------------------------
+
+Django includes default views and templates for several HTTP error codes. You
+may want to override the default templates by creating the following templates
+in your root template directory: ``404.html``, ``500.html``, ``403.html``, and
+``400.html``. The default views should suffice for 99% of Web applications, but
+if you desire to customize them, see these instructions which also contain
+details about the default templates:
+
+* :ref:`http_not_found_view`
+* :ref:`http_internal_server_error_view`
+* :ref:`http_forbidden_view`
+* :ref:`http_bad_request_view`
+
Miscellaneous
=============
diff --git a/docs/howto/deployment/fastcgi.txt b/docs/howto/deployment/fastcgi.txt
index 507e50d1a2..cc8d00966c 100644
--- a/docs/howto/deployment/fastcgi.txt
+++ b/docs/howto/deployment/fastcgi.txt
@@ -2,6 +2,9 @@
How to use Django with FastCGI, SCGI, or AJP
============================================
+.. deprecated:: 1.7
+ FastCGI support is deprecated and will be removed in Django 1.9.
+
.. highlight:: bash
Although :doc:`WSGI</howto/deployment/wsgi/index>` is the preferred deployment
diff --git a/docs/howto/deployment/index.txt b/docs/howto/deployment/index.txt
index ed4bcf3d4a..8b0368ac67 100644
--- a/docs/howto/deployment/index.txt
+++ b/docs/howto/deployment/index.txt
@@ -10,9 +10,15 @@ ways to easily deploy Django:
:maxdepth: 1
wsgi/index
- fastcgi
checklist
+FastCGI support is deprecated and will be removed in Django 1.9.
+
+.. toctree::
+ :maxdepth: 1
+
+ fastcgi
+
If you're new to deploying Django and/or Python, we'd recommend you try
:doc:`mod_wsgi </howto/deployment/wsgi/modwsgi>` first. In most cases it'll be
the easiest, fastest, and most stable deployment choice.
diff --git a/docs/howto/error-reporting.txt b/docs/howto/error-reporting.txt
index 987a503e95..5ebed92187 100644
--- a/docs/howto/error-reporting.txt
+++ b/docs/howto/error-reporting.txt
@@ -120,8 +120,8 @@ Filtering sensitive information
Error reports are really helpful for debugging errors, so it is generally
useful to record as much relevant information about those errors as possible.
For example, by default Django records the `full traceback`_ for the
-exception raised, each `traceback frame`_'s local variables, and the
-:class:`~django.http.HttpRequest`'s :ref:`attributes<httprequest-attributes>`.
+exception raised, each `traceback frame`_’s local variables, and the
+:class:`~django.http.HttpRequest`’s :ref:`attributes<httprequest-attributes>`.
However, sometimes certain types of information may be too sensitive and thus
may not be appropriate to be kept track of, for example a user's password or
@@ -164,7 +164,7 @@ production environment (that is, where :setting:`DEBUG` is set to ``False``):
.. admonition:: When using mutiple decorators
If the variable you want to hide is also a function argument (e.g.
- '``user``' in the following example), and if the decorated function has
+ '``user``’ in the following example), and if the decorated function has
mutiple decorators, then make sure to place ``@sensitive_variables`` at
the top of the decorator chain. This way it will also hide the function
argument as it gets passed through the other decorators::
@@ -232,7 +232,7 @@ own filter class and tell Django to use it via the
DEFAULT_EXCEPTION_REPORTER_FILTER = 'path.to.your.CustomExceptionReporterFilter'
You may also control in a more granular way which filter to use within any
-given view by setting the ``HttpRequest``'s ``exception_reporter_filter``
+given view by setting the ``HttpRequest``’s ``exception_reporter_filter``
attribute::
def my_view(request):
diff --git a/docs/howto/initial-data.txt b/docs/howto/initial-data.txt
index cea07bfea3..b86aaa834e 100644
--- a/docs/howto/initial-data.txt
+++ b/docs/howto/initial-data.txt
@@ -142,7 +142,7 @@ database tables already will have been created.
If you require data for a test case, you should add it using
either a :ref:`test fixture <topics-testing-fixtures>`, or
- programatically add it during the ``setUp()`` of your test case.
+ programmatically add it during the ``setUp()`` of your test case.
Database-backend-specific SQL data
----------------------------------
diff --git a/docs/index.txt b/docs/index.txt
index 19d574cb26..c58be5fcfc 100644
--- a/docs/index.txt
+++ b/docs/index.txt
@@ -193,7 +193,7 @@ testing of Django applications:
* **Deployment:**
:doc:`Overview <howto/deployment/index>` |
:doc:`WSGI servers <howto/deployment/wsgi/index>` |
- :doc:`FastCGI/SCGI/AJP <howto/deployment/fastcgi>` |
+ :doc:`FastCGI/SCGI/AJP <howto/deployment/fastcgi>` (deprecated) |
:doc:`Deploying static files <howto/static-files/deployment>` |
:doc:`Tracking code errors by email <howto/error-reporting>`
diff --git a/docs/internals/contributing/writing-code/unit-tests.txt b/docs/internals/contributing/writing-code/unit-tests.txt
index 7ee65cd6fa..b38c6f6783 100644
--- a/docs/internals/contributing/writing-code/unit-tests.txt
+++ b/docs/internals/contributing/writing-code/unit-tests.txt
@@ -25,16 +25,26 @@ Quickstart
~~~~~~~~~~
Running the tests requires a Django settings module that defines the
-databases to use. To make it easy to get started, Django provides a
-sample settings module that uses the SQLite database. To run the tests
-with this sample ``settings`` module:
+databases to use. To make it easy to get started, Django provides and uses a
+sample settings module that uses the SQLite database. To run the tests:
.. code-block:: bash
git clone git@github.com:django/django.git django-repo
cd django-repo/tests
+ ./runtests.py
+
+.. versionchanged:: 1.7
+
+Older versions of Django required running the tests like this::
+
PYTHONPATH=..:$PYTHONPATH python ./runtests.py --settings=test_sqlite
+``runtests.py`` now uses the Django package found at ``tests/../django`` (there
+isn't a need to add this on your ``PYTHONPATH``) and ``test_sqlite`` for the
+settings if settings aren't provided through either ``--settings`` or
+:envvar:`DJANGO_SETTINGS_MODULE`.
+
.. _running-unit-tests-settings:
Using another ``settings`` module
diff --git a/docs/internals/deprecation.txt b/docs/internals/deprecation.txt
index 25d54d5269..f0ac66bce8 100644
--- a/docs/internals/deprecation.txt
+++ b/docs/internals/deprecation.txt
@@ -412,6 +412,8 @@ these changes.
* ``django.utils.dictconfig`` will be removed.
+* ``django.utils.importlib`` will be removed.
+
* ``django.utils.unittest`` will be removed.
* The ``syncdb`` command will be removed.
@@ -425,6 +427,18 @@ these changes.
* ``allow_syncdb`` on database routers will no longer automatically become
``allow_migrate``.
+* If models are organized in a package, Django will no longer look for
+ :ref:`initial SQL data<initial-sql>` in ``myapp/models/sql/``. Move your
+ custom SQL files to ``myapp/sql/``.
+
+* FastCGI support via the ``runfcgi`` management command will be
+ removed. Please deploy your project using WSGI.
+
+* ``django.utils.datastructures.SortedDict`` will be removed. Use
+ :class:`collections.OrderedDict` from the Python standard library instead.
+
+* ``ModelAdmin.declared_fieldsets`` will be removed.
+
2.0
---
diff --git a/docs/intro/tutorial02.txt b/docs/intro/tutorial02.txt
index dd3e86d8ae..c5c5f8f288 100644
--- a/docs/intro/tutorial02.txt
+++ b/docs/intro/tutorial02.txt
@@ -352,12 +352,6 @@ representation of the output.
You can improve that by giving that method (in :file:`polls/models.py`) a few
attributes, as follows::
- import datetime
- from django.utils import timezone
- from django.db import models
-
- from polls.models import Poll
-
class Poll(models.Model):
# ...
def was_published_recently(self):
diff --git a/docs/intro/tutorial03.txt b/docs/intro/tutorial03.txt
index f0c39e2c93..1165fbf18a 100644
--- a/docs/intro/tutorial03.txt
+++ b/docs/intro/tutorial03.txt
@@ -454,51 +454,6 @@ just as :func:`~django.shortcuts.get_object_or_404` -- except using
:meth:`~django.db.models.query.QuerySet.get`. It raises
:exc:`~django.http.Http404` if the list is empty.
-Write a 404 (page not found) view
-=================================
-
-When you raise :exc:`~django.http.Http404` from within a view, Django
-will load a special view devoted to handling 404 errors. It finds it
-by looking for the variable ``handler404`` in your root URLconf (and
-only in your root URLconf; setting ``handler404`` anywhere else will
-have no effect), which is a string in Python dotted syntax -- the same
-format the normal URLconf callbacks use. A 404 view itself has nothing
-special: It's just a normal view.
-
-You normally won't have to bother with writing 404 views. If you don't set
-``handler404``, the built-in view :func:`django.views.defaults.page_not_found`
-is used by default. Optionally, you can create a ``404.html`` template
-in the root of your template directory. The default 404 view will then use that
-template for all 404 errors when :setting:`DEBUG` is set to ``False`` (in your
-settings module). If you do create the template, add at least some dummy
-content like "Page not found".
-
-.. warning::
-
- If :setting:`DEBUG` is set to ``False``, all responses will be
- "Bad Request (400)" unless you specify the proper :setting:`ALLOWED_HOSTS`
- as well (something like ``['localhost', '127.0.0.1']`` for
- local development).
-
-A couple more things to note about 404 views:
-
-* If :setting:`DEBUG` is set to ``True`` (in your settings module) then your
- 404 view will never be used (and thus the ``404.html`` template will never
- be rendered) because the traceback will be displayed instead.
-
-* The 404 view is also called if Django doesn't find a match after checking
- every regular expression in the URLconf.
-
-Write a 500 (server error) view
-===============================
-
-Similarly, your root URLconf may define a ``handler500``, which points
-to a view to call in case of server errors. Server errors happen when
-you have runtime errors in view code.
-
-Likewise, you should create a ``500.html`` template at the root of your
-template directory and add some content like "Something went wrong".
-
Use the template system
=======================
diff --git a/docs/intro/tutorial05.txt b/docs/intro/tutorial05.txt
index 39c3785f7c..63533d47ff 100644
--- a/docs/intro/tutorial05.txt
+++ b/docs/intro/tutorial05.txt
@@ -132,7 +132,7 @@ We identify a bug
Fortunately, there's a little bug in the ``polls`` application for us to fix
right away: the ``Poll.was_published_recently()`` method returns ``True`` if
the ``Poll`` was published within the last day (which is correct) but also if
-the ``Poll``'s ``pub_date`` field is in the future (which certainly isn't).
+the ``Poll``’s ``pub_date`` field is in the future (which certainly isn't).
You can see this in the Admin; create a poll whose date lies in the future;
you'll see that the ``Poll`` change list claims it was published recently.
diff --git a/docs/intro/whatsnext.txt b/docs/intro/whatsnext.txt
index a677bc9efd..638d219afe 100644
--- a/docs/intro/whatsnext.txt
+++ b/docs/intro/whatsnext.txt
@@ -66,6 +66,11 @@ different needs:
where you'll turn to find the details of a particular function or
whathaveyou.
+* If you are interested in deploying a project for public use, our docs have
+ :doc:`several guides</howto/deployment/index>` for various deployment
+ setups as well as a :doc:`deployment checklist</howto/deployment/checklist>`
+ for some things you'll need to think about.
+
* Finally, there's some "specialized" documentation not usually relevant to
most developers. This includes the :doc:`release notes </releases/index>` and
:doc:`internals documentation </internals/index>` for those who want to add
diff --git a/docs/ref/class-based-views/base.txt b/docs/ref/class-based-views/base.txt
index 4ad017c342..24058311a4 100644
--- a/docs/ref/class-based-views/base.txt
+++ b/docs/ref/class-based-views/base.txt
@@ -222,6 +222,8 @@ RedirectView
.. attribute:: pattern_name
+ .. versionadded:: 1.6
+
The name of the URL pattern to redirect to. Reversing will be done
using the same args and kwargs as are passed in for this view.
diff --git a/docs/ref/class-based-views/mixins-date-based.txt b/docs/ref/class-based-views/mixins-date-based.txt
index 1a1a4d531b..1162b2a194 100644
--- a/docs/ref/class-based-views/mixins-date-based.txt
+++ b/docs/ref/class-based-views/mixins-date-based.txt
@@ -225,7 +225,7 @@ DateMixin
.. attribute:: date_field
The name of the ``DateField`` or ``DateTimeField`` in the
- ``QuerySet``'s model that the date-based archive should use to
+ ``QuerySet``’s model that the date-based archive should use to
determine the list of objects to display on the page.
When :doc:`time zone support </topics/i18n/timezones>` is enabled and
diff --git a/docs/ref/class-based-views/mixins-multiple-object.txt b/docs/ref/class-based-views/mixins-multiple-object.txt
index b28bd11a71..67ca5429fa 100644
--- a/docs/ref/class-based-views/mixins-multiple-object.txt
+++ b/docs/ref/class-based-views/mixins-multiple-object.txt
@@ -63,6 +63,14 @@ MultipleObjectMixin
A ``QuerySet`` that represents the objects. If provided, the value of
``queryset`` supersedes the value provided for :attr:`model`.
+ .. warning::
+
+ ``queryset`` is a class attribute with a *mutable* value so care
+ must be taken when using it directly. Before using it, either call
+ its :meth:`~django.db.models.query.QuerySet.all` method or
+ retrieve it with :meth:`get_queryset` which takes care of the
+ cloning behind the scenes.
+
.. attribute:: paginate_by
An integer specifying how many objects should be displayed per page. If
diff --git a/docs/ref/class-based-views/mixins-single-object.txt b/docs/ref/class-based-views/mixins-single-object.txt
index bbe930d79e..1fce24acc5 100644
--- a/docs/ref/class-based-views/mixins-single-object.txt
+++ b/docs/ref/class-based-views/mixins-single-object.txt
@@ -23,6 +23,14 @@ SingleObjectMixin
A ``QuerySet`` that represents the objects. If provided, the value of
``queryset`` supersedes the value provided for :attr:`model`.
+ .. warning::
+
+ ``queryset`` is a class attribute with a *mutable* value so care
+ must be taken when using it directly. Before using it, either call
+ its :meth:`~django.db.models.query.QuerySet.all` method or
+ retrieve it with :meth:`get_queryset` which takes care of the
+ cloning behind the scenes.
+
.. attribute:: slug_field
The name of the field on the model that contains the slug. By default,
diff --git a/docs/ref/contrib/admin/actions.txt b/docs/ref/contrib/admin/actions.txt
index 65d096921f..58d8244525 100644
--- a/docs/ref/contrib/admin/actions.txt
+++ b/docs/ref/contrib/admin/actions.txt
@@ -271,7 +271,7 @@ Making actions available site-wide
This makes the `export_selected_objects` action globally available as an
action named `"export_selected_objects"`. You can explicitly give the action
- a name -- good if you later want to programatically :ref:`remove the action
+ a name -- good if you later want to programmatically :ref:`remove the action
<disabling-admin-actions>` -- by passing a second argument to
:meth:`AdminSite.add_action()`::
diff --git a/docs/ref/contrib/admin/index.txt b/docs/ref/contrib/admin/index.txt
index e5e9428805..8feb574efd 100644
--- a/docs/ref/contrib/admin/index.txt
+++ b/docs/ref/contrib/admin/index.txt
@@ -1218,6 +1218,14 @@ templates used by the :class:`ModelAdmin` views:
changelist that will be linked to the change view, as described in the
:attr:`ModelAdmin.list_display_links` section.
+.. method:: ModelAdmin.get_fields(self, request, obj=None)
+
+ .. versionadded:: 1.7
+
+ The ``get_fields`` method is given the ``HttpRequest`` and the ``obj``
+ being edited (or ``None`` on an add form) and is expected to return a list
+ of fields, as described above in the :attr:`ModelAdmin.fields` section.
+
.. method:: ModelAdmin.get_fieldsets(self, request, obj=None)
The ``get_fieldsets`` method is given the ``HttpRequest`` and the ``obj``
@@ -1233,6 +1241,14 @@ templates used by the :class:`ModelAdmin` views:
to return the same kind of sequence type as for the
:attr:`~ModelAdmin.list_filter` attribute.
+.. method:: ModelAdmin.get_search_fields(self, request)
+
+ .. versionadded:: 1.7
+
+ The ``get_search_fields`` method is given the ``HttpRequest`` and is expected
+ to return the same kind of sequence type as for the
+ :attr:`~ModelAdmin.search_fields` attribute.
+
.. method:: ModelAdmin.get_inline_instances(self, request, obj=None)
.. versionadded:: 1.5
@@ -1389,6 +1405,15 @@ templates used by the :class:`ModelAdmin` views:
kwargs['choices'] += (('ready', 'Ready for deployment'),)
return super(MyModelAdmin, self).formfield_for_choice_field(db_field, request, **kwargs)
+ .. admonition:: Note
+
+ Any ``choices`` attribute set on the formfield will limited to the form
+ field only. If the corresponding field on the model has choices set,
+ the choices provided to the form must be a valid subset of those
+ choices, otherwise the form submission will fail with
+ a :exc:`~django.core.exceptions.ValidationError` when the model itself
+ is validated before saving.
+
.. method:: ModelAdmin.get_changelist(self, request, **kwargs)
Returns the ``Changelist`` class to be used for listing. By default,
@@ -1590,7 +1615,7 @@ in your own admin JavaScript without including a second copy, you can use the
The embedded jQuery has been upgraded from 1.4.2 to 1.9.1.
The :class:`ModelAdmin` class requires jQuery by default, so there is no need
-to add jQuery to your ``ModelAdmin``'s list of media resources unless you have
+to add jQuery to your ``ModelAdmin``’s list of media resources unless you have
a specifc need. For example, if you require the jQuery library to be in the
global namespace (for example when using third-party jQuery plugins) or if you
need a newer version of jQuery, you will have to include your own copy.
@@ -2162,6 +2187,10 @@ Templates can override or extend base admin templates as described in
Path to a custom template that will be used by the admin site main index
view.
+.. attribute:: AdminSite.app_index_template
+
+ Path to a custom template that will be used by the admin site app index view.
+
.. attribute:: AdminSite.login_template
Path to a custom template that will be used by the admin site login view.
diff --git a/docs/ref/contrib/auth.txt b/docs/ref/contrib/auth.txt
index dfda8add4b..4fe87e9872 100644
--- a/docs/ref/contrib/auth.txt
+++ b/docs/ref/contrib/auth.txt
@@ -114,11 +114,13 @@ Methods
Always returns ``True`` (as opposed to
``AnonymousUser.is_authenticated()`` which always returns ``False``).
This is a way to tell if the user has been authenticated. This does not
- imply any permissions, and doesn't check if the user is active - it
- only indicates that ``request.user`` has been populated by the
- :class:`~django.contrib.auth.middleware.AuthenticationMiddleware` with
- a :class:`~django.contrib.auth.models.User` object representing the
- currently logged-in user.
+ imply any permissions, and doesn't check if the user is active or has
+ a valid session. Even though normally you will call this method on
+ ``request.user`` to find out whether it has been populated by the
+ :class:`~django.contrib.auth.middleware.AuthenticationMiddleware`
+ (representing the currently logged-in user), you should know this method
+ returns ``True`` for any :class:`~django.contrib.auth.models.User`
+ instance.
.. method:: get_full_name()
@@ -243,7 +245,7 @@ Manager methods
be called.
The ``extra_fields`` keyword arguments are passed through to the
- :class:`~django.contrib.auth.models.User`'s ``__init__`` method to
+ :class:`~django.contrib.auth.models.User`’s ``__init__`` method to
allow setting arbitrary fields on a :ref:`custom User model
<auth-custom-user>`.
diff --git a/docs/ref/contrib/comments/moderation.txt b/docs/ref/contrib/comments/moderation.txt
index 796e257200..5f0badfadb 100644
--- a/docs/ref/contrib/comments/moderation.txt
+++ b/docs/ref/contrib/comments/moderation.txt
@@ -54,7 +54,7 @@ following model, which would represent entries in a Weblog::
Now, suppose that we want the following steps to be applied whenever a
new comment is posted on an ``Entry``:
-1. If the ``Entry``'s ``enable_comments`` field is ``False``, the
+1. If the ``Entry``’s ``enable_comments`` field is ``False``, the
comment will simply be disallowed (i.e., immediately deleted).
2. If the ``enable_comments`` field is ``True``, the comment will be
diff --git a/docs/ref/contrib/sitemaps.txt b/docs/ref/contrib/sitemaps.txt
index 4467ed3a6e..7b53fc8c12 100644
--- a/docs/ref/contrib/sitemaps.txt
+++ b/docs/ref/contrib/sitemaps.txt
@@ -178,6 +178,15 @@ Sitemap class reference
representing the last-modified date/time for *every* object returned by
:attr:`~Sitemap.items()`.
+ .. versionadded:: 1.7
+
+ If all items in a sitemap have a :attr:`~Sitemap.lastmod`, the sitemap
+ generated by :func:`views.sitemap` will have a ``Last-Modified``
+ header equal to the latest ``lastmod``. You can activate the
+ :class:`~django.middleware.http.ConditionalGetMiddleware` to make
+ Django respond appropriately to requests with an ``If-Modified-Since``
+ header which will prevent sending the sitemap if it hasn't changed.
+
.. attribute:: Sitemap.changefreq
**Optional.** Either a method or attribute.
diff --git a/docs/ref/contrib/staticfiles.txt b/docs/ref/contrib/staticfiles.txt
index 806d135deb..f96c2e8a1b 100644
--- a/docs/ref/contrib/staticfiles.txt
+++ b/docs/ref/contrib/staticfiles.txt
@@ -226,7 +226,7 @@ CachedStaticFilesStorage
would be replaced by calling the
:meth:`~django.core.files.storage.Storage.url`
- method of the ``CachedStaticFilesStorage`` storage backend, ultimatively
+ method of the ``CachedStaticFilesStorage`` storage backend, ultimately
saving a ``'css/styles.55e7cbb9ba48.css'`` file with the following
content:
@@ -350,6 +350,12 @@ This view function serves static files in development.
**insecure**. This is only intended for local development, and should
**never be used in production**.
+.. versionchanged:: 1.7
+
+ This view will now raise an :exc:`~django.http.Http404` exception instead
+ of :exc:`~django.core.exceptions.ImproperlyConfigured` when
+ :setting:`DEBUG` is ``False``.
+
.. note::
To guess the served files' content types, this view relies on the
diff --git a/docs/ref/contrib/syndication.txt b/docs/ref/contrib/syndication.txt
index 9a0fb5830e..996950ef56 100644
--- a/docs/ref/contrib/syndication.txt
+++ b/docs/ref/contrib/syndication.txt
@@ -49,17 +49,17 @@ are views which can be used in your :doc:`URLconf </topics/http/urls>`.
A simple example
----------------
-This simple example, taken from `chicagocrime.org`_, describes a feed of the
-latest five news items::
+This simple example, taken from a hypothetical police beat news site describes
+a feed of the latest five news items::
from django.contrib.syndication.views import Feed
from django.core.urlresolvers import reverse
- from chicagocrime.models import NewsItem
+ from policebeat.models import NewsItem
class LatestEntriesFeed(Feed):
- title = "Chicagocrime.org site news"
+ title = "Police beat site news"
link = "/sitenews/"
- description = "Updates on changes and additions to chicagocrime.org."
+ description = "Updates on changes and additions to police beat central."
def items(self):
return NewsItem.objects.order_by('-pub_date')[:5]
@@ -199,22 +199,20 @@ into those elements.
are responsible for doing all necessary URL quoting and conversion to
ASCII inside the method itself.
-.. _chicagocrime.org: http://www.chicagocrime.org/
-
A complex example
-----------------
The framework also supports more complex feeds, via arguments.
-For example, `chicagocrime.org`_ offers an RSS feed of recent crimes for every
-police beat in Chicago. It'd be silly to create a separate
+For example, a website could offer an RSS feed of recent crimes for every
+police beat in a city. It'd be silly to create a separate
:class:`~django.contrib.syndication.views.Feed` class for each police beat; that
would violate the :ref:`DRY principle <dry>` and would couple data to
programming logic. Instead, the syndication framework lets you access the
arguments passed from your :doc:`URLconf </topics/http/urls>` so feeds can output
items based on information in the feed's URL.
-On chicagocrime.org, the police-beat feeds are accessible via URLs like this:
+The police beat feeds could be accessible via URLs like this:
* :file:`/beats/613/rss/` -- Returns recent crimes for beat 613.
* :file:`/beats/1424/rss/` -- Returns recent crimes for beat 1424.
@@ -238,7 +236,7 @@ Here's the code for these beat-specific feeds::
return get_object_or_404(Beat, pk=beat_id)
def title(self, obj):
- return "Chicagocrime.org: Crimes for beat %s" % obj.beat
+ return "Police beat central: Crimes for beat %s" % obj.beat
def link(self, obj):
return obj.get_absolute_url()
@@ -339,13 +337,13 @@ URLconf to add the extra versions.
Here's a full example::
from django.contrib.syndication.views import Feed
- from chicagocrime.models import NewsItem
+ from policebeat.models import NewsItem
from django.utils.feedgenerator import Atom1Feed
class RssSiteNewsFeed(Feed):
- title = "Chicagocrime.org site news"
+ title = "Police beat site news"
link = "/sitenews/"
- description = "Updates on changes and additions to chicagocrime.org."
+ description = "Updates on changes and additions to police beat central."
def items(self):
return NewsItem.objects.order_by('-pub_date')[:5]
diff --git a/docs/ref/django-admin.txt b/docs/ref/django-admin.txt
index 05fc8a1191..ab83e2cf33 100644
--- a/docs/ref/django-admin.txt
+++ b/docs/ref/django-admin.txt
@@ -233,7 +233,7 @@ probably be using this flag.
.. django-admin-option:: --pks
By default, ``dumpdata`` will output all the records of the model, but
-you can use the ``--pks`` option to specify a comma seperated list of
+you can use the ``--pks`` option to specify a comma separated list of
primary keys on which to filter. This is only available when dumping
one model.
@@ -251,8 +251,8 @@ prompts.
The :djadminopt:`--database` option may be used to specify the database
to flush.
---no-initial-data
-~~~~~~~~~~~~~~~~~
+``--no-initial-data``
+~~~~~~~~~~~~~~~~~~~~~
.. versionadded:: 1.5
@@ -558,7 +558,7 @@ several lines in language files.
.. django-admin-option:: --no-location
-Use the ``--no-location`` option to not write '``#: filename:line``'
+Use the ``--no-location`` option to not write '``#: filename:line``’
comment lines in language files. Note that using this option makes it harder
for technically skilled translators to understand each message's context.
@@ -617,6 +617,9 @@ runfcgi [options]
.. django-admin:: runfcgi
+.. deprecated:: 1.7
+ FastCGI support is deprecated and will be removed in Django 1.9.
+
Starts a set of FastCGI processes suitable for use with any Web server that
supports the FastCGI protocol. See the :doc:`FastCGI deployment documentation
</howto/deployment/fastcgi>` for details. Requires the Python FastCGI module from
@@ -780,7 +783,7 @@ You can provide an IPv6 address surrounded by brackets
A hostname containing ASCII-only characters can also be used.
If the :doc:`staticfiles</ref/contrib/staticfiles>` contrib app is enabled
-(default in new projects) the :djadmin:`runserver` command will be overriden
+(default in new projects) the :djadmin:`runserver` command will be overridden
with its own :ref:`runserver<staticfiles-runserver>` command.
.. django-admin-option:: --noreload
@@ -1432,6 +1435,19 @@ that ``django-admin.py`` should print to the console.
* ``2`` means verbose output.
* ``3`` means *very* verbose output.
+.. django-admin-option:: --no-color
+
+.. versionadded:: 1.7
+
+Example usage::
+
+ django-admin.py sqlall --no-color
+
+By default, ``django-admin.py`` will format the output to be colorized. For
+example, errors will be printed to the console in red and SQL statements will
+be syntax highlighted. To prevent this and have a plain text output, pass the
+``--no-color`` option when running your command.
+
Common options
==============
diff --git a/docs/ref/exceptions.txt b/docs/ref/exceptions.txt
index b15bbea8fa..bee8559ab0 100644
--- a/docs/ref/exceptions.txt
+++ b/docs/ref/exceptions.txt
@@ -6,24 +6,29 @@ Django Exceptions
Django raises some Django specific exceptions as well as many standard
Python exceptions.
-Django-specific Exceptions
-==========================
+Django Core Exceptions
+======================
.. module:: django.core.exceptions
- :synopsis: Django specific exceptions
+ :synopsis: Django core exceptions
+
+Django core exception classes are defined in :mod:`django.core.exceptions`.
ObjectDoesNotExist and DoesNotExist
-----------------------------------
.. exception:: DoesNotExist
-.. exception:: ObjectDoesNotExist
- The :exc:`DoesNotExist` exception is raised when an object is not found
- for the given parameters of a query.
+ The ``DoesNotExist`` exception is raised when an object is not found for
+ the given parameters of a query. Django provides a ``DoesNotExist``
+ exception as an attribute of each model class to identify the class of
+ object that could not be found and to allow you to catch a particular model
+ class with ``try/except``.
+
+.. exception:: ObjectDoesNotExist
- :exc:`ObjectDoesNotExist` is defined in :mod:`django.core.exceptions`.
- :exc:`DoesNotExist` is a subclass of the base :exc:`ObjectDoesNotExist`
- exception that is provided on every model class as a way of
- identifying the specific type of object that could not be found.
+ The base class for ``DoesNotExist`` exceptions; a ``try/except`` for
+ ``ObjectDoesNotExist`` will catch ``DoesNotExist`` exceptions for all
+ models.
See :meth:`~django.db.models.query.QuerySet.get()` for further information
on :exc:`ObjectDoesNotExist` and :exc:`DoesNotExist`.
@@ -121,6 +126,11 @@ ValidationError
.. currentmodule:: django.core.urlresolvers
+URL Resolver exceptions
+=======================
+
+URL Resolver exceptions are defined in :mod:`django.core.urlresolvers`.
+
NoReverseMatch
--------------
.. exception:: NoReverseMatch
@@ -134,9 +144,10 @@ NoReverseMatch
Database Exceptions
===================
+Database exceptions are provided in :mod:`django.db`.
+
Django wraps the standard database exceptions so that your Django code has a
-guaranteed common implementation of these classes. These database exceptions
-are provided in :mod:`django.db`.
+guaranteed common implementation of these classes.
.. exception:: Error
.. exception:: InterfaceError
@@ -160,34 +171,37 @@ to Python 3.)
.. versionchanged:: 1.6
- Previous version of Django only wrapped ``DatabaseError`` and
+ Previous versions of Django only wrapped ``DatabaseError`` and
``IntegrityError``, and did not provide ``__cause__``.
.. exception:: models.ProtectedError
Raised to prevent deletion of referenced objects when using
-:attr:`django.db.models.PROTECT`. Subclass of :exc:`IntegrityError`.
+:attr:`django.db.models.PROTECT`. :exc:`models.ProtectedError` is a subclass
+of :exc:`IntegrityError`.
.. currentmodule:: django.http
Http Exceptions
===============
+Http exceptions are provided in :mod:`django.http`.
+
.. exception:: UnreadablePostError
The :exc:`UnreadablePostError` is raised when a user cancels an upload.
- It is available from :mod:`django.http`.
.. currentmodule:: django.db.transaction
Transaction Exceptions
======================
+Transaction exceptions are defined in :mod:`django.db.transaction`.
+
.. exception:: TransactionManagementError
The :exc:`TransactionManagementError` is raised for any and all problems
- related to database transactions. It is available from
- :mod:`django.db.transaction`.
+ related to database transactions.
Python Exceptions
=================
diff --git a/docs/ref/forms/api.txt b/docs/ref/forms/api.txt
index 7c1601d3ea..780cb5d4f7 100644
--- a/docs/ref/forms/api.txt
+++ b/docs/ref/forms/api.txt
@@ -527,6 +527,11 @@ Note that the label suffix is added only if the last character of the
label isn't a punctuation character (in English, those are ``.``, ``!``, ``?``
or ``:``).
+.. versionadded:: 1.6
+
+You can also customize the ``label_suffix`` on a per-field basis using the
+``label_suffix`` parameter to :meth:`~django.forms.BoundField.label_tag`.
+
Notes on field ordering
~~~~~~~~~~~~~~~~~~~~~~~
@@ -653,7 +658,7 @@ when printed::
>>> str(f['subject'].errors)
''
-.. method:: BoundField.label_tag(contents=None, attrs=None)
+.. method:: BoundField.label_tag(contents=None, attrs=None, label_suffix=None)
To separately render the label tag of a form field, you can call its
``label_tag`` method::
@@ -671,6 +676,14 @@ additional attributes for the ``<label>`` tag.
The label now includes the form's :attr:`~django.forms.Form.label_suffix`
(a colon, by default).
+.. versionadded:: 1.6
+
+ The optional ``label_suffix`` parameter allows you to override the form's
+ :attr:`~django.forms.Form.label_suffix`. For example, you can use an empty
+ string to hide the label on selected fields. If you need to do this in a
+ template, you could write a custom filter to allow passing parameters to
+ ``label_tag``.
+
.. method:: BoundField.css_classes()
When you use Django's rendering shortcuts, CSS classes are used to
diff --git a/docs/ref/forms/fields.txt b/docs/ref/forms/fields.txt
index ef4ed729bd..e7c6612a72 100644
--- a/docs/ref/forms/fields.txt
+++ b/docs/ref/forms/fields.txt
@@ -877,7 +877,7 @@ Slightly complex built-in ``Field`` classes
* Normalizes to: the type returned by the ``compress`` method of the subclass.
* Validates that the given value against each of the fields specified
as an argument to the ``MultiValueField``.
- * Error message keys: ``required``, ``invalid``
+ * Error message keys: ``required``, ``invalid``, ``incomplete``
Aggregates the logic of multiple fields that together produce a single
value.
@@ -898,6 +898,45 @@ Slightly complex built-in ``Field`` classes
Once all fields are cleaned, the list of clean values is combined into
a single value by :meth:`~MultiValueField.compress`.
+ Also takes one extra optional argument:
+
+ .. attribute:: require_all_fields
+
+ .. versionadded:: 1.7
+
+ Defaults to ``True``, in which case a ``required`` validation error
+ will be raised if no value is supplied for any field.
+
+ When set to ``False``, the :attr:`Field.required` attribute can be set
+ to ``False`` for individual fields to make them optional. If no value
+ is supplied for a required field, an ``incomplete`` validation error
+ will be raised.
+
+ A default ``incomplete`` error message can be defined on the
+ :class:`MultiValueField` subclass, or different messages can be defined
+ on each individual field. For example::
+
+ from django.core.validators import RegexValidator
+
+ class PhoneField(MultiValueField):
+ def __init__(self, *args, **kwargs):
+ # Define one message for all fields.
+ error_messages = {
+ 'incomplete': 'Enter a country code and phone number.',
+ }
+ # Or define a different message for each field.
+ fields = (
+ CharField(error_messages={'incomplete': 'Enter a country code.'},
+ validators=[RegexValidator(r'^\d+$', 'Enter a valid country code.')]),
+ CharField(error_messages={'incomplete': 'Enter a phone number.'},
+ validators=[RegexValidator(r'^\d+$', 'Enter a valid phone number.')]),
+ CharField(validators=[RegexValidator(r'^\d+$', 'Enter a valid extension.')],
+ required=False),
+ )
+ super(PhoneField, self).__init__(
+ self, error_messages=error_messages, fields=fields,
+ require_all_fields=False, *args, **kwargs)
+
.. attribute:: MultiValueField.widget
Must be a subclass of :class:`django.forms.MultiWidget`.
diff --git a/docs/ref/forms/validation.txt b/docs/ref/forms/validation.txt
index 8ab1c26831..255b665c42 100644
--- a/docs/ref/forms/validation.txt
+++ b/docs/ref/forms/validation.txt
@@ -75,10 +75,8 @@ overridden:
any validation that requires access to multiple fields from the form at
once. This is where you might put in things to check that if field ``A``
is supplied, field ``B`` must contain a valid email address and the
- like. The data that this method returns is the final ``cleaned_data``
- attribute for the form, so don't forget to return the full list of
- cleaned data if you override this method (by default, ``Form.clean()``
- just returns ``self.cleaned_data``).
+ like. This method can return a completely different dictionary if it wishes,
+ which will be used as the ``cleaned_data``.
Note that any errors raised by your ``Form.clean()`` override will not
be associated with any field in particular. They go into a special
@@ -171,7 +169,7 @@ following guidelines:
Putting it all together::
- raise ValidationErrror(
+ raise ValidationError(
_('Invalid value: %(value)s'),
code='invalid',
params={'value': '42'},
@@ -365,6 +363,8 @@ write a cleaning method that operates on the ``recipients`` field, like so::
Cleaning and validating fields that depend on each other
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.. method:: django.forms.Form.clean
+
Suppose we add another requirement to our contact form: if the ``cc_myself``
field is ``True``, the ``subject`` must contain the word ``"help"``. We are
performing validation on more than one field at a time, so the form's
@@ -403,9 +403,6 @@ example::
raise forms.ValidationError("Did not send for 'help' in "
"the subject despite CC'ing yourself.")
- # Always return the full collection of cleaned data.
- return cleaned_data
-
In this code, if the validation error is raised, the form will display an
error message at the top of the form (normally) describing the problem.
@@ -443,9 +440,6 @@ sample) looks like this::
del cleaned_data["cc_myself"]
del cleaned_data["subject"]
- # Always return the full collection of cleaned data.
- return cleaned_data
-
As you can see, this approach requires a bit more effort, not withstanding the
extra design effort to create a sensible form display. The details are worth
noting, however. Firstly, earlier we mentioned that you might need to check if
diff --git a/docs/ref/forms/widgets.txt b/docs/ref/forms/widgets.txt
index 5b66776cfc..080d1fea86 100644
--- a/docs/ref/forms/widgets.txt
+++ b/docs/ref/forms/widgets.txt
@@ -52,8 +52,7 @@ widget on the field. In the following example, the
:attr:`~django.forms.extras.widgets.SelectDateWidget.years` attribute is set
for a :class:`~django.forms.extras.widgets.SelectDateWidget`::
- from django.forms.fields import DateField, ChoiceField, MultipleChoiceField
- from django.forms.widgets import RadioSelect, CheckboxSelectMultiple
+ from django import forms
from django.forms.extras.widgets import SelectDateWidget
BIRTH_YEAR_CHOICES = ('1980', '1981', '1982')
@@ -62,9 +61,9 @@ for a :class:`~django.forms.extras.widgets.SelectDateWidget`::
('black', 'Black'))
class SimpleForm(forms.Form):
- birth_year = DateField(widget=SelectDateWidget(years=BIRTH_YEAR_CHOICES))
+ birth_year = forms.DateField(widget=SelectDateWidget(years=BIRTH_YEAR_CHOICES))
favorite_colors = forms.MultipleChoiceField(required=False,
- widget=CheckboxSelectMultiple, choices=FAVORITE_COLORS_CHOICES)
+ widget=forms.CheckboxSelectMultiple, choices=FAVORITE_COLORS_CHOICES)
See the :ref:`built-in widgets` for more information about which widgets
are available and which arguments they accept.
diff --git a/docs/ref/middleware.txt b/docs/ref/middleware.txt
index 4898bab636..d011f054ac 100644
--- a/docs/ref/middleware.txt
+++ b/docs/ref/middleware.txt
@@ -37,7 +37,7 @@ defines. See the :doc:`cache documentation </topics/cache>`.
Adds a few conveniences for perfectionists:
* Forbids access to user agents in the :setting:`DISALLOWED_USER_AGENTS`
- setting, which should be a list of strings.
+ setting, which should be a list of compiled regular expression objects.
* Performs URL rewriting based on the :setting:`APPEND_SLASH` and
:setting:`PREPEND_WWW` settings.
diff --git a/docs/ref/models/fields.txt b/docs/ref/models/fields.txt
index 869996643f..01215884c4 100644
--- a/docs/ref/models/fields.txt
+++ b/docs/ref/models/fields.txt
@@ -152,11 +152,20 @@ method to retrieve the human-readable name for the field's current value. See
:meth:`~django.db.models.Model.get_FOO_display` in the database API
documentation.
-Finally, note that choices can be any iterable object -- not necessarily a list
-or tuple. This lets you construct choices dynamically. But if you find yourself
-hacking :attr:`~Field.choices` to be dynamic, you're probably better off using a
-proper database table with a :class:`ForeignKey`. :attr:`~Field.choices` is
-meant for static data that doesn't change much, if ever.
+Note that choices can be any iterable object -- not necessarily a list or tuple.
+This lets you construct choices dynamically. But if you find yourself hacking
+:attr:`~Field.choices` to be dynamic, you're probably better off using a proper
+database table with a :class:`ForeignKey`. :attr:`~Field.choices` is meant for
+static data that doesn't change much, if ever.
+
+.. versionadded:: 1.7
+
+Unless :attr:`blank=False<Field.blank>` is set on the field along with a
+:attr:`~Field.default` then a label containing ``"---------"`` will be rendered
+with the select box. To override this behavior, add a tuple to ``choices``
+containing ``None``; e.g. ``(None, 'Your String For Display')``.
+Alternatively, you can use an empty string instead of ``None`` where this makes
+sense - such as on a :class:`~django.db.models.CharField`.
``db_column``
-------------
@@ -874,6 +883,9 @@ are converted to lowercase.
``192.0.2.1``. Default is disabled. Can only be used
when ``protocol`` is set to ``'both'``.
+If you allow for blank values, you have to allow for null values since blank
+values are stored as null.
+
``NullBooleanField``
--------------------
diff --git a/docs/ref/models/instances.txt b/docs/ref/models/instances.txt
index f06866d9a1..cb8570afdc 100644
--- a/docs/ref/models/instances.txt
+++ b/docs/ref/models/instances.txt
@@ -118,7 +118,7 @@ validation for your own manually created models. For example::
article.full_clean()
except ValidationError as e:
# Do something based on the errors contained in e.message_dict.
- # Display them to a user, or handle them programatically.
+ # Display them to a user, or handle them programmatically.
pass
The first step ``full_clean()`` performs is to clean each individual field.
@@ -140,15 +140,19 @@ attributes on your model if desired. For instance, you could use it to
automatically provide a value for a field, or to do validation that requires
access to more than a single field::
- def clean(self):
- import datetime
- from django.core.exceptions import ValidationError
- # Don't allow draft entries to have a pub_date.
- if self.status == 'draft' and self.pub_date is not None:
- 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.date.today()
+ import datetime
+ from django.core.exceptions import ValidationError
+ from django.db import models
+
+ class Article(models.Model):
+ ...
+ def clean(self):
+ # Don't allow draft entries to have a pub_date.
+ if self.status == 'draft' and self.pub_date is not None:
+ 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.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/options.txt b/docs/ref/models/options.txt
index 6eeed51b6f..6415a9d2da 100644
--- a/docs/ref/models/options.txt
+++ b/docs/ref/models/options.txt
@@ -90,7 +90,7 @@ Django quotes column and table names behind the scenes.
The name of an orderable field in the model, typically a :class:`DateField`,
:class:`DateTimeField`, or :class:`IntegerField`. This specifies the default
- field to use in your model :class:`Manager`'s
+ field to use in your model :class:`Manager`’s
:meth:`~django.db.models.query.QuerySet.latest` and
:meth:`~django.db.models.query.QuerySet.earliest` methods.
@@ -227,9 +227,8 @@ Django quotes column and table names behind the scenes.
.. attribute:: Options.permissions
Extra permissions to enter into the permissions table when creating this object.
- Add, delete and change permissions are automatically created for each object
- that has ``admin`` set. This example specifies an extra permission,
- ``can_deliver_pizzas``::
+ Add, delete and change permissions are automatically created for each
+ model. This example specifies an extra permission, ``can_deliver_pizzas``::
permissions = (("can_deliver_pizzas", "Can deliver pizzas"),)
diff --git a/docs/ref/models/querysets.txt b/docs/ref/models/querysets.txt
index 3963785733..0f08022179 100644
--- a/docs/ref/models/querysets.txt
+++ b/docs/ref/models/querysets.txt
@@ -110,7 +110,7 @@ described here.
.. admonition:: You can't share pickles between versions
- Pickles of QuerySets are only valid for the version of Django that
+ Pickles of ``QuerySets`` are only valid for the version of Django that
was used to generate them. If you generate a pickle using Django
version N, there is no guarantee that pickle will be readable with
Django version N+1. Pickles should not be used as part of a long-term
@@ -121,9 +121,7 @@ described here.
QuerySet API
============
-Though you usually won't create one manually — you'll go through a
-:class:`~django.db.models.Manager` — here's the formal declaration of a
-``QuerySet``:
+Here's the formal declaration of a ``QuerySet``:
.. class:: QuerySet([model=None, query=None, using=None])
@@ -300,14 +298,30 @@ Be cautious when ordering by fields in related models if you are also using
:meth:`distinct()`. See the note in :meth:`distinct` for an explanation of how
related model ordering can change the expected results.
-It is permissible to specify a multi-valued field to order the results by (for
-example, a :class:`~django.db.models.ManyToManyField` field). Normally
-this won't be a sensible thing to do and it's really an advanced usage
-feature. However, if you know that your queryset's filtering or available data
-implies that there will only be one ordering piece of data for each of the main
-items you are selecting, the ordering may well be exactly what you want to do.
-Use ordering on multi-valued fields with care and make sure the results are
-what you expect.
+.. note::
+ It is permissible to specify a multi-valued field to order the results by
+ (for example, a :class:`~django.db.models.ManyToManyField` field, or the
+ reverse relation of a :class:`~django.db.models.ForeignKey` field).
+
+ Consider this case::
+
+ class Event(Model):
+ parent = models.ForeignKey('self', related_name='children')
+ date = models.DateField()
+
+ Event.objects.order_by('children__date')
+
+ Here, there could potentially be multiple ordering data for each ``Event``;
+ each ``Event`` with multiple ``children`` will be returned multiple times
+ into the new ``QuerySet`` that ``order_by()`` creates. In other words,
+ using ``order_by()`` on the ``QuerySet`` could return more items than you
+ were working on to begin with - which is probably neither expected nor
+ useful.
+
+ Thus, take care when using multi-valued field to order the results. **If**
+ you can be sure that there will only be one ordering piece of data for each
+ of the items you're ordering, this approach should not present problems. If
+ not, make sure the results are what you expect.
There's no way to specify whether ordering should be case sensitive. With
respect to case-sensitivity, Django will order results however your database
@@ -388,7 +402,7 @@ field names, the database will only compare the specified field names.
.. note::
When you specify field names, you *must* provide an ``order_by()`` in the
- QuerySet, and the fields in ``order_by()`` must start with the fields in
+ ``QuerySet``, and the fields in ``order_by()`` must start with the fields in
``distinct()``, in the same order.
For example, ``SELECT DISTINCT ON (a)`` gives you the first row for each
@@ -789,8 +803,8 @@ stop the deluge of database queries that is caused by accessing related objects,
but the strategy is quite different.
``select_related`` works by creating a SQL join and including the fields of the
-related object in the SELECT statement. For this reason, ``select_related`` gets
-the related objects in the same database query. However, to avoid the much
+related object in the ``SELECT`` statement. For this reason, ``select_related``
+gets the related objects in the same database query. However, to avoid the much
larger result set that would result from joining across a 'many' relationship,
``select_related`` is limited to single-valued relationships - foreign key and
one-to-one.
@@ -819,39 +833,54 @@ For example, suppose you have these models::
return u"%s (%s)" % (self.name, u", ".join([topping.name
for topping in self.toppings.all()]))
-and run this code::
+and run::
>>> Pizza.objects.all()
[u"Hawaiian (ham, pineapple)", u"Seafood (prawns, smoked salmon)"...
-The problem with this code is that it will run a query on the Toppings table for
-**every** item in the Pizza ``QuerySet``. Using ``prefetch_related``, this can
-be reduced to two:
+The problem with this is that every time ``Pizza.__unicode__()`` asks for
+``self.toppings.all()`` it has to query the database, so
+``Pizza.objects.all()`` will run a query on the Toppings table for **every**
+item in the Pizza ``QuerySet``.
+
+We can reduce to just two queries using ``prefetch_related``:
>>> Pizza.objects.all().prefetch_related('toppings')
-All the relevant toppings will be fetched in a single query, and used to make
-``QuerySets`` that have a pre-filled cache of the relevant results. These
-``QuerySets`` are then used in the ``self.toppings.all()`` calls.
+This implies a ``self.toppings.all()`` for each ``Pizza``; now each time
+``self.toppings.all()`` is called, instead of having to go to the database for
+the items, it will find them in a prefetched ``QuerySet`` cache that was
+populated in a single query.
-The additional queries are executed after the QuerySet has begun to be evaluated
-and the primary query has been executed. Note that the result cache of the
-primary QuerySet and all specified related objects will then be fully loaded
-into memory, which is often avoided in other cases - even after a query has been
-executed in the database, QuerySet normally tries to make uses of chunking
-between the database to avoid loading all objects into memory before you need
-them.
+That is, all the relevant toppings will have been fetched in a single query,
+and used to make ``QuerySets`` that have a pre-filled cache of the relevant
+results; these ``QuerySets`` are then used in the ``self.toppings.all()`` calls.
-Also remember that, as always with QuerySets, any subsequent chained methods
-which imply a different database query will ignore previously cached results,
-and retrieve data using a fresh database query. So, if you write the following:
+The additional queries in ``prefetch_related()`` are executed after the
+``QuerySet`` has begun to be evaluated and the primary query has been executed.
- >>> pizzas = Pizza.objects.prefetch_related('toppings')
- >>> [list(pizza.toppings.filter(spicy=True)) for pizza in pizzas]
+Note that the result cache of the primary ``QuerySet`` and all specified related
+objects will then be fully loaded into memory. This changes the typical
+behavior of ``QuerySets``, which normally try to avoid loading all objects into
+memory before they are needed, even after a query has been executed in the
+database.
-...then the fact that ``pizza.toppings.all()`` has been prefetched will not help
-you - in fact it hurts performance, since you have done a database query that
-you haven't used. So use this feature with caution!
+.. note::
+
+ Remember that, as always with ``QuerySets``, any subsequent chained methods
+ which imply a different database query will ignore previously cached
+ results, and retrieve data using a fresh database query. So, if you write
+ the following:
+
+ >>> pizzas = Pizza.objects.prefetch_related('toppings')
+ >>> [list(pizza.toppings.filter(spicy=True)) for pizza in pizzas]
+
+ ...then the fact that ``pizza.toppings.all()`` has been prefetched will not
+ help you. The ``prefetch_related('toppings')`` implied
+ ``pizza.toppings.all()``, but ``pizza.toppings.filter()`` is a new and
+ different query. The prefetched cache can't help here; in fact it hurts
+ performance, since you have done a database query that you haven't used. So
+ use this feature with caution!
You can also use the normal join syntax to do related fields of related
fields. Suppose we have an additional model to the example above::
@@ -904,7 +933,7 @@ additional queries on the ``ContentType`` table if the relevant rows have not
already been fetched.
``prefetch_related`` in most cases will be implemented using a SQL query that
-uses the 'IN' operator. This means that for a large QuerySet a large 'IN' clause
+uses the 'IN' operator. This means that for a large ``QuerySet`` a large 'IN' clause
could be generated, which, depending on the database, might have performance
problems of its own when it comes to parsing or executing the SQL query. Always
profile for your use case!
@@ -979,14 +1008,13 @@ of the arguments is required, but you should use at least one of them.
``select_params`` parameter. Since ``select_params`` is a sequence and
the ``select`` attribute is a dictionary, some care is required so that
the parameters are matched up correctly with the extra select pieces.
- In this situation, you should use a
- :class:`django.utils.datastructures.SortedDict` for the ``select``
- value, not just a normal Python dictionary.
+ In this situation, you should use a :class:`collections.OrderedDict` for
+ the ``select`` value, not just a normal Python dictionary.
This will work, for example::
Blog.objects.extra(
- select=SortedDict([('a', '%s'), ('b', '%s')]),
+ select=OrderedDict([('a', '%s'), ('b', '%s')]),
select_params=('one', 'two'))
The only thing to be careful about when using select parameters in
@@ -1264,6 +1292,28 @@ unexpectedly blocking.
Using ``select_for_update`` on backends which do not support
``SELECT ... FOR UPDATE`` (such as SQLite) will have no effect.
+raw
+~~~
+
+.. method:: raw(raw_query, params=None, translations=None)
+
+.. versionchanged:: 1.7
+
+ ``raw`` was moved to the ``QuerySet`` class. It was previously only on
+ :class:`~django.db.models.Manager`.
+
+Takes a raw SQL query, executes it, and returns a
+``django.db.models.query.RawQuerySet`` instance. This ``RawQuerySet`` instance
+can be iterated over just like an normal ``QuerySet`` to provide object instances.
+
+See the :ref:`executing-raw-queries` for more information.
+
+.. warning::
+
+ ``raw()`` always triggers a new query and doesn't account for previous
+ filtering. As such, it should generally be called from the ``Manager`` or
+ from a fresh ``QuerySet`` instance.
+
Methods that do not return QuerySets
------------------------------------
@@ -1866,6 +1916,17 @@ DO_NOTHING do not prevent taking the fast-path in deletion.
Note that the queries generated in object deletion is an implementation
detail subject to change.
+as_manager
+~~~~~~~~~~
+
+.. classmethod:: as_manager()
+
+.. versionadded:: 1.7
+
+Class method that returns an instance of :class:`~django.db.models.Manager`
+with a copy of the ``QuerySet``’s methods. See
+:ref:`create-manager-with-queryset-methods` for more details.
+
.. _field-lookups:
Field lookups
diff --git a/docs/ref/request-response.txt b/docs/ref/request-response.txt
index 060ec02e91..c57a1470d6 100644
--- a/docs/ref/request-response.txt
+++ b/docs/ref/request-response.txt
@@ -495,6 +495,26 @@ In addition, ``QueryDict`` has the following methods:
>>> q.lists()
[(u'a', [u'1', u'2', u'3'])]
+.. method:: QueryDict.pop(key)
+
+ Returns a list of values for the given key and removes them from the
+ dictionary. Raises ``KeyError`` if the key does not exist. For example::
+
+ >>> q = QueryDict('a=1&a=2&a=3', mutable=True)
+ >>> q.pop('a')
+ [u'1', u'2', u'3']
+
+.. method:: QueryDict.popitem()
+
+ Removes an arbitrary member of the dictionary (since there's no concept
+ of ordering), and returns a two value tuple containing the key and a list
+ of all values for the key. Raises ``KeyError`` when called on an empty
+ dictionary. For example::
+
+ >>> q = QueryDict('a=1&a=2&a=3', mutable=True)
+ >>> q.popitem()
+ (u'a', [u'1', u'2', u'3'])
+
.. method:: QueryDict.dict()
Returns ``dict`` representation of ``QueryDict``. For every (key, list)
diff --git a/docs/ref/settings.txt b/docs/ref/settings.txt
index c970311342..38d7275aed 100644
--- a/docs/ref/settings.txt
+++ b/docs/ref/settings.txt
@@ -1744,7 +1744,7 @@ Default::
A tuple of template loader classes, specified as strings. Each ``Loader`` class
knows how to import templates from a particular source. Optionally, a tuple can be
-used instead of a string. The first item in the tuple should be the ``Loader``'s
+used instead of a string. The first item in the tuple should be the ``Loader``’s
module, subsequent items are passed to the ``Loader`` during initialization. See
:doc:`/ref/templates/api`.
@@ -2478,7 +2478,7 @@ files</howto/static-files/index>` for more details about usage.
your static files from their permanent locations into one directory for
ease of deployment; it is **not** a place to store your static files
permanently. You should do that in directories that will be found by
- :doc:`staticfiles</ref/contrib/staticfiles>`'s
+ :doc:`staticfiles</ref/contrib/staticfiles>`’s
:setting:`finders<STATICFILES_FINDERS>`, which by default, are
``'static/'`` app sub-directories and any directories you include in
:setting:`STATICFILES_DIRS`).
diff --git a/docs/ref/templates/api.txt b/docs/ref/templates/api.txt
index f7dd0121d1..87822fe7f8 100644
--- a/docs/ref/templates/api.txt
+++ b/docs/ref/templates/api.txt
@@ -708,7 +708,7 @@ class. Here are the template loaders that come with Django:
with your own ``admin/base_site.html`` in ``myproject.polls``. You must
then make sure that your ``myproject.polls`` comes *before*
``django.contrib.admin`` in :setting:`INSTALLED_APPS`, otherwise
- ``django.contrib.admin``'s will be loaded first and yours will be ignored.
+ ``django.contrib.admin``’s will be loaded first and yours will be ignored.
Note that the loader performs an optimization when it is first imported:
it caches a list of which :setting:`INSTALLED_APPS` packages have a
diff --git a/docs/ref/utils.txt b/docs/ref/utils.txt
index 6b614e0c83..d31de35006 100644
--- a/docs/ref/utils.txt
+++ b/docs/ref/utils.txt
@@ -105,6 +105,10 @@ to distinguish caches by the ``Accept-language`` header.
.. class:: SortedDict
+.. deprecated:: 1.7
+ ``SortedDict`` is deprecated and will be removed in Django 1.9. Use
+ :class:`collections.OrderedDict` instead.
+
The :class:`django.utils.datastructures.SortedDict` class is a dictionary
that keeps its keys in the order in which they're inserted.
@@ -427,6 +431,64 @@ Atom1Feed
.. module:: django.utils.functional
:synopsis: Functional programming tools.
+.. class:: cached_property(object)
+
+ The ``@cached_property`` decorator caches the result of a method with a
+ single ``self`` argument as a property. The cached result will persist
+ as long as the instance does, so if the instance is passed around and the
+ function subsequently invoked, the cached result will be returned.
+
+ Consider a typical case, where a view might need to call a model's method
+ to perform some computation, before placing the model instance into the
+ context, where the template might invoke the method once more::
+
+ # the model
+ class Person(models.Model):
+
+ def friends(self):
+ # expensive computation
+ ...
+ return friends
+
+ # in the view:
+ if person.friends():
+
+ # in the template:
+ {% for friend in person.friends %}
+
+ Here, ``friends()`` will be called twice. Since the instance ``person`` in
+ the view and the template are the same, ``@cached_property`` can avoid
+ that::
+
+ from django.utils.functional import cached_property
+
+ @cached_property
+ def friends(self):
+ # expensive computation
+ ...
+ return friends
+
+ Note that as the method is now a property, in Python code it will need to
+ be invoked appropriately::
+
+ # in the view:
+ if person.friends:
+
+ The cached value can be treated like an ordinary attribute of the instance::
+
+ # clear it, requiring re-computation next time it's called
+ del person.friends # or delattr(person, "friends")
+
+ # set a value manually, that will persist on the instance until cleared
+ person.friends = ["Huckleberry Finn", "Tom Sawyer"]
+
+ As well as offering potential performance advantages, ``@cached_property``
+ can ensure that an attribute's value does not change unexpectedly over the
+ life of an instance. This could occur with a method whose computation is
+ based on ``datetime.now()``, or simply if a change were saved to the
+ database by some other process in the brief interval between subsequent
+ invocations of a method on the same instance.
+
.. function:: allow_lazy(func, *resultclasses)
Django offers many utility functions (particularly in ``django.utils``) that
diff --git a/docs/releases/1.2.1.txt b/docs/releases/1.2.1.txt
index bdac39dd5d..0e193bfe34 100644
--- a/docs/releases/1.2.1.txt
+++ b/docs/releases/1.2.1.txt
@@ -4,7 +4,7 @@ Django 1.2.1 release notes
Django 1.2.1 was released almost immediately after 1.2.0 to correct two small
bugs: one was in the documentation packaging script, the other was a bug_ that
-affected datetime form field widgets when localisation was enabled.
+affected datetime form field widgets when localization was enabled.
.. _bug: https://code.djangoproject.com/ticket/13560
diff --git a/docs/releases/1.3.txt b/docs/releases/1.3.txt
index 060f099c52..6bf4c0db60 100644
--- a/docs/releases/1.3.txt
+++ b/docs/releases/1.3.txt
@@ -365,7 +365,7 @@ In earlier Django versions, when a model instance containing a
file from the backend storage. This opened the door to several data-loss
scenarios, including rolled-back transactions and fields on different models
referencing the same file. In Django 1.3, when a model is deleted the
-:class:`~django.db.models.FileField`'s ``delete()`` method won't be called. If
+:class:`~django.db.models.FileField`’s ``delete()`` method won't be called. If
you need cleanup of orphaned files, you'll need to handle it yourself (for
instance, with a custom management command that can be run manually or
scheduled to run periodically via e.g. cron).
@@ -654,7 +654,7 @@ Password reset view now accepts ``from_email``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The :func:`django.contrib.auth.views.password_reset` view now accepts a
-``from_email`` parameter, which is passed to the ``password_reset_form``'s
+``from_email`` parameter, which is passed to the ``password_reset_form``’s
``save()`` method as a keyword argument. If you are using this view with a
custom password reset form, then you will need to ensure your form's ``save()``
method accepts this keyword argument.
diff --git a/docs/releases/1.5-beta-1.txt b/docs/releases/1.5-beta-1.txt
index 69c591ac03..4495a281af 100644
--- a/docs/releases/1.5-beta-1.txt
+++ b/docs/releases/1.5-beta-1.txt
@@ -7,7 +7,7 @@ November 27, 2012.
Welcome to Django 1.5 beta!
This is the second in a series of preview/development releases leading
-up to the eventual release of Django 1.5, scheduled for Decemeber
+up to the eventual release of Django 1.5, scheduled for December
2012. This release is primarily targeted at developers who are
interested in trying out new features and testing the Django codebase
to help identify and resolve bugs prior to the final 1.5 release.
diff --git a/docs/releases/1.6.txt b/docs/releases/1.6.txt
index b8babe1843..c0f5c51194 100644
--- a/docs/releases/1.6.txt
+++ b/docs/releases/1.6.txt
@@ -32,6 +32,16 @@ deprecation process for some features`_.
.. _`backwards incompatible changes`: `Backwards incompatible changes in 1.6`_
.. _`begun the deprecation process for some features`: `Features deprecated in 1.6`_
+Python compatibility
+====================
+
+Django 1.6, like Django 1.5, requires Python 2.6.5 or above. Python 3 is also
+officially supported. We **highly recommend** the latest minor release for each
+supported Python series (2.6.X, 2.7.X, 3.2.X, and 3.3.X).
+
+Django 1.6 will be the final release series to support Python 2.6; beginning
+with Django 1.7, the minimum supported Python version will be 2.7.
+
What's new in Django 1.6
========================
@@ -173,7 +183,7 @@ Minor features
* The :attr:`~django.views.generic.edit.DeletionMixin.success_url` of
:class:`~django.views.generic.edit.DeletionMixin` is now interpolated with
- its ``object``\'s ``__dict__``.
+ its ``object``’s ``__dict__``.
* :class:`~django.http.HttpResponseRedirect` and
:class:`~django.http.HttpResponsePermanentRedirect` now provide an ``url``
@@ -199,10 +209,6 @@ Minor features
* The admin list columns have a ``column-<field_name>`` class in the HTML
so the columns header can be styled with CSS, e.g. to set a column width.
-* Some admin templates now have ``app-<app_name>`` and ``model-<model_name>``
- classes in their ``<body>`` tag to allow customizing the CSS per app or per
- model.
-
* The :ref:`isolation level<database-isolation-level>` can be customized under
PostgreSQL.
@@ -324,7 +330,7 @@ Minor features
* :class:`~django.forms.ModelForm` fields can now override error messages
defined in model fields by using the
- :attr:`~django.forms.Field.error_messages` argument of a ``Field``'s
+ :attr:`~django.forms.Field.error_messages` argument of a ``Field``’s
constructor. To take advantage of this new feature with your custom fields,
:ref:`see the updated recommendation <raising-validation-error>` for raising
a ``ValidationError``.
@@ -654,7 +660,9 @@ will render something like:
<label for="id_my_field">My Field:</label> <input id="id_my_field" type="text" name="my_field" />
If you want to keep the current behavior of rendering ``label_tag`` without
-the ``label_suffix``, instantiate the form ``label_suffix=''``.
+the ``label_suffix``, instantiate the form ``label_suffix=''``. You can also
+customize the ``label_suffix`` on a per-field basis using the new
+``label_suffix`` parameter on :meth:`~django.forms.BoundField.label_tag`.
Admin views ``_changelist_filters`` GET parameter
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -801,6 +809,13 @@ Miscellaneous
of the admin views. You should update your custom templates if they use the
previous parameter name.
+* :meth:`~django.core.validators.validate_email` now accepts email addresses
+ with ``localhost`` as the domain.
+
+* The :djadminopt:`--keep-pot` option was added to :djadmin:`makemessages`
+ to prevent django from deleting the temporary .pot file it generates before
+ creating the .po file.
+
Features deprecated in 1.6
==========================
diff --git a/docs/releases/1.7.txt b/docs/releases/1.7.txt
index a617c90b34..23e4e3e64a 100644
--- a/docs/releases/1.7.txt
+++ b/docs/releases/1.7.txt
@@ -57,6 +57,13 @@ but a few of the key features are:
will still work, but that method name is deprecated and you should change
it as soon as possible (nothing more than renaming is required).
+Calling custom ``QuerySet`` methods from the ``Manager``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The :meth:`QuerySet.as_manager() <django.db.models.query.QuerySet.as_manager>`
+class method has been added to :ref:`create Manager with QuerySet methods
+<create-manager-with-queryset-methods>`.
+
Admin shortcuts support time zones
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -99,6 +106,58 @@ Minor features
allowing the ``published`` element to be included in the feed (which
relies on ``pubdate``).
+* Buttons in :mod:`django.contrib.admin` now use the ``border-radius`` CSS
+ property for rounded corners rather than GIF background images.
+
+* Some admin templates now have ``app-<app_name>`` and ``model-<model_name>``
+ classes in their ``<body>`` tag to allow customizing the CSS per app or per
+ model.
+
+* The admin changelist cells now have a ``field-<field_name>`` class in the
+ HTML to enable style customizations.
+
+* :func:`~django.core.mail.send_mail` now accepts an ``html_message``
+ parameter for sending a multipart ``text/plain`` and ``text/html`` email.
+
+* The :djadminopt:`--no-color` option for ``django-admin.py`` allows you to
+ disable the colorization of management command output.
+
+* The :mod:`sitemap framework<django.contrib.sitemaps>` now makes use of
+ :attr:`~django.contrib.sitemaps.Sitemap.lastmod` to set a ``Last-Modified``
+ header in the response. This makes it possible for the
+ :class:`~django.middleware.http.ConditionalGetMiddleware` to handle
+ conditional ``GET`` requests for sitemaps which set ``lastmod``.
+
+* You can override the new :meth:`AuthenticationForm.confirm_login_allowed()
+ <django.contrib.auth.forms.AuthenticationForm.confirm_login_allowed>` method
+ to more easily customize the login policy.
+
+* :attr:`Field.choices<django.db.models.Field.choices>` now allows you to
+ customize the "empty choice" label by including a tuple with an empty string
+ or ``None`` for the key and the custom label as the value. The default blank
+ option ``"----------"`` will be omitted in this case.
+
+* The admin's search fields can now be customized per-request thanks to the new
+ :meth:`django.contrib.admin.ModelAdmin.get_search_fields` method.
+
+* The :meth:`ModelAdmin.get_fields()
+ <django.contrib.admin.ModelAdmin.get_fields>` method may be overridden to
+ customize the value of :attr:`ModelAdmin.fields
+ <django.contrib.admin.ModelAdmin.fields>`.
+
+* :func:`django.contrib.auth.views.password_reset` takes an optional
+ ``html_email_template_name`` parameter used to send a multipart HTML email
+ for password resets.
+
+* :class:`~django.forms.MultiValueField` allows optional subfields by setting
+ the ``require_all_fields`` argument to ``False``. The ``required`` attribute
+ for each individual field will be respected, and a new ``incomplete``
+ validation error will be raised when any required fields are empty.
+
+* The :meth:`~django.forms.Form.clean` method on a form no longer needs to
+ return ``self.cleaned_data``. If it does return a changed dictionary then
+ that will still be used.
+
Backwards incompatible changes in 1.7
=====================================
@@ -130,14 +189,31 @@ Miscellaneous
have a custom :class:`~django.core.files.uploadhandler.FileUploadHandler`
that implements ``new_file()``, be sure it accepts this new parameter.
+* :class:`ModelFormSet<django.forms.models.BaseModelFormSet>`’s no longer
+ delete instances when ``save(commit=False)`` is called. See
+ :attr:`~django.forms.formsets.BaseFormSet.can_delete` for instructions on how
+ to manually delete objects from deleted forms.
+
+* Loading empty fixtures emits a ``RuntimeWarning`` rather than raising
+ :class:`~django.core.management.CommandError`.
+
+* :func:`django.contrib.staticfiles.views.serve` will now raise an
+ :exc:`~django.http.Http404` exception instead of
+ :exc:`~django.core.exceptions.ImproperlyConfigured` when :setting:`DEBUG`
+ is ``False``. This change removes the need to conditionally add the view to
+ your root URLconf, which in turn makes it safe to reverse by name. It also
+ removes the ability for visitors to generate spurious HTTP 500 errors by
+ requesting static files that don't exist or haven't been collected yet.
+
Features deprecated in 1.7
==========================
-``django.utils.dictconfig``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
+``django.utils.dictconfig``/``django.utils.importlib``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-``django.utils.dictconfig`` was a copy of :mod:`logging.config` provided for
-Python versions prior to 2.7. It has been deprecated.
+``django.utils.dictconfig`` and ``django.utils.importlib`` were copies of
+respectively :mod:`logging.config` and :mod:`importlib` provided for Python
+versions prior to 2.7. They have been deprecated.
``django.utils.unittest``
~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -147,3 +223,27 @@ on all Python versions. Since ``unittest2`` became the standard library's
:mod:`unittest` module in Python 2.7, and Django 1.7 drops support for older
Python versions, this module isn't useful anymore. It has been deprecated. Use
:mod:`unittest` instead.
+
+``django.utils.datastructures.SortedDict``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+As :class:`~collections.OrderedDict` was added to the standard library in
+Python 2.7, :class:`~django.utils.datastructures.SortedDict` is no longer
+needed and has been deprecated.
+
+Custom SQL location for models package
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Previously, if models were organized in a package (``myapp/models/``) rather
+than simply ``myapp/models.py``, Django would look for :ref:`initial SQL data
+<initial-sql>` in ``myapp/models/sql/``. This bug has been fixed so that Django
+will search ``myapp/sql/`` as documented. The old location will continue to
+work until Django 1.9.
+
+``declared_fieldsets`` attribute on ``ModelAdmin.``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+``ModelAdmin.declared_fieldsets`` was deprecated. Despite being a private API,
+it will go through a regular deprecation path. This attribute was mostly used
+by methods that bypassed ``ModelAdmin.get_fieldsets()`` but this was considered
+a bug and has been addressed.
diff --git a/docs/topics/auth/default.txt b/docs/topics/auth/default.txt
index cfa3ec3cad..902adc9e32 100644
--- a/docs/topics/auth/default.txt
+++ b/docs/topics/auth/default.txt
@@ -561,13 +561,33 @@ Most built-in authentication views provide a URL name for easier reference. See
patterns.
-.. function:: login(request, [template_name, redirect_field_name, authentication_form])
+.. function:: login(request, [template_name, redirect_field_name, authentication_form, current_app, extra_context])
**URL name:** ``login``
See :doc:`the URL documentation </topics/http/urls>` for details on using
named URL patterns.
+ **Optional arguments:**
+
+ * ``template_name``: The name of a template to display for the view used to
+ log the user in. Defaults to :file:`registration/login.html`.
+
+ * ``redirect_field_name``: The name of a ``GET`` field containing the
+ URL to redirect to after login. Overrides ``next`` if the given
+ ``GET`` parameter is passed.
+
+ * ``authentication_form``: A callable (typically just a form class) to
+ use for authentication. Defaults to
+ :class:`~django.contrib.auth.forms.AuthenticationForm`.
+
+ * ``current_app``: A hint indicating which application contains the current
+ view. See the :ref:`namespaced URL resolution strategy
+ <topics-http-reversing-url-namespaces>` for more information.
+
+ * ``extra_context``: A dictionary of context data that will be added to the
+ default context data passed to the template.
+
Here's what ``django.contrib.auth.views.login`` does:
* If called via ``GET``, it displays a login form that POSTs to the
@@ -657,7 +677,7 @@ patterns.
.. _site framework docs: ../sites/
-.. function:: logout(request, [next_page, template_name, redirect_field_name])
+.. function:: logout(request, [next_page, template_name, redirect_field_name, current_app, extra_context])
Logs a user out.
@@ -675,6 +695,13 @@ patterns.
URL to redirect to after log out. Overrides ``next_page`` if the given
``GET`` parameter is passed.
+ * ``current_app``: A hint indicating which application contains the current
+ view. See the :ref:`namespaced URL resolution strategy
+ <topics-http-reversing-url-namespaces>` for more information.
+
+ * ``extra_context``: A dictionary of context data that will be added to the
+ default context data passed to the template.
+
**Template context:**
* ``title``: The string "Logged out", localized.
@@ -691,7 +718,14 @@ patterns.
:attr:`request.META['SERVER_NAME'] <django.http.HttpRequest.META>`.
For more on sites, see :doc:`/ref/contrib/sites`.
-.. function:: logout_then_login(request[, login_url])
+ * ``current_app``: A hint indicating which application contains the current
+ view. See the :ref:`namespaced URL resolution strategy
+ <topics-http-reversing-url-namespaces>` for more information.
+
+ * ``extra_context``: A dictionary of context data that will be added to the
+ default context data passed to the template.
+
+.. function:: logout_then_login(request[, login_url, current_app, extra_context])
Logs a user out, then redirects to the login page.
@@ -702,7 +736,14 @@ patterns.
* ``login_url``: The URL of the login page to redirect to.
Defaults to :setting:`settings.LOGIN_URL <LOGIN_URL>` if not supplied.
-.. function:: password_change(request[, template_name, post_change_redirect, password_change_form])
+ * ``current_app``: A hint indicating which application contains the current
+ view. See the :ref:`namespaced URL resolution strategy
+ <topics-http-reversing-url-namespaces>` for more information.
+
+ * ``extra_context``: A dictionary of context data that will be added to the
+ default context data passed to the template.
+
+.. function:: password_change(request[, template_name, post_change_redirect, password_change_form, current_app, extra_context])
Allows a user to change their password.
@@ -722,11 +763,18 @@ patterns.
actually changing the user's password. Defaults to
:class:`~django.contrib.auth.forms.PasswordChangeForm`.
+ * ``current_app``: A hint indicating which application contains the current
+ view. See the :ref:`namespaced URL resolution strategy
+ <topics-http-reversing-url-namespaces>` for more information.
+
+ * ``extra_context``: A dictionary of context data that will be added to the
+ default context data passed to the template.
+
**Template context:**
* ``form``: The password change form (see ``password_change_form`` above).
-.. function:: password_change_done(request[, template_name])
+.. function:: password_change_done(request[, template_name, current_app, extra_context])
The page shown after a user has changed their password.
@@ -738,7 +786,14 @@ patterns.
Defaults to :file:`registration/password_change_done.html` if not
supplied.
-.. function:: password_reset(request[, is_admin_site, template_name, email_template_name, password_reset_form, token_generator, post_reset_redirect, from_email])
+ * ``current_app``: A hint indicating which application contains the current
+ view. See the :ref:`namespaced URL resolution strategy
+ <topics-http-reversing-url-namespaces>` for more information.
+
+ * ``extra_context``: A dictionary of context data that will be added to the
+ default context data passed to the template.
+
+.. function:: password_reset(request[, is_admin_site, template_name, email_template_name, password_reset_form, token_generator, post_reset_redirect, from_email, current_app, extra_context, html_email_template_name])
Allows a user to reset their password by generating a one-time use link
that can be used to reset the password, and sending that link to the
@@ -794,6 +849,21 @@ patterns.
* ``from_email``: A valid email address. By default Django uses
the :setting:`DEFAULT_FROM_EMAIL`.
+ * ``current_app``: A hint indicating which application contains the current
+ view. See the :ref:`namespaced URL resolution strategy
+ <topics-http-reversing-url-namespaces>` for more information.
+
+ * ``extra_context``: A dictionary of context data that will be added to the
+ default context data passed to the template.
+
+ * ``html_email_template_name``: The full name of a template to use
+ for generating a ``text/html`` multipart email with the password reset
+ link. By default, HTML email is not sent.
+
+ .. versionadded:: 1.7
+
+ ``html_email_template_name`` was added.
+
**Template context:**
* ``form``: The form (see ``password_reset_form`` above) for resetting
@@ -838,7 +908,7 @@ patterns.
single line plain text string.
-.. function:: password_reset_done(request[, template_name])
+.. function:: password_reset_done(request[, template_name, current_app, extra_context])
The page shown after a user has been emailed a link to reset their
password. This view is called by default if the :func:`password_reset` view
@@ -852,7 +922,14 @@ patterns.
Defaults to :file:`registration/password_reset_done.html` if not
supplied.
-.. function:: password_reset_confirm(request[, uidb64, token, template_name, token_generator, set_password_form, post_reset_redirect])
+ * ``current_app``: A hint indicating which application contains the current
+ view. See the :ref:`namespaced URL resolution strategy
+ <topics-http-reversing-url-namespaces>` for more information.
+
+ * ``extra_context``: A dictionary of context data that will be added to the
+ default context data passed to the template.
+
+.. function:: password_reset_confirm(request[, uidb64, token, template_name, token_generator, set_password_form, post_reset_redirect, current_app, extra_context])
Presents a form for entering a new password.
@@ -883,6 +960,13 @@ patterns.
* ``post_reset_redirect``: URL to redirect after the password reset
done. Defaults to ``None``.
+ * ``current_app``: A hint indicating which application contains the current
+ view. See the :ref:`namespaced URL resolution strategy
+ <topics-http-reversing-url-namespaces>` for more information.
+
+ * ``extra_context``: A dictionary of context data that will be added to the
+ default context data passed to the template.
+
**Template context:**
* ``form``: The form (see ``set_password_form`` above) for setting the
@@ -891,7 +975,7 @@ patterns.
* ``validlink``: Boolean, True if the link (combination of ``uidb64`` and
``token``) is valid or unused yet.
-.. function:: password_reset_complete(request[,template_name])
+.. function:: password_reset_complete(request[,template_name, current_app, extra_context])
Presents a view which informs the user that the password has been
successfully changed.
@@ -903,6 +987,13 @@ patterns.
* ``template_name``: The full name of a template to display the view.
Defaults to :file:`registration/password_reset_complete.html`.
+ * ``current_app``: A hint indicating which application contains the current
+ view. See the :ref:`namespaced URL resolution strategy
+ <topics-http-reversing-url-namespaces>` for more information.
+
+ * ``extra_context``: A dictionary of context data that will be added to the
+ default context data passed to the template.
+
Helper functions
----------------
@@ -959,6 +1050,40 @@ provides several built-in forms located in :mod:`django.contrib.auth.forms`:
Takes ``request`` as its first positional argument, which is stored on the
form instance for use by sub-classes.
+ .. method:: confirm_login_allowed(user)
+
+ .. versionadded:: 1.7
+
+ By default, ``AuthenticationForm`` rejects users whose ``is_active`` flag
+ is set to ``False``. You may override this behavior with a custom policy to
+ determine which users can log in. Do this with a custom form that subclasses
+ ``AuthenticationForm`` and overrides the ``confirm_login_allowed`` method.
+ This method should raise a :exc:`~django.core.exceptions.ValidationError`
+ if the given user may not log in.
+
+ For example, to allow all users to log in, regardless of "active" status::
+
+ from django.contrib.auth.forms import AuthenticationForm
+
+ class AuthenticationFormWithInactiveUsersOkay(AuthenticationForm):
+ def confirm_login_allowed(self, user):
+ pass
+
+ Or to allow only some active users to log in::
+
+ class PickyAuthenticationForm(AuthenticationForm):
+ def confirm_login_allowed(self, user):
+ if not user.is_active:
+ raise forms.ValidationError(
+ _("This account is inactive."),
+ code='inactive',
+ )
+ if user.username.startswith('b'):
+ raise forms.ValidationError(
+ _("Sorry, accounts starting with 'b' aren't welcome here."),
+ code='no_b_users',
+ )
+
.. class:: PasswordChangeForm
A form for allowing a user to change their password.
diff --git a/docs/topics/cache.txt b/docs/topics/cache.txt
index ea23943c81..092df1f876 100644
--- a/docs/topics/cache.txt
+++ b/docs/topics/cache.txt
@@ -39,6 +39,8 @@ Django also works well with "upstream" caches, such as `Squid
caches that you don't directly control but to which you can provide hints (via
HTTP headers) about which parts of your site should be cached, and how.
+.. _setting-up-the-cache:
+
Setting up the cache
====================
@@ -152,6 +154,8 @@ permanent storage -- they're all intended to be solutions for caching, not
storage -- but we point this out here because memory-based caching is
particularly temporary.
+.. _database-caching:
+
Database caching
----------------
diff --git a/docs/topics/class-based-views/mixins.txt b/docs/topics/class-based-views/mixins.txt
index df1a5505a5..fdd5d42c5d 100644
--- a/docs/topics/class-based-views/mixins.txt
+++ b/docs/topics/class-based-views/mixins.txt
@@ -170,7 +170,7 @@ being taken from the
:attr:`~django.views.generic.list.MultipleObjectTemplateResponseMixin.template_name_suffix`
attribute. (The date based generic views use suffixes such as ``_archive``,
``_archive_year`` and so on to use different templates for the various
-specialised date-based list views.)
+specialized date-based list views.)
Using Django's class-based view mixins
======================================
@@ -288,7 +288,7 @@ object. In order to do this, we need to have two different querysets:
``Book`` queryset for use by :class:`~django.views.generic.list.ListView`
Since we have access to the ``Publisher`` whose books we want to list, we
- simply override ``get_queryset()`` and use the ``Publisher``'s
+ simply override ``get_queryset()`` and use the ``Publisher``’s
:ref:`reverse foreign key manager<backwards-related-objects>`.
``Publisher`` queryset for use in :meth:`~django.views.generic.detail.SingleObjectMixin.get_object()`
@@ -345,7 +345,7 @@ The ``paginate_by`` is deliberately small in the example so you don't
have to create lots of books to see the pagination working! Here's the
template you'd want to use:
-.. code-block: html+django
+.. code-block:: html+django
{% extends "base.html" %}
diff --git a/docs/topics/db/managers.txt b/docs/topics/db/managers.txt
index b940b09d33..2d3f35db8b 100644
--- a/docs/topics/db/managers.txt
+++ b/docs/topics/db/managers.txt
@@ -100,7 +100,7 @@ access ``self.model`` to get the model class to which they're attached.
Modifying initial Manager QuerySets
-----------------------------------
-A ``Manager``'s base ``QuerySet`` returns all objects in the system. For
+A ``Manager``’s base ``QuerySet`` returns all objects in the system. For
example, using this model::
from django.db import models
@@ -111,7 +111,7 @@ example, using this model::
...the statement ``Book.objects.all()`` will return all books in the database.
-You can override a ``Manager``\'s base ``QuerySet`` by overriding the
+You can override a ``Manager``’s base ``QuerySet`` by overriding the
``Manager.get_queryset()`` method. ``get_queryset()`` should return a
``QuerySet`` with the properties you require.
@@ -201,6 +201,125 @@ attribute on the manager class. This is documented fully below_.
.. _below: manager-types_
+.. _calling-custom-queryset-methods-from-manager:
+
+Calling custom ``QuerySet`` methods from the ``Manager``
+--------------------------------------------------------
+
+While most methods from the standard ``QuerySet`` are accessible directly from
+the ``Manager``, this is only the case for the extra methods defined on a
+custom ``QuerySet`` if you also implement them on the ``Manager``::
+
+ class PersonQuerySet(models.QuerySet):
+ def male(self):
+ return self.filter(sex='M')
+
+ def female(self):
+ return self.filter(sex='F')
+
+ class PersonManager(models.Manager):
+ def get_queryset(self):
+ return PersonQuerySet()
+
+ def male(self):
+ return self.get_queryset().male()
+
+ def female(self):
+ return self.get_queryset().female()
+
+ class Person(models.Model):
+ first_name = models.CharField(max_length=50)
+ last_name = models.CharField(max_length=50)
+ sex = models.CharField(max_length=1, choices=(('M', 'Male'), ('F', 'Female')))
+ people = PersonManager()
+
+This example allows you to call both ``male()`` and ``female()`` directly from
+the manager ``Person.people``.
+
+.. _create-manager-with-queryset-methods:
+
+Creating ``Manager`` with ``QuerySet`` methods
+----------------------------------------------
+
+.. versionadded:: 1.7
+
+In lieu of the above approach which requires duplicating methods on both the
+``QuerySet`` and the ``Manager``, :meth:`QuerySet.as_manager()
+<django.db.models.query.QuerySet.as_manager>` can be used to create an instance
+of ``Manager`` with a copy of a custom ``QuerySet``’s methods::
+
+ class Person(models.Model):
+ ...
+ people = PersonQuerySet.as_manager()
+
+The ``Manager`` instance created by :meth:`QuerySet.as_manager()
+<django.db.models.query.QuerySet.as_manager>` will be virtually
+identical to the ``PersonManager`` from the previous example.
+
+Not every ``QuerySet`` method makes sense at the ``Manager`` level; for
+instance we intentionally prevent the :meth:`QuerySet.delete()
+<django.db.models.query.QuerySet.delete>` method from being copied onto
+the ``Manager`` class.
+
+Methods are copied according to the following rules:
+
+- Public methods are copied by default.
+- Private methods (starting with an underscore) are not copied by default.
+- Methods with a `queryset_only` attribute set to `False` are always copied.
+- Methods with a `queryset_only` attribute set to `True` are never copied.
+
+For example::
+
+ class CustomQuerySet(models.QuerySet):
+ # Available on both Manager and QuerySet.
+ def public_method(self):
+ return
+
+ # Available only on QuerySet.
+ def _private_method(self):
+ return
+
+ # Available only on QuerySet.
+ def opted_out_public_method(self):
+ return
+ opted_out_public_method.queryset_only = True
+
+ # Available on both Manager and QuerySet.
+ def _opted_in_private_method(self):
+ return
+ _opted_in_private_method.queryset_only = False
+
+from_queryset
+~~~~~~~~~~~~~
+
+.. classmethod:: from_queryset(queryset_class)
+
+For advance usage you might want both a custom ``Manager`` and a custom
+``QuerySet``. You can do that by calling ``Manager.from_queryset()`` which
+returns a *subclass* of your base ``Manager`` with a copy of the custom
+``QuerySet`` methods::
+
+ class BaseManager(models.Manager):
+ def __init__(self, *args, **kwargs):
+ ...
+
+ def manager_only_method(self):
+ return
+
+ class CustomQuerySet(models.QuerySet):
+ def manager_and_queryset_method(self):
+ return
+
+ class MyModel(models.Model):
+ objects = BaseManager.from_queryset(CustomQueryset)(*args, **kwargs)
+
+You may also store the generated class into a variable::
+
+ CustomManager = BaseManager.from_queryset(CustomQueryset)
+
+ class MyModel(models.Model):
+ objects = CustomManager(*args, **kwargs)
+
.. _custom-managers-and-inheritance:
Custom managers and model inheritance
diff --git a/docs/topics/db/queries.txt b/docs/topics/db/queries.txt
index 1d6052f938..9a0d0ce6b9 100644
--- a/docs/topics/db/queries.txt
+++ b/docs/topics/db/queries.txt
@@ -720,7 +720,7 @@ efficient code.
In a newly created :class:`~django.db.models.query.QuerySet`, the cache is
empty. The first time a :class:`~django.db.models.query.QuerySet` is evaluated
-- and, hence, a database query happens -- Django saves the query results in
-the :class:`~django.db.models.query.QuerySet`\'s cache and returns the results
+the :class:`~django.db.models.query.QuerySet`’s cache and returns the results
that have been explicitly requested (e.g., the next element, if the
:class:`~django.db.models.query.QuerySet` is being iterated over). Subsequent
evaluations of the :class:`~django.db.models.query.QuerySet` reuse the cached
diff --git a/docs/topics/db/tablespaces.txt b/docs/topics/db/tablespaces.txt
index 8bf1d07bca..115887f512 100644
--- a/docs/topics/db/tablespaces.txt
+++ b/docs/topics/db/tablespaces.txt
@@ -30,7 +30,7 @@ Declaring tablespaces for indexes
---------------------------------
You can pass the :attr:`~django.db.models.Field.db_tablespace` option to a
-``Field`` constructor to specify an alternate tablespace for the ``Field``'s
+``Field`` constructor to specify an alternate tablespace for the ``Field``’s
column index. If no index would be created for the column, the option is
ignored.
diff --git a/docs/topics/db/transactions.txt b/docs/topics/db/transactions.txt
index 903579cc38..4411b326d7 100644
--- a/docs/topics/db/transactions.txt
+++ b/docs/topics/db/transactions.txt
@@ -619,7 +619,7 @@ context managers breaks atomicity.
Managing autocommit
~~~~~~~~~~~~~~~~~~~
-Django 1.6 introduces an explicit :ref:`API for mananging autocommit
+Django 1.6 introduces an explicit :ref:`API for managing autocommit
<managing-autocommit>`.
To disable autocommit temporarily, instead of::
diff --git a/docs/topics/email.txt b/docs/topics/email.txt
index 8bf501c62a..c007c2b856 100644
--- a/docs/topics/email.txt
+++ b/docs/topics/email.txt
@@ -38,7 +38,7 @@ a secure connection is used.
send_mail()
===========
-.. function:: send_mail(subject, message, from_email, recipient_list, fail_silently=False, auth_user=None, auth_password=None, connection=None)
+.. function:: send_mail(subject, message, from_email, recipient_list, fail_silently=False, auth_user=None, auth_password=None, connection=None, html_message=None)
The simplest way to send email is using
``django.core.mail.send_mail()``.
@@ -66,6 +66,14 @@ are required.
If unspecified, an instance of the default backend will be used.
See the documentation on :ref:`Email backends <topic-email-backends>`
for more details.
+* ``html_message``: If ``html_message`` is provided, the resulting email will be a
+ :mimetype:`multipart/alternative` email with ``message`` as the
+ :mimetype:`text/plain` content type and ``html_message`` as the
+ :mimetype:`text/html` content type.
+
+.. versionadded:: 1.7
+
+ The ``html_message`` parameter was added.
send_mass_mail()
================
diff --git a/docs/topics/forms/formsets.txt b/docs/topics/forms/formsets.txt
index 470d9f52e4..8be6e10ff6 100644
--- a/docs/topics/forms/formsets.txt
+++ b/docs/topics/forms/formsets.txt
@@ -3,7 +3,10 @@
Formsets
========
-.. class:: django.forms.formsets.BaseFormSet
+.. module:: django.forms.formsets
+ :synopsis: An abstraction for working with multiple forms on the same page.
+
+.. class:: BaseFormSet
A formset is a layer of abstraction to work with multiple forms on the same
page. It can be best compared to a data grid. Let's say you have the following
@@ -164,9 +167,7 @@ As we can see, ``formset.errors`` is a list whose entries correspond to the
forms in the formset. Validation was performed for each of the two forms, and
the expected error message appears for the second item.
-.. currentmodule:: django.forms.formsets.BaseFormSet
-
-.. method:: total_error_count(self)
+.. method:: BaseFormSet.total_error_count(self)
.. versionadded:: 1.6
@@ -353,6 +354,8 @@ formsets and deletion of forms from a formset.
``can_order``
~~~~~~~~~~~~~
+.. attribute:: BaseFormSet.can_order
+
Default: ``False``
Lets you create a formset with the ability to order::
@@ -411,6 +414,8 @@ happen when the user changes these values::
``can_delete``
~~~~~~~~~~~~~~
+.. attribute:: BaseFormSet.can_delete
+
Default: ``False``
Lets you create a formset with the ability to select forms for deletion::
@@ -463,10 +468,23 @@ delete fields you can access them with ``deleted_forms``::
If you are using a :class:`ModelFormSet<django.forms.models.BaseModelFormSet>`,
model instances for deleted forms will be deleted when you call
-``formset.save()``. On the other hand, if you are using a plain ``FormSet``,
-it's up to you to handle ``formset.deleted_forms``, perhaps in your formset's
-``save()`` method, as there's no general notion of what it means to delete a
-form.
+``formset.save()``.
+
+.. versionchanged:: 1.7
+
+ If you call ``formset.save(commit=False)``, objects will not be deleted
+ automatically. You'll need to call ``delete()`` on each of the
+ :attr:`formset.deleted_objects
+ <django.forms.models.BaseModelFormSet.deleted_objects>` to actually delete
+ them::
+
+ >>> instances = formset.save(commit=False)
+ >>> for obj in formset.deleted_objects:
+ ... obj.delete()
+
+On the other hand, if you are using a plain ``FormSet``, it's up to you to
+handle ``formset.deleted_forms``, perhaps in your formset's ``save()`` method,
+as there's no general notion of what it means to delete a form.
Adding additional fields to a formset
-------------------------------------
diff --git a/docs/topics/forms/modelforms.txt b/docs/topics/forms/modelforms.txt
index 0f3c5bb815..a823c8acb5 100644
--- a/docs/topics/forms/modelforms.txt
+++ b/docs/topics/forms/modelforms.txt
@@ -392,7 +392,7 @@ these security concerns do not apply to you:
model = Author
fields = '__all__'
-2. Set the ``exclude`` attribute of the ``ModelForm``'s inner ``Meta`` class to
+2. Set the ``exclude`` attribute of the ``ModelForm``’s inner ``Meta`` class to
a list of fields to be excluded from the form.
For example::
@@ -757,7 +757,7 @@ Specifying widgets to use in the form with ``widgets``
.. versionadded:: 1.6
Using the ``widgets`` parameter, you can specify a dictionary of values to
-customize the ``ModelForm``'s widget class for a particular field. This
+customize the ``ModelForm``’s widget class for a particular field. This
works the same way as the ``widgets`` dictionary on the inner ``Meta``
class of a ``ModelForm`` works::
@@ -825,6 +825,13 @@ to the database. If your formset contains a ``ManyToManyField``, you'll also
need to call ``formset.save_m2m()`` to ensure the many-to-many relationships
are saved properly.
+After calling ``save()``, your model formset will have three new attributes
+containing the formset's changes:
+
+.. attribute:: models.BaseModelFormSet.changed_objects
+.. attribute:: models.BaseModelFormSet.deleted_objects
+.. attribute:: models.BaseModelFormSet.new_objects
+
.. _model-formsets-max-num:
Limiting the number of editable objects
diff --git a/docs/topics/http/middleware.txt b/docs/topics/http/middleware.txt
index 503d4322e0..6bb7ccb8f8 100644
--- a/docs/topics/http/middleware.txt
+++ b/docs/topics/http/middleware.txt
@@ -28,11 +28,12 @@ here's the default value created by :djadmin:`django-admin.py startproject
<startproject>`::
MIDDLEWARE_CLASSES = (
- 'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
+ 'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
+ 'django.middleware.clickjacking.XFrameOptionsMiddleware',
)
A Django installation doesn't require any middleware —
diff --git a/docs/topics/http/sessions.txt b/docs/topics/http/sessions.txt
index 0b818c4f5d..3ee7af9539 100644
--- a/docs/topics/http/sessions.txt
+++ b/docs/topics/http/sessions.txt
@@ -293,7 +293,7 @@ You can edit it multiple times.
expiration (or those set to expire at browser close), this will equal the
date :setting:`SESSION_COOKIE_AGE` seconds from now.
- This function accepts the same keyword argumets as :meth:`get_expiry_age`.
+ This function accepts the same keyword arguments as :meth:`get_expiry_age`.
.. method:: get_expire_at_browser_close
diff --git a/docs/topics/http/urls.txt b/docs/topics/http/urls.txt
index 8a3f240307..83610e99c0 100644
--- a/docs/topics/http/urls.txt
+++ b/docs/topics/http/urls.txt
@@ -412,7 +412,7 @@ For example::
)
In this example, for a request to ``/blog/2005/``, Django will call
-``blog.views.year_archive(year='2005', foo='bar')``.
+``blog.views.year_archive(request, year='2005', foo='bar')``.
This technique is used in the
:doc:`syndication framework </ref/contrib/syndication>` to pass metadata and
@@ -623,7 +623,7 @@ change the entry in the URLconf.
In some scenarios where views are of a generic nature, a many-to-one
relationship might exist between URLs and views. For these cases the view name
-isn't a good enough identificator for it when it comes the time of reversing
+isn't a good enough identifier for it when comes the time of reversing
URLs. Read the next section to know about the solution Django provides for this.
.. _naming-url-patterns:
diff --git a/docs/topics/http/views.txt b/docs/topics/http/views.txt
index 5c27c9c958..ebe5302ef8 100644
--- a/docs/topics/http/views.txt
+++ b/docs/topics/http/views.txt
@@ -140,18 +140,18 @@ The 404 (page not found) view
.. function:: django.views.defaults.page_not_found(request, template_name='404.html')
-When you raise an ``Http404`` exception, Django loads a special view devoted
-to handling 404 errors. By default, it's the view
-``django.views.defaults.page_not_found``, which either produces a very simple
-"Not Found" message or loads and renders the template ``404.html`` if you
-created it in your root template directory.
+When you raise :exc:`~django.http.Http404` from within a view, Django loads a
+special view devoted to handling 404 errors. By default, it's the view
+:func:`django.views.defaults.page_not_found`, which either produces a very
+simple "Not Found" message or loads and renders the template ``404.html`` if
+you created it in your root template directory.
The default 404 view will pass one variable to the template: ``request_path``,
which is the URL that resulted in the error.
The ``page_not_found`` view should suffice for 99% of Web applications, but if
-you want to override it, you can specify ``handler404`` in your URLconf, like
-so::
+you want to override it, you can specify ``handler404`` in your root URLconf
+(setting ``handler404`` anywhere else will have no effect), like so::
handler404 = 'mysite.views.my_custom_404_view'
diff --git a/docs/topics/install.txt b/docs/topics/install.txt
index 5d88ed4f82..3e813b2a41 100644
--- a/docs/topics/install.txt
+++ b/docs/topics/install.txt
@@ -59,11 +59,10 @@ installed.
If you can't use mod_wsgi for some reason, fear not: Django supports many other
deployment options. One is :doc:`uWSGI </howto/deployment/wsgi/uwsgi>`; it works
-very well with `nginx`_. Another is :doc:`FastCGI </howto/deployment/fastcgi>`,
-perfect for using Django with servers other than Apache. Additionally, Django
-follows the WSGI spec (:pep:`3333`), which allows it to run on a variety of
-server platforms. See the `server-arrangements wiki page`_ for specific
-installation instructions for each platform.
+very well with `nginx`_. Additionally, Django follows the WSGI spec
+(:pep:`3333`), which allows it to run on a variety of server platforms. See the
+`server-arrangements wiki page`_ for specific installation instructions for
+each platform.
.. _Apache: http://httpd.apache.org/
.. _nginx: http://nginx.org/
diff --git a/docs/topics/localflavor.txt b/docs/topics/localflavor.txt
index 8bc8b2f9e3..724805b147 100644
--- a/docs/topics/localflavor.txt
+++ b/docs/topics/localflavor.txt
@@ -7,8 +7,9 @@ assorted pieces of code that are useful for particular countries or cultures.
This code is now distributed separately from Django, for easier maintenance
and to trim the size of Django's codebase.
-The localflavor packages are named ``django-localflavor-*``, where the asterisk
-is an `ISO 3166 country code`_. For example: ``django-localflavor-us`` is the
+The new localflavor package is named ``django-localflavor``, with a main
+module called ``localflavor`` and many subpackages using an
+`ISO 3166 country code`_. For example: ``localflavor.us`` is the
localflavor package for the U.S.A.
Most of these ``localflavor`` add-ons are country-specific fields for the
@@ -22,7 +23,7 @@ For example, here's how you can create a form with a field representing a
French telephone number::
from django import forms
- from django_localflavor_fr.forms import FRPhoneNumberField
+ from localflavor.fr.forms import FRPhoneNumberField
class MyForm(forms.Form):
my_french_phone_no = FRPhoneNumberField()
@@ -37,75 +38,30 @@ file.
Supported countries
===================
-The following countries have django-localflavor- packages.
+See the official documentation for more information:
-* Argentina: https://github.com/django/django-localflavor-ar
-* Australia: https://github.com/django/django-localflavor-au
-* Austria: https://github.com/django/django-localflavor-at
-* Belgium: https://github.com/django/django-localflavor-be
-* Brazil: https://github.com/django/django-localflavor-br
-* Canada: https://github.com/django/django-localflavor-ca
-* Chile: https://github.com/django/django-localflavor-cl
-* China: https://github.com/django/django-localflavor-cn
-* Colombia: https://github.com/django/django-localflavor-co
-* Croatia: https://github.com/django/django-localflavor-hr
-* Czech Republic: https://github.com/django/django-localflavor-cz
-* Ecuador: https://github.com/django/django-localflavor-ec
-* Finland: https://github.com/django/django-localflavor-fi
-* France: https://github.com/django/django-localflavor-fr
-* Germany: https://github.com/django/django-localflavor-de
-* Greece: https://github.com/spapas/django-localflavor-gr
-* Hong Kong: https://github.com/django/django-localflavor-hk
-* Iceland: https://github.com/django/django-localflavor-is
-* India: https://github.com/django/django-localflavor-in
-* Indonesia: https://github.com/django/django-localflavor-id
-* Ireland: https://github.com/django/django-localflavor-ie
-* Israel: https://github.com/django/django-localflavor-il
-* Italy: https://github.com/django/django-localflavor-it
-* Japan: https://github.com/django/django-localflavor-jp
-* Kuwait: https://github.com/django/django-localflavor-kw
-* Lithuania: https://github.com/simukis/django-localflavor-lt
-* Macedonia: https://github.com/django/django-localflavor-mk
-* Mexico: https://github.com/django/django-localflavor-mx
-* The Netherlands: https://github.com/django/django-localflavor-nl
-* Norway: https://github.com/django/django-localflavor-no
-* Peru: https://github.com/django/django-localflavor-pe
-* Poland: https://github.com/django/django-localflavor-pl
-* Portugal: https://github.com/django/django-localflavor-pt
-* Paraguay: https://github.com/django/django-localflavor-py
-* Romania: https://github.com/django/django-localflavor-ro
-* Russia: https://github.com/django/django-localflavor-ru
-* Slovakia: https://github.com/django/django-localflavor-sk
-* Slovenia: https://github.com/django/django-localflavor-si
-* South Africa: https://github.com/django/django-localflavor-za
-* Spain: https://github.com/django/django-localflavor-es
-* Sweden: https://github.com/django/django-localflavor-se
-* Switzerland: https://github.com/django/django-localflavor-ch
-* Turkey: https://github.com/django/django-localflavor-tr
-* United Kingdom: https://github.com/django/django-localflavor-gb
-* United States of America: https://github.com/django/django-localflavor-us
-* Uruguay: https://github.com/django/django-localflavor-uy
+ https://django-localflavor.readthedocs.org/
Internationalization of localflavors
====================================
-To activate translations for a ``localflavor`` application, you must include
-the application's name (e.g. ``django_localflavor_jp``) in the
-:setting:`INSTALLED_APPS` setting, so the internationalization system can find
-the catalog, as explained in :ref:`how-django-discovers-translations`.
+To activate translations for the ``localflavor`` application, you must include
+the application's name in the :setting:`INSTALLED_APPS` setting, so the
+internationalization system can find the catalog, as explained in
+:ref:`how-django-discovers-translations`.
.. _localflavor-how-to-migrate:
How to migrate
==============
-If you've used the old ``django.contrib.localflavor`` package, follow these two
-easy steps to update your code:
+If you've used the old ``django.contrib.localflavor`` package or one of the
+temporary ``django-localflavor-*`` releases, follow these two easy steps to
+update your code:
-1. Install the appropriate third-party ``django-localflavor-*`` package(s).
- Go to https://github.com/django/ and find the package for your country.
+1. Install the third-party ``django-localflavor`` package from PyPI.
-2. Change your app's import statements to reference the new packages.
+2. Change your app's import statements to reference the new package.
For example, change this::
@@ -113,9 +69,9 @@ easy steps to update your code:
...to this::
- from django_localflavor_fr.forms import FRPhoneNumberField
+ from localflavor.fr.forms import FRPhoneNumberField
-The code in the new packages is the same (it was copied directly from Django),
+The code in the new package is the same (it was copied directly from Django),
so you don't have to worry about backwards compatibility in terms of
functionality. Only the imports have changed.
diff --git a/docs/topics/templates.txt b/docs/topics/templates.txt
index 58a3ee9870..c75b83f158 100644
--- a/docs/topics/templates.txt
+++ b/docs/topics/templates.txt
@@ -45,7 +45,9 @@ A template contains **variables**, which get replaced with values when the
template is evaluated, and **tags**, which control the logic of the template.
Below is a minimal template that illustrates a few basics. Each element will be
-explained later in this document.::
+explained later in this document.
+
+.. code-block:: html+django
{% extends "base_generic.html" %}
diff --git a/docs/topics/testing/advanced.txt b/docs/topics/testing/advanced.txt
index 6d9ea8d5c1..99af951866 100644
--- a/docs/topics/testing/advanced.txt
+++ b/docs/topics/testing/advanced.txt
@@ -174,7 +174,7 @@ Advanced features of ``TransactionTestCase``
.. warning::
This attribute is a private API. It may be changed or removed without
- a deprecation period in the future, for instance to accomodate changes
+ a deprecation period in the future, for instance to accommodate changes
in application loading.
It's used to optimize Django's own test suite, which contains hundreds
diff --git a/docs/topics/testing/overview.txt b/docs/topics/testing/overview.txt
index dbeaf0fb00..457d10eec0 100644
--- a/docs/topics/testing/overview.txt
+++ b/docs/topics/testing/overview.txt
@@ -1421,7 +1421,7 @@ The decorator can also be applied to test case classes::
You can also simulate the absence of a setting by deleting it after settings
-have been overriden, like this::
+have been overridden, like this::
@override_settings()
def test_something(self):
@@ -1437,7 +1437,7 @@ callbacks to clean up and otherwise reset state when settings are changed.
Django itself uses this signal to reset various data:
================================ ========================
-Overriden settings Data reset
+Overridden settings Data reset
================================ ========================
USE_TZ, TIME_ZONE Databases timezone
TEMPLATE_CONTEXT_PROCESSORS Context processors cache
@@ -1639,7 +1639,7 @@ your test suite.
.. versionadded:: 1.5
Asserts that the strings ``xml1`` and ``xml2`` are equal. The
- comparison is based on XML semantics. Similarily to
+ comparison is based on XML semantics. Similarly to
:meth:`~SimpleTestCase.assertHTMLEqual`, the comparison is
made on parsed content, hence only semantic differences are considered, not
syntax differences. When unvalid XML is passed in any parameter, an