[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