[Python-modules-commits] [python-django] 01/08: Import python-django_1.9.5.orig.tar.gz

Raphaël Hertzog hertzog at moszumanska.debian.org
Mon Apr 4 14:51:36 UTC 2016


This is an automated email from the git hooks/post-receive script.

hertzog pushed a commit to branch debian/master
in repository python-django.

commit 2d44413e8c1748908cc49a72ffe13021ddff88cc
Author: Raphaël Hertzog <hertzog at debian.org>
Date:   Mon Apr 4 15:39:59 2016 +0200

    Import python-django_1.9.5.orig.tar.gz
---
 Django.egg-info/PKG-INFO                           |  2 +-
 Django.egg-info/SOURCES.txt                        |  2 +
 PKG-INFO                                           |  2 +-
 django/__init__.py                                 |  2 +-
 .../static/admin/js/admin/RelatedObjectLookups.js  |  8 ++++
 .../contrib/admin/templates/admin/change_form.html |  8 ----
 django/contrib/auth/forms.py                       |  9 +++-
 .../contrib/gis/db/backends/postgis/operations.py  |  2 +-
 .../gis/db/backends/spatialite/operations.py       |  2 +-
 django/contrib/gis/sitemaps/views.py               |  3 +-
 django/contrib/postgres/forms/jsonb.py             | 15 ++++++
 django/contrib/sitemaps/__init__.py                |  2 +-
 .../management/commands/collectstatic.py           | 14 ++++--
 django/core/cache/backends/base.py                 | 10 ++--
 django/core/management/base.py                     |  2 +-
 django/db/backends/sqlite3/schema.py               | 10 +++-
 django/db/migrations/autodetector.py               |  2 +-
 django/db/models/__init__.py                       |  4 +-
 django/db/models/base.py                           | 10 +++-
 django/db/models/fields/__init__.py                |  3 +-
 django/db/models/query.py                          |  6 +--
 django/db/models/sql/query.py                      |  2 +-
 django/http/multipartparser.py                     |  5 +-
 django/middleware/common.py                        | 21 ++++----
 django/template/backends/django.py                 | 17 +++++--
 django/template/loaders/cached.py                  | 27 +++++++++--
 docs/howto/deployment/wsgi/modwsgi.txt             |  7 ++-
 docs/howto/error-reporting.txt                     | 10 ++--
 .../contributing/writing-documentation.txt         |  6 +--
 docs/internals/howto-release-django.txt            |  2 +-
 docs/intro/reusable-apps.txt                       |  4 +-
 docs/intro/tutorial01.txt                          | 14 ++++++
 docs/intro/tutorial02.txt                          |  2 +-
 docs/intro/tutorial03.txt                          | 28 ++---------
 docs/intro/tutorial07.txt                          |  3 +-
 docs/ref/class-based-views/generic-date-based.txt  |  2 +-
 docs/ref/class-based-views/generic-editing.txt     |  2 +-
 docs/ref/class-based-views/mixins-simple.txt       |  2 +-
 docs/ref/contrib/gis/geoquerysets.txt              |  7 +--
 docs/ref/contrib/gis/install/index.txt             |  2 +-
 docs/ref/contrib/postgres/aggregates.txt           |  2 +-
 docs/ref/contrib/postgres/fields.txt               | 14 +++++-
 docs/ref/contrib/sitemaps.txt                      | 37 +++++++-------
 docs/ref/django-admin.txt                          |  9 +++-
 docs/ref/forms/api.txt                             |  5 ++
 docs/ref/forms/widgets.txt                         |  8 ++--
 docs/ref/models/fields.txt                         |  6 +++
 docs/ref/settings.txt                              |  4 +-
 docs/ref/utils.txt                                 |  2 +-
 docs/ref/views.txt                                 |  2 +-
 docs/releases/1.0.txt                              |  2 +-
 docs/releases/1.8.12.txt                           | 20 ++++++++
 docs/releases/1.9.5.txt                            | 51 ++++++++++++++++++++
 docs/releases/index.txt                            |  2 +
 docs/releases/security.txt                         |  2 +-
 docs/topics/auth/default.txt                       |  2 +-
 docs/topics/conditional-view-processing.txt        |  2 +-
 docs/topics/db/aggregation.txt                     |  2 +-
 docs/topics/db/optimization.txt                    |  2 +-
 docs/topics/pagination.txt                         |  7 ++-
 docs/topics/performance.txt                        |  2 +-
 docs/topics/serialization.txt                      |  3 +-
 docs/topics/templates.txt                          | 18 +++++--
 docs/topics/testing/advanced.txt                   |  2 +-
 tests/admin_views/admin.py                         |  8 ++++
 tests/admin_views/tests.py                         | 17 +++++++
 tests/aggregation/tests.py                         |  2 +-
 tests/aggregation_regress/tests.py                 |  2 +-
 tests/annotations/tests.py                         |  2 +-
 tests/auth_tests/test_forms.py                     | 56 ++++++++++++++++++++++
 tests/cache/tests.py                               | 11 ++++-
 tests/delete/tests.py                              |  4 +-
 tests/expressions/tests.py                         |  2 +-
 tests/expressions_case/tests.py                    |  2 +-
 tests/file_uploads/tests.py                        | 35 ++++++++++++++
 tests/fixtures/tests.py                            |  1 +
 tests/generic_relations_regress/tests.py           |  2 +-
 tests/gis_tests/geo3d/models.py                    |  2 -
 tests/gis_tests/geoadmin/models.py                 |  2 -
 tests/gis_tests/geoapp/models.py                   |  8 ----
 tests/gis_tests/inspectapp/models.py               |  4 --
 tests/gis_tests/layermap/models.py                 |  2 -
 tests/gis_tests/models.py                          |  1 -
 tests/gis_tests/relatedapp/models.py               |  3 --
 tests/gis_tests/relatedapp/tests.py                |  8 ++--
 tests/gis_tests/test_measure.py                    |  2 +-
 tests/middleware/tests.py                          |  7 +--
 tests/model_fields/test_durationfield.py           |  6 +++
 tests/model_inheritance/tests.py                   | 29 +++++++++--
 tests/postgres_tests/test_json.py                  | 21 ++++++++
 tests/queries/tests.py                             | 10 ++--
 tests/schema/models.py                             |  5 ++
 tests/schema/tests.py                              | 19 +++++++-
 tests/select_related_regress/tests.py              |  2 +-
 tests/signing/tests.py                             |  2 +-
 tests/staticfiles_tests/storage.py                 | 37 ++++++++++++++
 tests/staticfiles_tests/test_management.py         |  5 ++
 tests/template_tests/test_loaders.py               | 43 +++++++++++++++--
 tests/update/tests.py                              |  2 +-
 99 files changed, 642 insertions(+), 209 deletions(-)

