[Python-modules-commits] [python-django] 02/09: Import python-django_1.8.5.orig.tar.gz
Raphaël Hertzog
hertzog at moszumanska.debian.org
Tue Oct 13 10:20:25 UTC 2015
This is an automated email from the git hooks/post-receive script.
hertzog pushed a commit to branch debian/experimental
in repository python-django.
commit 498fc878694353cf7bde7baed7ce6e04311ade66
Author: Raphaël Hertzog <hertzog at debian.org>
Date: Tue Oct 13 11:34:29 2015 +0200
Import python-django_1.8.5.orig.tar.gz
---
AUTHORS | 1 +
Django.egg-info/PKG-INFO | 2 +-
Django.egg-info/SOURCES.txt | 1 +
Django.egg-info/requires.txt | 3 +-
PKG-INFO | 2 +-
django/__init__.py | 2 +-
django/contrib/admin/tests.py | 7 +
django/contrib/admin/utils.py | 7 +-
django/contrib/gis/maps/google/overlays.py | 10 +-
django/core/cache/backends/base.py | 2 +-
django/core/management/__init__.py | 19 ++-
django/core/management/base.py | 1 +
django/core/management/commands/runserver.py | 4 +
django/core/urlresolvers.py | 5 +-
django/db/backends/base/creation.py | 2 +-
django/db/backends/mysql/schema.py | 3 +-
django/db/backends/oracle/creation.py | 52 ++++---
django/db/backends/sqlite3/introspection.py | 5 +-
django/db/migrations/questioner.py | 4 +-
django/db/migrations/state.py | 2 +-
django/db/migrations/writer.py | 2 +-
django/db/models/aggregates.py | 4 +-
django/db/models/expressions.py | 8 ++
django/db/models/fields/related.py | 12 +-
django/db/models/query.py | 4 +-
django/db/models/sql/compiler.py | 2 +-
django/db/models/sql/query.py | 3 +-
django/db/transaction.py | 7 -
django/forms/models.py | 14 +-
django/forms/utils.py | 2 +-
django/utils/autoreload.py | 23 ++-
django/utils/functional.py | 56 ++++----
django/utils/ipv6.py | 2 +-
django/utils/translation/__init__.py | 4 +-
docs/howto/custom-template-tags.txt | 8 +-
docs/howto/deployment/wsgi/modwsgi.txt | 6 +-
docs/howto/static-files/index.txt | 6 +-
.../contributing/writing-code/unit-tests.txt | 6 +-
docs/internals/deprecation.txt | 11 +-
docs/internals/team.txt | 4 +-
docs/intro/tutorial01.txt | 13 +-
docs/ref/applications.txt | 15 +-
docs/ref/class-based-views/generic-date-based.txt | 26 ++--
docs/ref/class-based-views/index.txt | 2 +-
docs/ref/contrib/admin/index.txt | 7 +
docs/ref/contrib/contenttypes.txt | 47 +++---
docs/ref/contrib/gis/install/geolibs.txt | 2 +-
docs/ref/contrib/gis/install/index.txt | 26 +++-
docs/ref/contrib/gis/tutorial.txt | 4 +-
docs/ref/contrib/messages.txt | 2 +-
docs/ref/contrib/sites.txt | 2 +-
docs/ref/contrib/syndication.txt | 3 +-
docs/ref/csrf.txt | 6 +-
docs/ref/databases.txt | 32 +++--
docs/ref/django-admin.txt | 11 +-
docs/ref/migration-operations.txt | 32 ++++-
docs/ref/models/querysets.txt | 10 +-
docs/ref/request-response.txt | 8 +-
docs/ref/settings.txt | 27 +++-
docs/ref/templates/api.txt | 7 +
docs/ref/templates/builtins.txt | 25 ++--
docs/ref/unicode.txt | 6 +
docs/ref/utils.txt | 2 +-
docs/releases/1.8.5.txt | 60 ++++++++
docs/releases/1.8.txt | 11 +-
docs/releases/index.txt | 1 +
docs/spelling_wordlist | 5 +
docs/topics/auth/default.txt | 4 +-
docs/topics/class-based-views/generic-display.txt | 2 +-
docs/topics/class-based-views/index.txt | 2 +-
docs/topics/class-based-views/intro.txt | 4 +-
docs/topics/class-based-views/mixins.txt | 5 +-
docs/topics/db/aggregation.txt | 4 +-
docs/topics/db/examples/one_to_one.txt | 2 +-
docs/topics/db/models.txt | 8 +-
docs/topics/db/sql.txt | 42 ++++--
docs/topics/db/transactions.txt | 14 +-
docs/topics/forms/index.txt | 3 +
docs/topics/http/urls.txt | 2 +-
docs/topics/i18n/translation.txt | 5 +-
docs/topics/install.txt | 149 +++----------------
docs/topics/logging.txt | 4 +-
docs/topics/security.txt | 15 +-
docs/topics/settings.txt | 4 +-
docs/topics/testing/advanced.txt | 47 +++---
docs/topics/testing/overview.txt | 26 ++--
docs/topics/testing/tools.txt | 19 ++-
setup.cfg | 2 +-
tests/admin_views/admin.py | 6 +-
tests/admin_views/tests.py | 20 ++-
tests/admin_widgets/tests.py | 21 ++-
tests/aggregation/tests.py | 6 +
tests/aggregation_regress/tests.py | 2 +-
tests/custom_managers/tests.py | 4 +
tests/expressions/tests.py | 1 +
tests/i18n/tests.py | 3 +
tests/m2m_regress/models.py | 11 ++
tests/m2m_regress/tests.py | 13 +-
tests/migrations/test_autodetector.py | 12 +-
tests/migrations/test_state.py | 7 +
tests/model_formsets/models.py | 4 +
tests/model_meta/results.py | 20 +--
tests/model_meta/tests.py | 2 +-
tests/one_to_one/models.py | 2 +-
tests/one_to_one/tests.py | 20 ++-
tests/queries/models.py | 1 +
tests/queries/tests.py | 30 +++-
tests/requirements/mysql.txt | 3 +-
tests/requirements/py2.txt | 3 +-
tests/schema/tests.py | 12 ++
tests/test_runner/test_debug_sql.py | 24 ++--
tests/transactions/tests.py | 17 ++-
tests/utils_tests/models.py | 4 +
tests/utils_tests/test_autoreload.py | 157 ++++++++++++++++-----
tests/utils_tests/test_lazyobject.py | 92 ++++++++++++
tests/validators/valid_urls.txt | 2 +-
116 files changed, 1016 insertions(+), 556 deletions(-)
diff --git a/AUTHORS b/AUTHORS
index ba80d56..0c1b017 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -341,6 +341,7 @@ answer newbie questions, and generally made Django that much better:
john at calixto.net
John D'Agostino <john.dagostino at gmail.com>
John Huddleston <huddlej at wwu.edu>
+ John Moses <moses.john.r at gmail.com>
John Paulett <john at paulett.org>
John Shaffer <jshaffer2112 at gmail.com>
Jökull Sólberg Auðunsson <jokullsolberg at gmail.com>
diff --git a/Django.egg-info/PKG-INFO b/Django.egg-info/PKG-INFO
index 639f603..6a8f3a7 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.8.4
+Version: 1.8.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 c3367bd..debb4fb 100644
--- a/Django.egg-info/SOURCES.txt
+++ b/Django.egg-info/SOURCES.txt
@@ -3402,6 +3402,7 @@ docs/releases/1.8.1.txt
docs/releases/1.8.2.txt
docs/releases/1.8.3.txt
docs/releases/1.8.4.txt
+docs/releases/1.8.5.txt
docs/releases/1.8.txt
docs/releases/index.txt
docs/releases/security.txt
diff --git a/Django.egg-info/requires.txt b/Django.egg-info/requires.txt
index 1b80b4a..14b2d26 100644
--- a/Django.egg-info/requires.txt
+++ b/Django.egg-info/requires.txt
@@ -1,4 +1,3 @@
-
[bcrypt]
-bcrypt
\ No newline at end of file
+bcrypt
diff --git a/PKG-INFO b/PKG-INFO
index 639f603..6a8f3a7 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: Django
-Version: 1.8.4
+Version: 1.8.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 6151137..1a527db 100644
--- a/django/__init__.py
+++ b/django/__init__.py
@@ -1,6 +1,6 @@
from django.utils.version import get_version
-VERSION = (1, 8, 4, 'final', 0)
+VERSION = (1, 8, 5, 'final', 0)
__version__ = get_version(VERSION)
diff --git a/django/contrib/admin/tests.py b/django/contrib/admin/tests.py
index d7780da..5415d5f 100644
--- a/django/contrib/admin/tests.py
+++ b/django/contrib/admin/tests.py
@@ -45,6 +45,13 @@ class AdminSeleniumWebDriverTestCase(StaticLiveServerTestCase):
from selenium.webdriver.support.wait import WebDriverWait
WebDriverWait(self.selenium, timeout).until(callback)
+ def wait_for_popup(self, num_windows=2, timeout=10):
+ """
+ Block until `num_windows` are present (usually 2, but can be
+ overridden in the case of pop-ups opening other pop-ups).
+ """
+ self.wait_until(lambda d: len(d.window_handles) == num_windows, timeout)
+
def wait_loaded_tag(self, tag_name, timeout=10):
"""
Helper function that blocks until the element with the given tag name
diff --git a/django/contrib/admin/utils.py b/django/contrib/admin/utils.py
index 619e9ad..8ddba50 100644
--- a/django/contrib/admin/utils.py
+++ b/django/contrib/admin/utils.py
@@ -293,9 +293,14 @@ def _get_non_gfk_field(opts, name):
"""
For historical reasons, the admin app relies on GenericForeignKeys as being
"not found" by get_field(). This could likely be cleaned up.
+
+ Reverse relations should also be excluded as these aren't attributes of the
+ model (rather something like `foo_set`).
"""
field = opts.get_field(name)
- if field.is_relation and field.many_to_one and not field.related_model:
+ if (field.is_relation and
+ # Generic foreign keys OR reverse relations
+ ((field.many_to_one and not field.related_model) or field.one_to_many)):
raise FieldDoesNotExist()
return field
diff --git a/django/contrib/gis/maps/google/overlays.py b/django/contrib/gis/maps/google/overlays.py
index ac0a6bd..f313329 100644
--- a/django/contrib/gis/maps/google/overlays.py
+++ b/django/contrib/gis/maps/google/overlays.py
@@ -19,7 +19,7 @@ class GEvent(object):
add_event() call.
For more information please see the Google Maps API Reference:
- http://code.google.com/apis/maps/documentation/reference.html#GEvent
+ https://developers.google.com/maps/documentation/javascript/reference#event
Example:
@@ -83,7 +83,7 @@ class GPolygon(GOverlayBase):
"""
A Python wrapper for the Google GPolygon object. For more information
please see the Google Maps API Reference:
- http://code.google.com/apis/maps/documentation/reference.html#GPolygon
+ https://developers.google.com/maps/documentation/javascript/reference#Polygon
"""
def __init__(self, poly,
stroke_color='#0000ff', stroke_weight=2, stroke_opacity=1,
@@ -143,7 +143,7 @@ class GPolyline(GOverlayBase):
"""
A Python wrapper for the Google GPolyline object. For more information
please see the Google Maps API Reference:
- http://code.google.com/apis/maps/documentation/reference.html#GPolyline
+ https://developers.google.com/maps/documentation/javascript/reference#Polyline
"""
def __init__(self, geom, color='#0000ff', weight=2, opacity=1):
"""
@@ -194,7 +194,7 @@ class GIcon(object):
in turn, correspond to a subset of the attributes of the official GIcon
javascript object:
- http://code.google.com/apis/maps/documentation/reference.html#GIcon
+ https://developers.google.com/maps/documentation/javascript/reference#Icon
Because a Google map often uses several different icons, a name field has
been added to the required arguments.
@@ -267,7 +267,7 @@ class GMarker(GOverlayBase):
"""
A Python wrapper for the Google GMarker object. For more information
please see the Google Maps API Reference:
- http://code.google.com/apis/maps/documentation/reference.html#GMarker
+ https://developers.google.com/maps/documentation/javascript/reference#Marker
Example:
diff --git a/django/core/cache/backends/base.py b/django/core/cache/backends/base.py
index 7ac1e5b..07e172e 100644
--- a/django/core/cache/backends/base.py
+++ b/django/core/cache/backends/base.py
@@ -91,7 +91,7 @@ class BaseCache(object):
def make_key(self, key, version=None):
"""Constructs the key used by all other methods. By default it
uses the key_func to generate a key (which, by default,
- prepends the `key_prefix' and 'version'). An different key
+ prepends the `key_prefix' and 'version'). A different key
function can be provided at the time of cache construction;
alternatively, you can subclass the cache backend to provide
custom key making behavior.
diff --git a/django/core/management/__init__.py b/django/core/management/__init__.py
index 5b08977..e2885bb 100644
--- a/django/core/management/__init__.py
+++ b/django/core/management/__init__.py
@@ -13,7 +13,7 @@ from django.core.exceptions import ImproperlyConfigured
from django.core.management.base import (BaseCommand, CommandError,
CommandParser, handle_default_options)
from django.core.management.color import color_style
-from django.utils import lru_cache, six
+from django.utils import autoreload, lru_cache, six
from django.utils._os import npath, upath
@@ -254,7 +254,7 @@ class ManagementUtility(object):
options.extend((sorted(s_opt.option_strings)[0], s_opt.nargs != 0) for s_opt in
parser._actions if s_opt.option_strings)
else:
- options.extend((s_opt.get_opt_string(), s_opt.nargs) for s_opt in
+ options.extend((s_opt.get_opt_string(), s_opt.nargs != 0) for s_opt in
parser.option_list)
# filter out previously specified options from available options
prev_opts = [x.split('=')[0] for x in cwords[1:cword - 1]]
@@ -309,7 +309,20 @@ class ManagementUtility(object):
settings.configure()
if settings.configured:
- django.setup()
+ # Start the auto-reloading dev server even if the code is broken.
+ # The hardcoded condition is a code smell but we can't rely on a
+ # flag on the command class because we haven't located it yet.
+ if subcommand == 'runserver' and '--noreload' not in self.argv:
+ try:
+ autoreload.check_errors(django.setup)()
+ except Exception:
+ # The exception will be raised later in the child process
+ # started by the autoreloader.
+ pass
+
+ # In all other cases, django.setup() is required to succeed.
+ else:
+ django.setup()
self.autocomplete()
diff --git a/django/core/management/base.py b/django/core/management/base.py
index 558cc32..971e26c 100644
--- a/django/core/management/base.py
+++ b/django/core/management/base.py
@@ -175,6 +175,7 @@ class BaseCommand(object):
This is the list of ``optparse`` options which will be fed
into the command's ``OptionParser`` for parsing arguments.
Deprecated and will be removed in Django 1.10.
+ Use ``add_arguments`` instead.
``output_transaction``
A boolean indicating whether the command outputs SQL
diff --git a/django/core/management/commands/runserver.py b/django/core/management/commands/runserver.py
index af81393..73ddb44 100644
--- a/django/core/management/commands/runserver.py
+++ b/django/core/management/commands/runserver.py
@@ -102,6 +102,10 @@ class Command(BaseCommand):
from django.conf import settings
from django.utils import translation
+ # If an exception was silenced in ManagementUtility.execute in order
+ # to be raised in the child process, raise it now.
+ autoreload.raise_last_exception()
+
threading = options.get('use_threading')
shutdown_message = options.get('shutdown_message', '')
quit_command = 'CTRL-BREAK' if sys.platform == 'win32' else 'CONTROL-C'
diff --git a/django/core/urlresolvers.py b/django/core/urlresolvers.py
index f7753cf..f3caaa9 100644
--- a/django/core/urlresolvers.py
+++ b/django/core/urlresolvers.py
@@ -2,9 +2,8 @@
This module converts requested URLs to callback view functions.
RegexURLResolver is the main class here. Its resolve() method takes a URL (as
-a string) and returns a tuple in this format:
-
- (view_function, function_args, function_kwargs)
+a string) and returns a ResolverMatch object which provides access to all
+attributes of the resolved URL match.
"""
from __future__ import unicode_literals
diff --git a/django/db/backends/base/creation.py b/django/db/backends/base/creation.py
index 72eb345..909c570 100644
--- a/django/db/backends/base/creation.py
+++ b/django/db/backends/base/creation.py
@@ -427,7 +427,7 @@ class BaseDatabaseCreation(object):
Internal implementation - returns the name of the test DB that will be
created. Only useful when called from create_test_db() and
_create_test_db() and when no external munging is done with the 'NAME'
- or 'TEST_NAME' settings.
+ settings.
"""
if self.connection.settings_dict['TEST']['NAME']:
return self.connection.settings_dict['TEST']['NAME']
diff --git a/django/db/backends/mysql/schema.py b/django/db/backends/mysql/schema.py
index 91a14ad..2d35da8 100644
--- a/django/db/backends/mysql/schema.py
+++ b/django/db/backends/mysql/schema.py
@@ -43,7 +43,8 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
super(DatabaseSchemaEditor, self).add_field(model, field)
# Simulate the effect of a one-off default.
- if self.skip_default(field) and field.default not in {None, NOT_PROVIDED}:
+ # field.default may be unhashable, so a set isn't used for "in" check.
+ if self.skip_default(field) and field.default not in (None, NOT_PROVIDED):
effective_default = self.effective_default(field)
self.execute('UPDATE %(table)s SET %(column)s = %%s' % {
'table': self.quote_name(model._meta.db_table),
diff --git a/django/db/backends/oracle/creation.py b/django/db/backends/oracle/creation.py
index 1e999f8..b7373e8 100644
--- a/django/db/backends/oracle/creation.py
+++ b/django/db/backends/oracle/creation.py
@@ -17,7 +17,7 @@ class DatabaseCreation(BaseDatabaseCreation):
cursor = self.connection.cursor()
if self._test_database_create():
try:
- self._execute_test_db_creation(cursor, parameters, verbosity)
+ self._execute_test_db_creation(cursor, parameters, verbosity, keepdb)
except Exception as e:
# if we want to keep the db, then no need to do any of the below,
# just return and skip it all.
@@ -45,7 +45,7 @@ class DatabaseCreation(BaseDatabaseCreation):
sys.stderr.write("Got an error destroying the old test database: %s\n" % e)
sys.exit(2)
try:
- self._execute_test_db_creation(cursor, parameters, verbosity)
+ self._execute_test_db_creation(cursor, parameters, verbosity, keepdb)
except Exception as e:
sys.stderr.write("Got an error recreating the test database: %s\n" % e)
sys.exit(2)
@@ -57,8 +57,11 @@ class DatabaseCreation(BaseDatabaseCreation):
if verbosity >= 1:
print("Creating test user...")
try:
- self._create_test_user(cursor, parameters, verbosity)
+ self._create_test_user(cursor, parameters, verbosity, keepdb)
except Exception as e:
+ # If we want to keep the db, then we want to also keep the user.
+ if keepdb:
+ return
sys.stderr.write("Got an error creating the test user: %s\n" % e)
if not autoclobber:
confirm = input(
@@ -71,7 +74,7 @@ class DatabaseCreation(BaseDatabaseCreation):
self._destroy_test_user(cursor, parameters, verbosity)
if verbosity >= 1:
print("Creating test user...")
- self._create_test_user(cursor, parameters, verbosity)
+ self._create_test_user(cursor, parameters, verbosity, keepdb)
except Exception as e:
sys.stderr.write("Got an error recreating the test user: %s\n" % e)
sys.exit(2)
@@ -149,7 +152,7 @@ class DatabaseCreation(BaseDatabaseCreation):
self._execute_test_db_destruction(cursor, parameters, verbosity)
self.connection.close()
- def _execute_test_db_creation(self, cursor, parameters, verbosity):
+ def _execute_test_db_creation(self, cursor, parameters, verbosity, keepdb=False):
if verbosity >= 2:
print("_create_test_db(): dbname = %s" % parameters['user'])
statements = [
@@ -162,9 +165,11 @@ class DatabaseCreation(BaseDatabaseCreation):
REUSE AUTOEXTEND ON NEXT 10M MAXSIZE %(maxsize_tmp)s
""",
]
- self._execute_statements(cursor, statements, parameters, verbosity)
+ # Ignore "tablespace already exists" error when keepdb is on.
+ acceptable_ora_err = 'ORA-01543' if keepdb else None
+ self._execute_allow_fail_statements(cursor, statements, parameters, verbosity, acceptable_ora_err)
- def _create_test_user(self, cursor, parameters, verbosity):
+ def _create_test_user(self, cursor, parameters, verbosity, keepdb=False):
if verbosity >= 2:
print("_create_test_user(): username = %s" % parameters['user'])
statements = [
@@ -181,18 +186,14 @@ class DatabaseCreation(BaseDatabaseCreation):
CREATE TRIGGER
TO %(user)s""",
]
- self._execute_statements(cursor, statements, parameters, verbosity)
+ # Ignore "user already exists" error when keepdb is on
+ acceptable_ora_err = 'ORA-01920' if keepdb else None
+ self._execute_allow_fail_statements(cursor, statements, parameters, verbosity, acceptable_ora_err)
# Most test-suites can be run without the create-view privilege. But some need it.
extra = "GRANT CREATE VIEW TO %(user)s"
- try:
- self._execute_statements(cursor, [extra], parameters, verbosity, allow_quiet_fail=True)
- except DatabaseError as err:
- description = str(err)
- if 'ORA-01031' in description:
- if verbosity >= 2:
- print("Failed to grant CREATE VIEW permission to test user. This may be ok.")
- else:
- raise
+ success = self._execute_allow_fail_statements(cursor, [extra], parameters, verbosity, 'ORA-01031')
+ if not success and verbosity >= 2:
+ print("Failed to grant CREATE VIEW permission to test user. This may be ok.")
def _execute_test_db_destruction(self, cursor, parameters, verbosity):
if verbosity >= 2:
@@ -224,6 +225,23 @@ class DatabaseCreation(BaseDatabaseCreation):
sys.stderr.write("Failed (%s)\n" % (err))
raise
+ def _execute_allow_fail_statements(self, cursor, statements, parameters, verbosity, acceptable_ora_err):
+ """
+ Execute statements which are allowed to fail silently if the Oracle
+ error code given by `acceptable_ora_err` is raised. Return True if the
+ statements execute without an exception, or False otherwise.
+ """
+ try:
+ # Statement can fail when acceptable_ora_err is not None
+ allow_quiet_fail = acceptable_ora_err is not None and len(acceptable_ora_err) > 0
+ self._execute_statements(cursor, statements, parameters, verbosity, allow_quiet_fail=allow_quiet_fail)
+ return True
+ except DatabaseError as err:
+ description = str(err)
+ if acceptable_ora_err is None or acceptable_ora_err not in description:
+ raise
+ return False
+
def _get_test_db_params(self):
return {
'dbname': self._test_database_name(),
diff --git a/django/db/backends/sqlite3/introspection.py b/django/db/backends/sqlite3/introspection.py
index c802489..2641015 100644
--- a/django/db/backends/sqlite3/introspection.py
+++ b/django/db/backends/sqlite3/introspection.py
@@ -88,10 +88,9 @@ class DatabaseIntrospection(BaseDatabaseIntrospection):
def get_relations(self, cursor, table_name):
"""
- Returns a dictionary of {field_index: (field_index_other_table, other_table)}
- representing all relationships to the given table. Indexes are 0-based.
+ Return a dictionary of {field_name: (field_name_other_table, other_table)}
+ representing all relationships to the given table.
"""
-
# Dictionary of relations to return
relations = {}
diff --git a/django/db/migrations/questioner.py b/django/db/migrations/questioner.py
index 5928e3d..55cbe0d 100644
--- a/django/db/migrations/questioner.py
+++ b/django/db/migrations/questioner.py
@@ -148,8 +148,8 @@ class InteractiveMigrationQuestioner(MigrationQuestioner):
[
"Provide a one-off default now (will be set on all existing rows)",
("Ignore for now, and let me handle existing rows with NULL myself "
- "(e.g. adding a RunPython or RunSQL operation in the new migration "
- "file before the AlterField operation)"),
+ "(e.g. because you added a RunPython or RunSQL operation to handle "
+ "NULL values in a previous data migration)"),
"Quit, and let me add a default in models.py",
]
)
diff --git a/django/db/migrations/state.py b/django/db/migrations/state.py
index 8add0b3..c01b12f 100644
--- a/django/db/migrations/state.py
+++ b/django/db/migrations/state.py
@@ -45,7 +45,7 @@ def get_related_models_recursive(model):
def _related_models(m):
return [
f.related_model for f in m._meta.get_fields(include_parents=True, include_hidden=True)
- if f.is_relation and not isinstance(f.related_model, six.string_types)
+ if f.is_relation and f.related_model is not None and not isinstance(f.related_model, six.string_types)
] + [
subclass for subclass in m.__subclasses__()
if issubclass(subclass, models.Model)
diff --git a/django/db/migrations/writer.py b/django/db/migrations/writer.py
index b4417aa..1bed59b 100644
--- a/django/db/migrations/writer.py
+++ b/django/db/migrations/writer.py
@@ -470,7 +470,7 @@ MIGRATION_TEMPLATE = """\
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
-from django.db import models, migrations
+from django.db import migrations, models
%(imports)s
class Migration(migrations.Migration):
diff --git a/django/db/models/aggregates.py b/django/db/models/aggregates.py
index 1b3c413..72b81ac 100644
--- a/django/db/models/aggregates.py
+++ b/django/db/models/aggregates.py
@@ -2,7 +2,7 @@
Classes to represent the definitions of aggregate functions.
"""
from django.core.exceptions import FieldError
-from django.db.models.expressions import Func, Value
+from django.db.models.expressions import Func, Star
from django.db.models.fields import FloatField, IntegerField
__all__ = [
@@ -90,7 +90,7 @@ class Count(Aggregate):
def __init__(self, expression, distinct=False, **extra):
if expression == '*':
- expression = Value(expression)
+ expression = Star()
super(Count, self).__init__(
expression, distinct='DISTINCT ' if distinct else '', output_field=IntegerField(), **extra)
diff --git a/django/db/models/expressions.py b/django/db/models/expressions.py
index 4306193..d3769b4 100644
--- a/django/db/models/expressions.py
+++ b/django/db/models/expressions.py
@@ -584,6 +584,14 @@ class RawSQL(Expression):
return [self]
+class Star(Expression):
+ def __repr__(self):
+ return "'*'"
+
+ def as_sql(self, compiler, connection):
+ return '*', []
+
+
class Random(Expression):
def __init__(self):
super(Random, self).__init__(output_field=fields.FloatField())
diff --git a/django/db/models/fields/related.py b/django/db/models/fields/related.py
index 91bc7f0..83e2a0a 100644
--- a/django/db/models/fields/related.py
+++ b/django/db/models/fields/related.py
@@ -506,12 +506,6 @@ class SingleRelatedObjectDescriptor(object):
raise ValueError('Cannot assign "%r": the current database router prevents this relation.' % value)
related_pk = tuple(getattr(instance, field.attname) for field in self.related.field.foreign_related_fields)
- if None in related_pk:
- raise ValueError(
- 'Cannot assign "%r": "%s" instance isn\'t saved in the database.' %
- (value, instance._meta.object_name)
- )
-
# Set the value of the related field to the value of the related object's related field
for index, field in enumerate(self.related.field.local_related_fields):
setattr(value, field.attname, related_pk[index])
@@ -2538,6 +2532,12 @@ class ManyToManyField(RelatedField):
# clash.
if self.rel.symmetrical and (self.rel.to == "self" or self.rel.to == cls._meta.object_name):
self.rel.related_name = "%s_rel_+" % name
+ elif self.rel.is_hidden():
+ # If the backwards relation is disabled, replace the original
+ # related_name with one generated from the m2m field name. Django
+ # still uses backwards relations internally and we need to avoid
+ # clashes between multiple m2m fields with related_name == '+'.
+ self.rel.related_name = "_%s_+" % name
super(ManyToManyField, self).contribute_to_class(cls, name, **kwargs)
diff --git a/django/db/models/query.py b/django/db/models/query.py
index 4163ce9..d76057e 100644
--- a/django/db/models/query.py
+++ b/django/db/models/query.py
@@ -937,10 +937,10 @@ class QuerySet(object):
using=self.db)
def _clone(self, klass=None, setup=False, **kwargs):
+ base_queryset_class = getattr(self, '_base_queryset_class', self.__class__)
if klass is None:
klass = self.__class__
- elif not issubclass(self.__class__, klass):
- base_queryset_class = getattr(self, '_base_queryset_class', self.__class__)
+ elif not (issubclass(base_queryset_class, klass) or issubclass(klass, base_queryset_class)):
class_bases = (klass, base_queryset_class)
class_dict = {
'_base_queryset_class': base_queryset_class,
diff --git a/django/db/models/sql/compiler.py b/django/db/models/sql/compiler.py
index 688e3f7..fed4353 100644
--- a/django/db/models/sql/compiler.py
+++ b/django/db/models/sql/compiler.py
@@ -986,7 +986,7 @@ class SQLDeleteCompiler(SQLCompiler):
Creates the SQL for this query. Returns the SQL string and list of
parameters.
"""
- assert len(self.query.tables) == 1, \
+ assert len([t for t in self.query.tables if self.query.alias_refcount[t] > 0]) == 1, \
"Can only delete from one table at a time."
qn = self.quote_name_unless_alias
result = ['DELETE FROM %s' % qn(self.query.tables[0])]
diff --git a/django/db/models/sql/query.py b/django/db/models/sql/query.py
index 7a0fe8f..40b6cc5 100644
--- a/django/db/models/sql/query.py
+++ b/django/db/models/sql/query.py
@@ -539,7 +539,8 @@ class Query(object):
# distinct joins for the same connection in rhs query, then the
# combined query must have two joins, too.
reuse.discard(new_alias)
- change_map[alias] = new_alias
+ if alias != new_alias:
+ change_map[alias] = new_alias
if not rhs.alias_refcount[alias]:
# The alias was unused in the rhs query. Unref it so that it
# will be unused in the new query, too. We have to add and
diff --git a/django/db/transaction.py b/django/db/transaction.py
index d138867..d67fd14 100644
--- a/django/db/transaction.py
+++ b/django/db/transaction.py
@@ -156,13 +156,6 @@ class Atomic(ContextDecorator):
raise TransactionManagementError(
"Your database backend doesn't behave properly when "
"autocommit is off. Turn it on before using 'atomic'.")
- # When entering an atomic block with autocommit turned off,
- # Django should only use savepoints and shouldn't commit.
- # This requires at least a savepoint for the outermost block.
- if not self.savepoint:
- raise TransactionManagementError(
- "The outermost 'atomic' block cannot use "
- "savepoint = False when autocommit is off.")
# Pretend we're already in an atomic block to bypass the code
# that disables autocommit to enter a transaction, and make a
# note to deal with this case in __exit__.
diff --git a/django/forms/models.py b/django/forms/models.py
index 08a3697..2137e9f 100644
--- a/django/forms/models.py
+++ b/django/forms/models.py
@@ -405,10 +405,11 @@ class BaseModelForm(BaseForm):
opts = self._meta
exclude = self._get_validation_exclusions()
- # a subset of `exclude` which won't have the InlineForeignKeyField
- # if we're adding a new object since that value doesn't exist
- # until after the new instance is saved to the database.
- construct_instance_exclude = list(exclude)
+
+ try:
+ self.instance = construct_instance(self, self.instance, opts.fields, exclude)
+ except ValidationError as e:
+ self._update_errors(e)
# Foreign Keys being used to represent inline relationships
# are excluded from basic field value validation. This is for two
@@ -419,13 +420,8 @@ class BaseModelForm(BaseForm):
# so this can't be part of _get_validation_exclusions().
for name, field in self.fields.items():
if isinstance(field, InlineForeignKeyField):
- if self.cleaned_data.get(name) is not None and self.cleaned_data[name]._state.adding:
- construct_instance_exclude.append(name)
exclude.append(name)
- # Update the model instance with self.cleaned_data.
- self.instance = construct_instance(self, self.instance, opts.fields, construct_instance_exclude)
-
try:
self.instance.full_clean(exclude=exclude, validate_unique=False)
except ValidationError as e:
diff --git a/django/forms/utils.py b/django/forms/utils.py
index 717c3d0..36cf13c 100644
--- a/django/forms/utils.py
+++ b/django/forms/utils.py
@@ -178,7 +178,7 @@ def from_current_timezone(value):
def to_current_timezone(value):
"""
When time zone support is enabled, convert aware datetimes
- to naive dateimes in the current time zone for display.
+ to naive datetimes in the current time zone for display.
"""
if settings.USE_TZ and value is not None and timezone.is_aware(value):
current_timezone = timezone.get_current_timezone()
diff --git a/django/utils/autoreload.py b/django/utils/autoreload.py
index 5cb7fd0..61804ee 100644
--- a/django/utils/autoreload.py
+++ b/django/utils/autoreload.py
@@ -40,6 +40,8 @@ import traceback
from django.apps import apps
from django.conf import settings
from django.core.signals import request_finished
+from django.utils import six
+from django.utils._os import npath
from django.utils.six.moves import _thread as thread
# This import does nothing, but it's necessary to avoid some race conditions
@@ -74,6 +76,7 @@ I18N_MODIFIED = 2
_mtimes = {}
_win = (sys.platform == "win32")
+_exception = None
_error_files = []
_cached_modules = set()
_cached_filenames = []
@@ -95,7 +98,7 @@ def gen_filenames(only_new=False):
if only_new:
return []
else:
- return _cached_filenames
+ return _cached_filenames + clean_files(_error_files)
new_modules = module_values - _cached_modules
new_filenames = clean_files(
@@ -109,7 +112,7 @@ def gen_filenames(only_new=False):
'conf', 'locale'),
'locale']
for app_config in reversed(list(apps.get_app_configs())):
- basedirs.append(os.path.join(app_config.path, 'locale'))
+ basedirs.append(os.path.join(npath(app_config.path), 'locale'))
basedirs.extend(settings.LOCALE_PATHS)
basedirs = [os.path.abspath(basedir) for basedir in basedirs
if os.path.isdir(basedir)]
@@ -122,7 +125,7 @@ def gen_filenames(only_new=False):
_cached_modules = _cached_modules.union(new_modules)
_cached_filenames += new_filenames
if only_new:
- return new_filenames
+ return new_filenames + clean_files(_error_files)
else:
return _cached_filenames + clean_files(_error_files)
@@ -221,11 +224,13 @@ def code_changed():
def check_errors(fn):
def wrapper(*args, **kwargs):
+ global _exception
try:
fn(*args, **kwargs)
- except (ImportError, IndentationError, NameError, SyntaxError,
- TypeError, AttributeError):
- et, ev, tb = sys.exc_info()
+ except Exception:
+ _exception = sys.exc_info()
+
+ et, ev, tb = _exception
if getattr(ev, 'filename', None) is None:
# get the filename from the last item in the stack
@@ -241,6 +246,12 @@ def check_errors(fn):
return wrapper
+def raise_last_exception():
+ global _exception
+ if _exception is not None:
+ six.reraise(*_exception)
+
+
def ensure_echo_on():
if termios:
fd = sys.stdin
diff --git a/django/utils/functional.py b/django/utils/functional.py
index 81bcb17..a3c0b88 100644
--- a/django/utils/functional.py
+++ b/django/utils/functional.py
@@ -6,7 +6,6 @@ from functools import wraps
from django.utils import six
from django.utils.deprecation import RemovedInDjango19Warning
-from django.utils.six.moves import copyreg
# You can't trivially replace this with `functools.partial` because this binds
@@ -268,32 +267,30 @@ class LazyObject(object):
raise NotImplementedError('subclasses of LazyObject must provide a _setup() method')
# Because we have messed with __class__ below, we confuse pickle as to what
- # class we are pickling. It also appears to stop __reduce__ from being
- # called. So, we define __getstate__ in a way that cooperates with the way
- # that pickle interprets this class. This fails when the wrapped class is
- # a builtin, but it is better than nothing.
- def __getstate__(self):
+ # class we are pickling. We're going to have to initialize the wrapped
+ # object to successfully pickle it, so we might as well just pickle the
+ # wrapped object since they're supposed to act the same way.
+ #
+ # Unfortunately, if we try to simply act like the wrapped object, the ruse
+ # will break down when pickle gets our id(). Thus we end up with pickle
+ # thinking, in effect, that we are a distinct object from the wrapped
+ # object, but with the same __dict__. This can cause problems (see #25389).
+ #
+ # So instead, we define our own __reduce__ method and custom unpickler. We
+ # pickle the wrapped object as the unpickler's argument, so that pickle
+ # will pickle it normally, and then the unpickler simply returns its
+ # argument.
+ def __reduce__(self):
if self._wrapped is empty:
self._setup()
- return self._wrapped.__dict__
-
- # Python 3.3 will call __reduce__ when pickling; this method is needed
- # to serialize and deserialize correctly.
- @classmethod
- def __newobj__(cls, *args):
- return cls.__new__(cls, *args)
-
- def __reduce_ex__(self, proto):
- if proto >= 2:
- # On Py3, since the default protocol is 3, pickle uses the
- # ``__newobj__`` method (& more efficient opcodes) for writing.
- return (self.__newobj__, (self.__class__,), self.__getstate__())
- else:
- # On Py2, the default protocol is 0 (for back-compat) & the above
- # code fails miserably (see regression test). Instead, we return
- # exactly what's returned if there's no ``__reduce__`` method at
- # all.
- return (copyreg._reconstructor, (self.__class__, object, None), self.__getstate__())
+ return (unpickle_lazyobject, (self._wrapped,))
+
+ # We have to explicitly override __getstate__ so that older versions of
+ # pickle don't try to pickle the __dict__ (which in the case of a
+ # SimpleLazyObject may contain a lambda). The value will end up being
+ # ignored by our __reduce__ and custom unpickler.
+ def __getstate__(self):
+ return {}
def __deepcopy__(self, memo):
if self._wrapped is empty:
@@ -332,6 +329,15 @@ class LazyObject(object):
__contains__ = new_method_proxy(operator.contains)
+def unpickle_lazyobject(wrapped):
+ """
+ Used to unpickle lazy objects. Just return its argument, which will be the
+ wrapped object.
+ """
+ return wrapped
+unpickle_lazyobject.__safe_for_unpickling__ = True
+
+
# Workaround for http://bugs.python.org/issue12370
_super = super
diff --git a/django/utils/ipv6.py b/django/utils/ipv6.py
index 94e9dcf..a0675ca 100644
--- a/django/utils/ipv6.py
+++ b/django/utils/ipv6.py
@@ -1,5 +1,5 @@
# This code was mostly based on ipaddr-py
-# Copyright 2007 Google Inc. http://code.google.com/p/ipaddr-py/
+# Copyright 2007 Google Inc. https://github.com/google/ipaddr-py
# Licensed under the Apache License, Version 2.0 (the "License").
from django.core.exceptions import ValidationError
from django.utils.six.moves import range
diff --git a/django/utils/translation/__init__.py b/django/utils/translation/__init__.py
index 505d753..a4c6963 100644
--- a/django/utils/translation/__init__.py
+++ b/django/utils/translation/__init__.py
@@ -163,7 +163,9 @@ class override(ContextDecorator):
deactivate_all()
def __exit__(self, exc_type, exc_value, traceback):
- if self.deactivate:
+ if self.old_language is None:
+ deactivate_all()
+ elif self.deactivate:
deactivate()
else:
activate(self.old_language)
diff --git a/docs/howto/custom-template-tags.txt b/docs/howto/custom-template-tags.txt
index eb5c99c..7e1bfe5 100644
--- a/docs/howto/custom-template-tags.txt
+++ b/docs/howto/custom-template-tags.txt
@@ -20,8 +20,12 @@ create a new app to hold them.
The app should contain a ``templatetags`` directory, at the same level as
``models.py``, ``views.py``, etc. If this doesn't already exist, create it -
don't forget the ``__init__.py`` file to ensure the directory is treated as a
-Python package. After adding this module, you will need to restart your server
-before you can use the tags or filters in templates.
+Python package.
+
+.. admonition:: Development server won't automatically restart
+
+ After adding the ``templatetags`` module, you will need to restart your
+ server before you can use the tags or filters in templates.
Your custom tags and filters will live in a module inside the ``templatetags``
directory. The name of the module file is the name you'll use to load the tags
diff --git a/docs/howto/deployment/wsgi/modwsgi.txt b/docs/howto/deployment/wsgi/modwsgi.txt
index 4e7d627..689effb 100644
--- a/docs/howto/deployment/wsgi/modwsgi.txt
+++ b/docs/howto/deployment/wsgi/modwsgi.txt
@@ -6,7 +6,7 @@ Deploying Django with Apache_ and `mod_wsgi`_ is a tried and tested way to get
Django into production.
.. _Apache: http://httpd.apache.org/
-.. _mod_wsgi: http://code.google.com/p/modwsgi/
+.. _mod_wsgi: http://www.modwsgi.org/
mod_wsgi is an Apache module which can host any Python WSGI_ application,
including Django. Django will work with any version of Apache which supports
@@ -18,8 +18,8 @@ The `official mod_wsgi documentation`_ is fantastic; it's your source for all
the details about how to use mod_wsgi. You'll probably want to start with the
`installation and configuration documentation`_.
-.. _official mod_wsgi documentation: http://code.google.com/p/modwsgi/
-.. _installation and configuration documentation: http://code.google.com/p/modwsgi/wiki/InstallationInstructions
+.. _official mod_wsgi documentation: http://modwsgi.readthedocs.org/
+.. _installation and configuration documentation: http://modwsgi.readthedocs.org/en/develop/installation.html
Basic configuration
===================
diff --git a/docs/howto/static-files/index.txt b/docs/howto/static-files/index.txt
index d05ae6a..7a26994 100644
--- a/docs/howto/static-files/index.txt
+++ b/docs/howto/static-files/index.txt
@@ -1,6 +1,6 @@
-===================================
-Managing static files (CSS, images)
... 2968 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