diff --git a/Django.egg-info/PKG-INFO b/Django.egg-info/PKG-INFO
index 265a382..76b8e52 100644
--- a/Django.egg-info/PKG-INFO
+++ b/Django.egg-info/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: Django
-Version: 1.9.4
+Version: 1.9.5
 Summary: A high-level Python Web framework that encourages rapid development and clean, pragmatic design.
 Home-page: http://www.djangoproject.com/
 Author: Django Software Foundation
diff --git a/Django.egg-info/SOURCES.txt b/Django.egg-info/SOURCES.txt
index cedc787..f504ca8 100644
--- a/Django.egg-info/SOURCES.txt
+++ b/Django.egg-info/SOURCES.txt
@@ -3489,6 +3489,7 @@ docs/releases/1.7.txt
 docs/releases/1.8.1.txt
 docs/releases/1.8.10.txt
 docs/releases/1.8.11.txt
+docs/releases/1.8.12.txt
 docs/releases/1.8.2.txt
 docs/releases/1.8.3.txt
 docs/releases/1.8.4.txt
@@ -3502,6 +3503,7 @@ docs/releases/1.9.1.txt
 docs/releases/1.9.2.txt
 docs/releases/1.9.3.txt
 docs/releases/1.9.4.txt
+docs/releases/1.9.5.txt
 docs/releases/1.9.txt
 docs/releases/index.txt
 docs/releases/security.txt
diff --git a/PKG-INFO b/PKG-INFO
index 265a382..76b8e52 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
 Metadata-Version: 1.1
 Name: Django
-Version: 1.9.4
+Version: 1.9.5
 Summary: A high-level Python Web framework that encourages rapid development and clean, pragmatic design.
 Home-page: http://www.djangoproject.com/
 Author: Django Software Foundation
diff --git a/django/__init__.py b/django/__init__.py
index e0c468f..608c01d 100644
--- a/django/__init__.py
+++ b/django/__init__.py
@@ -1,6 +1,6 @@
 from django.utils.version import get_version
 
-VERSION = (1, 9, 4, 'final', 0)
+VERSION = (1, 9, 5, 'final', 0)
 
 __version__ = get_version(VERSION)
 
diff --git a/django/contrib/admin/static/admin/js/admin/RelatedObjectLookups.js b/django/contrib/admin/static/admin/js/admin/RelatedObjectLookups.js
index e661e0b..4ac9baa 100644
--- a/django/contrib/admin/static/admin/js/admin/RelatedObjectLookups.js
+++ b/django/contrib/admin/static/admin/js/admin/RelatedObjectLookups.js
@@ -176,6 +176,14 @@
             }
         });
         $('.related-widget-wrapper select').trigger('change');
+        $('.related-lookup').click(function(e) {
+            e.preventDefault();
+            var event = $.Event('django:lookup-related');
+            $(this).trigger(event);
+            if (!event.isDefaultPrevented()) {
+                showRelatedObjectLookupPopup(this);
+            }
+        });
     });
 
 })(django.jQuery);
diff --git a/django/contrib/admin/templates/admin/change_form.html b/django/contrib/admin/templates/admin/change_form.html
index 993f6df..22d49dc 100644
--- a/django/contrib/admin/templates/admin/change_form.html
+++ b/django/contrib/admin/templates/admin/change_form.html
@@ -79,14 +79,6 @@
                         showAddAnotherPopup(this);
                     }
                 });
-                $('.related-lookup').click(function(e) {
-                    e.preventDefault();
-                    var event = $.Event('django:lookup-related');
-                    $(this).trigger(event);
-                    if (!event.isDefaultPrevented()) {
-                        showRelatedObjectLookupPopup(this);
-                    }
-                });
 
             {% if adminform and add %}
                 $('form#{{ opts.model_name }}_form :input:visible:enabled:first').focus()
diff --git a/django/contrib/auth/forms.py b/django/contrib/auth/forms.py
index b1cedc9..380dc2b 100644
--- a/django/contrib/auth/forms.py
+++ b/django/contrib/auth/forms.py
@@ -69,9 +69,11 @@ class UserCreationForm(forms.ModelForm):
         'password_mismatch': _("The two password fields didn't match."),
     }
     password1 = forms.CharField(label=_("Password"),
+        strip=False,
         widget=forms.PasswordInput)
     password2 = forms.CharField(label=_("Password confirmation"),
         widget=forms.PasswordInput,
+        strip=False,
         help_text=_("Enter the same password as before, for verification."))
 
     class Meta:
@@ -127,7 +129,7 @@ class AuthenticationForm(forms.Form):
     username/password logins.
     """
     username = forms.CharField(max_length=254)
-    password = forms.CharField(label=_("Password"), widget=forms.PasswordInput)
+    password = forms.CharField(label=_("Password"), strip=False, widget=forms.PasswordInput)
 
     error_messages = {
         'invalid_login': _("Please enter a correct %(username)s and password. "
@@ -269,8 +271,10 @@ class SetPasswordForm(forms.Form):
     }
     new_password1 = forms.CharField(label=_("New password"),
                                     widget=forms.PasswordInput,
+                                    strip=False,
                                     help_text=password_validation.password_validators_help_text_html())
     new_password2 = forms.CharField(label=_("New password confirmation"),
+                                    strip=False,
                                     widget=forms.PasswordInput)
 
     def __init__(self, user, *args, **kwargs):
@@ -307,6 +311,7 @@ class PasswordChangeForm(SetPasswordForm):
                                 "Please enter it again."),
     })
     old_password = forms.CharField(label=_("Old password"),
+                                   strip=False,
                                    widget=forms.PasswordInput)
 
     field_order = ['old_password', 'new_password1', 'new_password2']
@@ -335,11 +340,13 @@ class AdminPasswordChangeForm(forms.Form):
     password1 = forms.CharField(
         label=_("Password"),
         widget=forms.PasswordInput,
+        strip=False,
         help_text=password_validation.password_validators_help_text_html(),
     )
     password2 = forms.CharField(
         label=_("Password (again)"),
         widget=forms.PasswordInput,
+        strip=False,
         help_text=_("Enter the same password as before, for verification."),
     )
 
diff --git a/django/contrib/gis/db/backends/postgis/operations.py b/django/contrib/gis/db/backends/postgis/operations.py
index d56b7be..318c88f 100644
--- a/django/contrib/gis/db/backends/postgis/operations.py
+++ b/django/contrib/gis/db/backends/postgis/operations.py
@@ -199,7 +199,7 @@ class PostGISOperations(BaseSpatialOperations, DatabaseOperations):
 
     def convert_geom(self, hex, geo_field):
         """
-        Converts the geometry returned from PostGIS aggretates.
+        Converts the geometry returned from PostGIS aggregates.
         """
         if hex:
             return Geometry(hex, srid=geo_field.srid)
diff --git a/django/contrib/gis/db/backends/spatialite/operations.py b/django/contrib/gis/db/backends/spatialite/operations.py
index 127ea7b..45e7a30 100644
--- a/django/contrib/gis/db/backends/spatialite/operations.py
+++ b/django/contrib/gis/db/backends/spatialite/operations.py
@@ -176,7 +176,7 @@ class SpatiaLiteOperations(BaseSpatialOperations, DatabaseOperations):
 
     def geo_db_type(self, f):
         """
-        Returns None because geometry columnas are added via the
+        Returns None because geometry columns are added via the
         `AddGeometryColumn` stored procedure on SpatiaLite.
         """
         return None
diff --git a/django/contrib/gis/sitemaps/views.py b/django/contrib/gis/sitemaps/views.py
index c5fd1aa..948c3ec 100644
--- a/django/contrib/gis/sitemaps/views.py
+++ b/django/contrib/gis/sitemaps/views.py
@@ -13,8 +13,7 @@ def kml(request, label, model, field_name=None, compress=False, using=DEFAULT_DB
     """
     This view generates KML for the given app label, model, and field name.
 
-    The model's default manager must be GeoManager, and the field name
-    must be that of a geographic field.
+    The field name must be that of a geographic field.
     """
     placemarks = []
     try:
diff --git a/django/contrib/postgres/forms/jsonb.py b/django/contrib/postgres/forms/jsonb.py
index 8eefc14..415288d 100644
--- a/django/contrib/postgres/forms/jsonb.py
+++ b/django/contrib/postgres/forms/jsonb.py
@@ -1,11 +1,16 @@
 import json
 
 from django import forms
+from django.utils import six
 from django.utils.translation import ugettext_lazy as _
 
 __all__ = ['JSONField']
 
 
+class InvalidJSONInput(six.text_type):
+    pass
+
+
 class JSONField(forms.CharField):
     default_error_messages = {
         'invalid': _("'%(value)s' value must be valid JSON."),
@@ -27,5 +32,15 @@ class JSONField(forms.CharField):
                 params={'value': value},
             )
 
+    def bound_data(self, data, initial):
+        if self.disabled:
+            return initial
+        try:
+            return json.loads(data)
+        except ValueError:
+            return InvalidJSONInput(data)
+
     def prepare_value(self, value):
+        if isinstance(value, InvalidJSONInput):
+            return value
         return json.dumps(value)
diff --git a/django/contrib/sitemaps/__init__.py b/django/contrib/sitemaps/__init__.py
index 1b626cd..891890e 100644
--- a/django/contrib/sitemaps/__init__.py
+++ b/django/contrib/sitemaps/__init__.py
@@ -45,7 +45,7 @@ def ping_google(sitemap_url=None, ping_url=PING_URL):
 
 class Sitemap(object):
     # This limit is defined by Google. See the index documentation at
-    # http://sitemaps.org/protocol.php#index.
+    # http://www.sitemaps.org/protocol.html#index.
     limit = 50000
 
     # If protocol is None, the URLs in the sitemap will use the protocol
diff --git a/django/contrib/staticfiles/management/commands/collectstatic.py b/django/contrib/staticfiles/management/commands/collectstatic.py
index e6b6198..793c211 100644
--- a/django/contrib/staticfiles/management/commands/collectstatic.py
+++ b/django/contrib/staticfiles/management/commands/collectstatic.py
@@ -218,12 +218,16 @@ class Command(BaseCommand):
                          smart_text(fpath), level=1)
             else:
                 self.log("Deleting '%s'" % smart_text(fpath), level=1)
-                full_path = self.storage.path(fpath)
-                if not os.path.exists(full_path) and os.path.lexists(full_path):
-                    # Delete broken symlinks
-                    os.unlink(full_path)
-                else:
+                try:
+                    full_path = self.storage.path(fpath)
+                except NotImplementedError:
                     self.storage.delete(fpath)
+                else:
+                    if not os.path.exists(full_path) and os.path.lexists(full_path):
+                        # Delete broken symlinks
+                        os.unlink(full_path)
+                    else:
+                        self.storage.delete(fpath)
         for d in dirs:
             self.clear_dir(os.path.join(path, d))
 
diff --git a/django/core/cache/backends/base.py b/django/core/cache/backends/base.py
index 75a131a..12351c5 100644
--- a/django/core/cache/backends/base.py
+++ b/django/core/cache/backends/base.py
@@ -154,8 +154,7 @@ class BaseCache(object):
         also be any callable. If timeout is given, that timeout will be used
         for the key; otherwise the default cache timeout will be used.
 
-        Returns the value of the key stored or retrieved on success,
-        False on error.
+        Return the value of the key stored or retrieved.
         """
         if default is None:
             raise ValueError('You need to specify a value.')
@@ -163,9 +162,10 @@ class BaseCache(object):
         if val is None:
             if callable(default):
                 default = default()
-            val = self.add(key, default, timeout=timeout, version=version)
-            if val:
-                return self.get(key, default, version)
+            self.add(key, default, timeout=timeout, version=version)
+            # Fetch the value again to avoid a race condition if another caller
+            # added a value between the first get() and the add() above.
+            return self.get(key, default, version=version)
         return val
 
     def has_key(self, key, version=None):
diff --git a/django/core/management/base.py b/django/core/management/base.py
index a2fe1f9..b9cc2c0 100644
--- a/django/core/management/base.py
+++ b/django/core/management/base.py
@@ -262,7 +262,7 @@ class BaseCommand(object):
             # Backwards compatibility: use deprecated optparse module
             warnings.warn("OptionParser usage for Django management commands "
                           "is deprecated, use ArgumentParser instead",
-                          RemovedInDjango110Warning)
+                          RemovedInDjango110Warning, stacklevel=3)
             parser = OptionParser(prog=prog_name,
                                 usage=self.usage(subcommand),
                                 version=self.get_version())
diff --git a/django/db/backends/sqlite3/schema.py b/django/db/backends/sqlite3/schema.py
index 6f0c818..9d9eb3c 100644
--- a/django/db/backends/sqlite3/schema.py
+++ b/django/db/backends/sqlite3/schema.py
@@ -76,8 +76,16 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
           3. copy the data from the old renamed table to the new table
           4. delete the "app_model__old" table
         """
+        # Self-referential fields must be recreated rather than copied from
+        # the old model to ensure their remote_field.field_name doesn't refer
+        # to an altered field.
+        def is_self_referential(f):
+            return f.is_relation and f.remote_field.model is model
         # Work out the new fields dict / mapping
-        body = {f.name: f for f in model._meta.local_concrete_fields}
+        body = {
+            f.name: f.clone() if is_self_referential(f) else f
+            for f in model._meta.local_concrete_fields
+        }
         # Since mapping might mix column names and default values,
         # its values must be already quoted.
         mapping = {f.column: self.quote_name(f.column) for f in model._meta.local_concrete_fields}
diff --git a/django/db/migrations/autodetector.py b/django/db/migrations/autodetector.py
index 513bb54..62ea80b 100644
--- a/django/db/migrations/autodetector.py
+++ b/django/db/migrations/autodetector.py
@@ -38,7 +38,7 @@ class MigrationAutodetector(object):
 
     def changes(self, graph, trim_to_apps=None, convert_apps=None, migration_name=None):
         """
-        Main entry point to produce a list of appliable changes.
+        Main entry point to produce a list of applicable changes.
         Takes a graph to base names on and an optional set of apps
         to try and restrict to (restriction is not guaranteed)
         """
diff --git a/django/db/models/__init__.py b/django/db/models/__init__.py
index 5d9e14a..07fe6bc 100644
--- a/django/db/models/__init__.py
+++ b/django/db/models/__init__.py
@@ -7,7 +7,7 @@ from django.db.models.deletion import (  # NOQA
     CASCADE, DO_NOTHING, PROTECT, SET, SET_DEFAULT, SET_NULL, ProtectedError,
 )
 from django.db.models.expressions import (  # NOQA
-    F, Case, Expression, ExpressionWrapper, Func, Value, When,
+    Case, Expression, ExpressionWrapper, F, Func, Value, When,
 )
 from django.db.models.fields import *  # NOQA
 from django.db.models.fields.files import FileField, ImageField  # NOQA
@@ -15,7 +15,7 @@ from django.db.models.fields.proxy import OrderWrt  # NOQA
 from django.db.models.fields.subclassing import SubfieldBase  # NOQA
 from django.db.models.lookups import Lookup, Transform  # NOQA
 from django.db.models.manager import Manager  # NOQA
-from django.db.models.query import Q, Prefetch, QuerySet  # NOQA
+from django.db.models.query import Prefetch, Q, QuerySet  # NOQA
 
 # Imports that would create circular imports if sorted
 from django.db.models.base import Model  # NOQA isort:skip
diff --git a/django/db/models/base.py b/django/db/models/base.py
index e1a94d3..5635fab 100644
--- a/django/db/models/base.py
+++ b/django/db/models/base.py
@@ -245,13 +245,21 @@ class ModelBase(type):
                     field = None
                 new_class._meta.parents[base] = field
             else:
+                base_parents = base._meta.parents.copy()
+
                 # .. and abstract ones.
                 for field in parent_fields:
                     new_field = copy.deepcopy(field)
                     new_class.add_to_class(field.name, new_field)
+                    # Replace parent links defined on this base by the new
+                    # field as it will be appropriately resolved if required.
+                    if field.one_to_one:
+                        for parent, parent_link in base_parents.items():
+                            if field == parent_link:
+                                base_parents[parent] = new_field
 
                 # Pass any non-abstract parent classes onto child.
-                new_class._meta.parents.update(base._meta.parents)
+                new_class._meta.parents.update(base_parents)
 
             # Inherit managers from the abstract base classes.
             new_class.copy_managers(base._meta.abstract_managers)
diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py
index df2e3b4..cf7a3c3 100644
--- a/django/db/models/fields/__init__.py
+++ b/django/db/models/fields/__init__.py
@@ -1665,7 +1665,8 @@ class DurationField(Field):
             return value
         if value is None:
             return None
-        return value.total_seconds() * 1000000
+        # Discard any fractional microseconds due to floating point arithmetic.
+        return int(round(value.total_seconds() * 1000000))
 
     def get_db_converters(self, connection):
         converters = []
diff --git a/django/db/models/query.py b/django/db/models/query.py
index cb02085..33c40cb 100644
--- a/django/db/models/query.py
+++ b/django/db/models/query.py
@@ -16,10 +16,10 @@ from django.db import (
 from django.db.models import sql
 from django.db.models.constants import LOOKUP_SEP
 from django.db.models.deletion import Collector
-from django.db.models.expressions import F, Date, DateTime
+from django.db.models.expressions import Date, DateTime, F
 from django.db.models.fields import AutoField
 from django.db.models.query_utils import (
-    Q, InvalidQuery, check_rel_lookup_compatibility, deferred_class_factory,
+    InvalidQuery, Q, check_rel_lookup_compatibility, deferred_class_factory,
 )
 from django.db.models.sql.constants import CURSOR
 from django.utils import six, timezone
@@ -1113,7 +1113,7 @@ class QuerySet(object):
             # if they are set up to select only a single field.
             if len(self._fields or self.model._meta.concrete_fields) > 1:
                 raise TypeError('Cannot use multi-field values as a filter value.')
-        else:
+        elif self.model != field.model:
             # If the query is used as a subquery for a ForeignKey with non-pk
             # target field, make sure to select the target field in the subquery.
             foreign_fields = getattr(field, 'foreign_related_fields', ())
diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py
index 29fe885..dec7d9f 100644
--- a/django/db/models/sql/query.py
+++ b/django/db/models/sql/query.py
@@ -19,7 +19,7 @@ from django.db.models.constants import LOOKUP_SEP
 from django.db.models.expressions import Col, Ref
 from django.db.models.fields.related_lookups import MultiColSource
 from django.db.models.query_utils import (
-    Q, PathInfo, check_rel_lookup_compatibility, refs_expression,
+    PathInfo, Q, check_rel_lookup_compatibility, refs_expression,
 )
 from django.db.models.sql.constants import (
     INNER, LOUTER, ORDER_DIR, ORDER_PATTERN, QUERY_TERMS, SINGLE,
diff --git a/django/http/multipartparser.py b/django/http/multipartparser.py
index 375584e..67d0fc4 100644
--- a/django/http/multipartparser.py
+++ b/django/http/multipartparser.py
@@ -181,10 +181,11 @@ class MultiPartParser(object):
                 elif item_type == FILE:
                     # This is a file, use the handler...
                     file_name = disposition.get('filename')
+                    if file_name:
+                        file_name = force_text(file_name, encoding, errors='replace')
+                        file_name = self.IE_sanitize(unescape_entities(file_name))
                     if not file_name:
                         continue
-                    file_name = force_text(file_name, encoding, errors='replace')
-                    file_name = self.IE_sanitize(unescape_entities(file_name))
 
                     content_type, content_type_extra = meta_data.get('content-type', ('', {}))
                     content_type = content_type.strip()
diff --git a/django/middleware/common.py b/django/middleware/common.py
index 50acf32..b842dd8 100644
--- a/django/middleware/common.py
+++ b/django/middleware/common.py
@@ -54,18 +54,19 @@ class CommonMiddleware(object):
 
         # Check for a redirect based on settings.PREPEND_WWW
         host = request.get_host()
+        must_prepend = settings.PREPEND_WWW and host and not host.startswith('www.')
+        redirect_url = ('%s://www.%s' % (request.scheme, host)) if must_prepend else ''
 
-        if settings.PREPEND_WWW and host and not host.startswith('www.'):
-            host = 'www.' + host
-
-            # Check if we also need to append a slash so we can do it all
-            # with a single redirect.
-            if self.should_redirect_with_slash(request):
-                path = self.get_full_path_with_slash(request)
-            else:
-                path = request.get_full_path()
+        # Check if a slash should be appended
+        if self.should_redirect_with_slash(request):
+            path = self.get_full_path_with_slash(request)
+        else:
+            path = request.get_full_path()
 
-            return self.response_redirect_class('%s://%s%s' % (request.scheme, host, path))
+        # Return a redirect if necessary
+        if redirect_url or path != request.get_full_path():
+            redirect_url += path
+            return self.response_redirect_class(redirect_url)
 
     def should_redirect_with_slash(self, request):
         """
diff --git a/django/template/backends/django.py b/django/template/backends/django.py
index deca90c..70b39b5 100644
--- a/django/template/backends/django.py
+++ b/django/template/backends/django.py
@@ -97,13 +97,24 @@ class Template(object):
             reraise(exc, self.backend)
 
 
-def reraise(exc, backend):
+def copy_exception(exc, backend=None):
     """
-    Reraise TemplateDoesNotExist while maintaining template debug information.
+    Create a new TemplateDoesNotExist. Preserve its declared attributes and
+    template debug data but discard __traceback__, __context__, and __cause__
+    to make this object suitable for keeping around (in a cache, for example).
     """
-    new = exc.__class__(*exc.args, tried=exc.tried, backend=backend)
+    backend = backend or exc.backend
+    new = exc.__class__(*exc.args, tried=exc.tried, backend=backend, chain=exc.chain)
     if hasattr(exc, 'template_debug'):
         new.template_debug = exc.template_debug
+    return new
+
+
+def reraise(exc, backend):
+    """
+    Reraise TemplateDoesNotExist while maintaining template debug information.
+    """
+    new = copy_exception(exc, backend)
     six.reraise(exc.__class__, new, sys.exc_info()[2])
 
 
diff --git a/django/template/loaders/cached.py b/django/template/loaders/cached.py
index 5bf5c10..70c55fe 100644
--- a/django/template/loaders/cached.py
+++ b/django/template/loaders/cached.py
@@ -7,6 +7,7 @@ import hashlib
 import warnings
 
 from django.template import Origin, Template, TemplateDoesNotExist
+from django.template.backends.django import copy_exception
 from django.utils.deprecation import RemovedInDjango20Warning
 from django.utils.encoding import force_bytes
 from django.utils.inspect import func_supports_parameter
@@ -27,11 +28,31 @@ class Loader(BaseLoader):
         return origin.loader.get_contents(origin)
 
     def get_template(self, template_name, template_dirs=None, skip=None):
+        """
+        Perform the caching that gives this loader its name. Often many of the
+        templates attempted will be missing, so memory use is of concern here.
+        To keep it in check, caching behavior is a little complicated when a
+        template is not found. See ticket #26306 for more details.
+
+        With template debugging disabled, cache the TemplateDoesNotExist class
+        for every missing template and raise a new instance of it after
+        fetching it from the cache.
+
+        With template debugging enabled, a unique TemplateDoesNotExist object
+        is cached for each missing template to preserve debug data. When
+        raising an exception, Python sets __traceback__, __context__, and
+        __cause__ attributes on it. Those attributes can contain references to
+        all sorts of objects up the call chain and caching them creates a
+        memory leak. Thus, unraised copies of the exceptions are cached and
+        copies of those copies are raised after they're fetched from the cache.
+        """
         key = self.cache_key(template_name, template_dirs, skip)
         cached = self.get_template_cache.get(key)
         if cached:
-            if isinstance(cached, TemplateDoesNotExist):
-                raise cached
+            if isinstance(cached, type) and issubclass(cached, TemplateDoesNotExist):
+                raise cached(template_name)
+            elif isinstance(cached, TemplateDoesNotExist):
+                raise copy_exception(cached)
             return cached
 
         try:
@@ -39,7 +60,7 @@ class Loader(BaseLoader):
                 template_name, template_dirs, skip,
             )
         except TemplateDoesNotExist as e:
-            self.get_template_cache[key] = e
+            self.get_template_cache[key] = copy_exception(e) if self.engine.debug else TemplateDoesNotExist
             raise
         else:
             self.get_template_cache[key] = template
diff --git a/docs/howto/deployment/wsgi/modwsgi.txt b/docs/howto/deployment/wsgi/modwsgi.txt
index 988ff8a..96c7e48 100644
--- a/docs/howto/deployment/wsgi/modwsgi.txt
+++ b/docs/howto/deployment/wsgi/modwsgi.txt
@@ -25,12 +25,11 @@ Basic configuration
 ===================
 
 Once you've got mod_wsgi installed and activated, edit your Apache server's
-`httpd.conf`_ file (or a `virtual host`_ file) and add the following. If you
-are using a version of Apache older than 2.4, replace ``Require all granted``
-with ``Allow from all`` and also add the line ``Order deny,allow`` above it.
+`httpd.conf`_ file and add the following. If you are using a version of Apache
+older than 2.4, replace ``Require all granted`` with ``Allow from all`` and
+also add the line ``Order deny,allow`` above it.
 
 .. _httpd.conf: https://wiki.apache.org/httpd/DistrosDefaultLayout
-.. _virtual host: https://httpd.apache.org/docs/current/en/vhosts/
 
 .. code-block:: apache
 
diff --git a/docs/howto/error-reporting.txt b/docs/howto/error-reporting.txt
index fc04337..9ae194d 100644
--- a/docs/howto/error-reporting.txt
+++ b/docs/howto/error-reporting.txt
@@ -143,10 +143,12 @@ exception raised, each `traceback frame`_’s local variables, and the
 
 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
-credit card number. So Django offers a set of function decorators to help you
-control which information should be filtered out of error reports in a
-production environment (that is, where :setting:`DEBUG` is set to ``False``):
-:func:`sensitive_variables` and :func:`sensitive_post_parameters`.
+credit card number. So in addition to filtering out settings that appear to be
+sensitive as described in the :setting:`DEBUG` documentation, Django offers a
+set of function decorators to help you control which information should be
+filtered out of error reports in a production environment (that is, where
+:setting:`DEBUG` is set to ``False``): :func:`sensitive_variables` and
+:func:`sensitive_post_parameters`.
 
 .. _`full traceback`: https://en.wikipedia.org/wiki/Stack_trace
 .. _`traceback frame`: https://en.wikipedia.org/wiki/Stack_frame
diff --git a/docs/internals/contributing/writing-documentation.txt b/docs/internals/contributing/writing-documentation.txt
index 6c4e583..8cb5039 100644
--- a/docs/internals/contributing/writing-documentation.txt
+++ b/docs/internals/contributing/writing-documentation.txt
@@ -220,10 +220,8 @@ documentation:
 Django-specific markup
 ======================
 
-Besides the `Sphinx built-in markup`__, Django's docs defines some extra
-description units:
-
-__ http://sphinx-doc.org/markup/
+Besides the :ref:`Sphinx built-in markup <sphinx:sphinxmarkup>`, Django's
+docs defines some extra description units:
 
 * Settings::
 
diff --git a/docs/internals/howto-release-django.txt b/docs/internals/howto-release-django.txt
index 0da90ae..7edd692 100644
--- a/docs/internals/howto-release-django.txt
+++ b/docs/internals/howto-release-django.txt
@@ -368,7 +368,7 @@ You're almost done! All that's left to do now is:
 New stable branch tasks
 =======================
 
-There are several items to do in the time following a the creation of a new
+There are several items to do in the time following the creation of a new
 stable branch (often following an alpha release). Some of these tasks don't
 need to be done by the releaser.
 
diff --git a/docs/intro/reusable-apps.txt b/docs/intro/reusable-apps.txt
index 4f77e8b..fee59a3 100644
--- a/docs/intro/reusable-apps.txt
+++ b/docs/intro/reusable-apps.txt
@@ -2,11 +2,11 @@
 Advanced tutorial: How to write reusable apps
 =============================================
 
-This advanced tutorial begins where :doc:`Tutorial 6 </intro/tutorial06>`
+This advanced tutorial begins where :doc:`Tutorial 7 </intro/tutorial07>`
 left off. We'll be turning our Web-poll into a standalone Python package
 you can reuse in new projects and share with other people.
 
-If you haven't recently completed Tutorials 1–6, we encourage you to review
+If you haven't recently completed Tutorials 1–7, we encourage you to review
 these so that your example project matches the one described below.
 
 Reusability matters
diff --git a/docs/intro/tutorial01.txt b/docs/intro/tutorial01.txt
index 0bdc593..de86571 100644
--- a/docs/intro/tutorial01.txt
+++ b/docs/intro/tutorial01.txt
@@ -298,6 +298,20 @@ an :func:`~django.conf.urls.include` in the ``urlpatterns`` list, so you have:
         url(r'^admin/', admin.site.urls),
     ]
 
+The :func:`~django.conf.urls.include` function allows referencing other
+URLconfs. Note that the regular expressions for the
+:func:`~django.conf.urls.include` function doesn't have a ``$`` (end-of-string
+match character) but rather a trailing slash. Whenever Django encounters
+:func:`~django.conf.urls.include`, it chops off whatever part of the URL
+matched up to that point and sends the remaining string to the included URLconf
+for further processing.
+
+The idea behind :func:`~django.conf.urls.include` is to make it easy to
+plug-and-play URLs. Since polls are in their own URLconf
+(``polls/urls.py``), they can be placed under "/polls/", or under
+"/fun_polls/", or under "/content/polls/", or any other path root, and the
+app will still work.
+
 .. admonition:: When to use :func:`~django.conf.urls.include()`
 
     You should always use ``include()`` when you include other URL patterns.
diff --git a/docs/intro/tutorial02.txt b/docs/intro/tutorial02.txt
index 53daae9..1d4e16f 100644
--- a/docs/intro/tutorial02.txt
+++ b/docs/intro/tutorial02.txt
@@ -41,7 +41,7 @@ If you are not using SQLite as your database, additional settings such as
 :setting:`USER`, :setting:`PASSWORD`, and :setting:`HOST` must be added.
 For more details, see the reference documentation for :setting:`DATABASES`.
 
-.. admonition:: For non-SQLite users
+.. admonition:: For databases other than SQLite
 
     If you're using a database besides SQLite, make sure you've created a
     database by this point. Do that with "``CREATE DATABASE database_name;``"
diff --git a/docs/intro/tutorial03.txt b/docs/intro/tutorial03.txt
index ef2ad2d..b3973a4 100644
--- a/docs/intro/tutorial03.txt
+++ b/docs/intro/tutorial03.txt
@@ -106,29 +106,11 @@ placeholder results and voting pages.
 When somebody requests a page from your website -- say, "/polls/34/", Django
 will load the ``mysite.urls`` Python module because it's pointed to by the
 :setting:`ROOT_URLCONF` setting. It finds the variable named ``urlpatterns``
-and traverses the regular expressions in order. The
-:func:`~django.conf.urls.include` functions we are using simply reference
-other URLconfs. Note that the regular expressions for the
-:func:`~django.conf.urls.include` functions don't have a ``$`` (end-of-string
-match character) but rather a trailing slash. Whenever Django encounters
-:func:`~django.conf.urls.include`, it chops off whatever part of the URL
-matched up to that point and sends the remaining string to the included
-URLconf for further processing.
-
-The idea behind :func:`~django.conf.urls.include` is to make it easy to
-plug-and-play URLs. Since polls are in their own URLconf
-(``polls/urls.py``), they can be placed under "/polls/", or under
-"/fun_polls/", or under "/content/polls/", or any other path root, and the
-app will still work.
-
-Here's what happens if a user goes to "/polls/34/" in this system:
-
-* Django will find the match at ``'^polls/'``
-
-* Then, Django will strip off the matching text (``"polls/"``) and send the
-  remaining text -- ``"34/"`` -- to the 'polls.urls' URLconf for
-  further processing which matches ``r'^(?P<question_id>[0-9]+)/$'`` resulting in a
-  call to the ``detail()`` view like so::
+and traverses the regular expressions in order. After finding the match at
+``'^polls/'``, it strips off the matching text (``"polls/"``) and sends the
+remaining text -- ``"34/"`` -- to the 'polls.urls' URLconf for further
+processing. There it matches ``r'^(?P<question_id>[0-9]+)/$'``, resulting in a
+call to the ``detail()`` view like so::
 
     detail(request=<HttpRequest object>, question_id='34')
 
diff --git a/docs/intro/tutorial07.txt b/docs/intro/tutorial07.txt
index ecfd90d..cc39abf 100644
--- a/docs/intro/tutorial07.txt
+++ b/docs/intro/tutorial07.txt
@@ -232,7 +232,8 @@ attributes, as follows:
     class Question(models.Model):
         # ...
         def was_published_recently(self):
-            return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
+            now = timezone.now()
+            return now - datetime.timedelta(days=1) <= self.pub_date <= now
         was_published_recently.admin_order_field = 'pub_date'
         was_published_recently.boolean = True
         was_published_recently.short_description = 'Published recently?'
diff --git a/docs/ref/class-based-views/generic-date-based.txt b/docs/ref/class-based-views/generic-date-based.txt
index 8e93182..0aab34b 100644
--- a/docs/ref/class-based-views/generic-date-based.txt
+++ b/docs/ref/class-based-views/generic-date-based.txt
@@ -339,7 +339,7 @@ views for displaying drilldown pages for date-based data.
       * ``'%U'``: Based on the United States week system where the week
         begins on Sunday. This is the default value.
 
-      * ``'%V'``: Similar to ``'%U'``, except it assumes that the week
+      * ``'%W'``: Similar to ``'%U'``, except it assumes that the week
         begins on Monday. This is not the same as the ISO 8601 week number.
 
     **Example myapp/views.py**::
diff --git a/docs/ref/class-based-views/generic-editing.txt b/docs/ref/class-based-views/generic-editing.txt
index 3def731..3bcd9fe 100644
--- a/docs/ref/class-based-views/generic-editing.txt
+++ b/docs/ref/class-based-views/generic-editing.txt
@@ -132,7 +132,7 @@ editing content:
 
         <form action="" method="post">{% csrf_token %}
             {{ form.as_p }}
-            <input type="submit" value="Create" />
+            <input type="submit" value="Save" />
         </form>
 
 ``UpdateView``
diff --git a/docs/ref/class-based-views/mixins-simple.txt b/docs/ref/class-based-views/mixins-simple.txt
index 6130b82..1d41b25 100644
--- a/docs/ref/class-based-views/mixins-simple.txt
+++ b/docs/ref/class-based-views/mixins-simple.txt
@@ -105,7 +105,7 @@ Simple mixins
     .. method:: get_template_names()
 
         Returns a list of template names to search for when rendering the
-        template.
+        template. The first template that is found will be used.
 
         If :attr:`template_name` is specified, the default implementation will
         return a list containing :attr:`template_name` (if it is specified).
diff --git a/docs/ref/contrib/gis/geoquerysets.txt b/docs/ref/contrib/gis/geoquerysets.txt
index 72078eb..5e20d98 100644
--- a/docs/ref/contrib/gis/geoquerysets.txt
+++ b/docs/ref/contrib/gis/geoquerysets.txt
@@ -11,10 +11,7 @@ GeoQuerySet API Reference
 Spatial Lookups
 ===============
 
-Just like when using the :ref:`queryset-api`, interaction
-with ``GeoQuerySet`` by :ref:`chaining filters <chaining-filters>`.
-Instead of the regular Django :ref:`field-lookups`, the
-spatial lookups in this section are available for :class:`GeometryField`.
+The spatial lookups in this section are available for :class:`GeometryField`.
 
 For an introduction, see the :ref:`spatial lookups introduction
 <spatial-lookups-intro>`.  For an overview of what lookups are
@@ -294,7 +291,7 @@ SpatiaLite SQL equivalent::
 Oracle
 ~~~~~~
 
-Here the relation pattern is comprised at least one of the nine relation
+Here the relation pattern is comprised of at least one of the nine relation
 strings: ``TOUCH``, ``OVERLAPBDYDISJOINT``, ``OVERLAPBDYINTERSECT``,
 ``EQUAL``, ``INSIDE``, ``COVEREDBY``, ``CONTAINS``, ``COVERS``, ``ON``, and
 ``ANYINTERACT``.   Multiple strings may be combined with the logical Boolean
diff --git a/docs/ref/contrib/gis/install/index.txt b/docs/ref/contrib/gis/install/index.txt
index 0bb476c..b7ba8e5 100644
--- a/docs/ref/contrib/gis/install/index.txt
+++ b/docs/ref/contrib/gis/install/index.txt
@@ -94,7 +94,7 @@ Add ``django.contrib.gis`` to :setting:`INSTALLED_APPS`
 
 Like other Django contrib applications, you will *only* need to add
 :mod:`django.contrib.gis` to :setting:`INSTALLED_APPS` in your settings.
-This is the so that ``gis`` templates can be located -- if not done, then
+This is so that the ``gis`` templates can be located -- if not done, then
 features such as the geographic admin or KML sitemaps will not function properly.
 
 Troubleshooting
diff --git a/docs/ref/contrib/postgres/aggregates.txt b/docs/ref/contrib/postgres/aggregates.txt
index aa6d091..3097498 100644
--- a/docs/ref/contrib/postgres/aggregates.txt
+++ b/docs/ref/contrib/postgres/aggregates.txt
@@ -118,7 +118,7 @@ field or an expression returning a numeric data. Both are required.
 
 .. class:: RegrAvgY(y, x)
 
-    Returns the average of the independent variable (``sum(y)/N``) as a
+    Returns the average of the dependent variable (``sum(y)/N``) as a
     ``float``, or ``None`` if there aren't any matching rows.
 
 ``RegrCount``
diff --git a/docs/ref/contrib/postgres/fields.txt b/docs/ref/contrib/postgres/fields.txt
index 20b68b5..a70cebe 100644
--- a/docs/ref/contrib/postgres/fields.txt
+++ b/docs/ref/contrib/postgres/fields.txt
@@ -586,7 +586,7 @@ suitable for.
 All of the range fields translate to :ref:`psycopg2 Range objects
 <psycopg2:adapt-range>` in python, but also accept tuples as input if no bounds
 information is necessary. The default is lower bound included, upper bound
-excluded.
+excluded; that is, ``[)``.
 
 ``IntegerRangeField``
 ---------------------
@@ -598,6 +598,10 @@ excluded.
     the database and a :class:`~psycopg2:psycopg2.extras.NumericRange` in
     Python.
 
+    Regardless of the bounds specified when saving the data, PostgreSQL always
+    returns a range in a canonical form that includes the lower bound and
+    excludes the upper bound; that is ``[)``.
+
 ``BigIntegerRangeField``
 ------------------------
 
@@ -608,6 +612,10 @@ excluded.
     in the database and a :class:`~psycopg2:psycopg2.extras.NumericRange` in
     Python.
 
+    Regardless of the bounds specified when saving the data, PostgreSQL always
+    returns a range in a canonical form that includes the lower bound and
+    excludes the upper bound; that is ``[)``.
+
 ``FloatRangeField``
 -------------------
 
@@ -636,6 +644,10 @@ excluded.
     :class:`~django.db.models.DateField`. Represented by a ``daterange`` in the
     database and a :class:`~psycopg2:psycopg2.extras.DateRange` in Python.
... 1377 lines suppressed ...

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/python-django.git



More information about the Python-modules-commits mailing list