[Python-modules-commits] [python-django] 01/03: Imported Upstream version 1.7.4
Raphaël Hertzog
hertzog at moszumanska.debian.org
Wed Jan 28 09:18:45 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 bd3fd2fbc27536e52bf6add0bee647402539b5f6
Author: Raphaël Hertzog <hertzog at debian.org>
Date: Wed Jan 28 09:36:42 2015 +0100
Imported Upstream version 1.7.4
---
Django.egg-info/PKG-INFO | 2 +-
Django.egg-info/SOURCES.txt | 3 +
PKG-INFO | 2 +-
django/__init__.py | 2 +-
django/contrib/auth/management/__init__.py | 5 +
django/contrib/auth/tests/test_management.py | 20 +++-
django/contrib/contenttypes/management.py | 5 +
django/contrib/contenttypes/tests/tests.py | 23 +++-
django/contrib/sessions/tests.py | 5 +-
django/db/backends/schema.py | 29 +++--
django/db/backends/sqlite3/schema.py | 9 +-
django/db/migrations/loader.py | 12 +++
django/db/migrations/operations/models.py | 21 ++++
django/http/__init__.py | 5 +-
django/http/response.py | 18 ++++
django/views/static.py | 8 +-
docs/howto/custom-management-commands.txt | 14 ++-
docs/internals/deprecation.txt | 35 ++++--
docs/internals/release-process.txt | 6 +-
docs/intro/tutorial01.txt | 12 +--
docs/intro/tutorial03.txt | 2 +-
docs/ref/contrib/admin/index.txt | 4 +-
docs/ref/contrib/contenttypes.txt | 25 +++--
docs/ref/contrib/sites.txt | 10 +-
docs/ref/models/querysets.txt | 19 ++--
docs/ref/utils.txt | 12 ++-
docs/releases/1.4.19.txt | 16 +++
docs/releases/1.7.4.txt | 26 +++++
docs/releases/1.7.txt | 36 ++++++-
docs/releases/index.txt | 2 +
docs/topics/http/shortcuts.txt | 4 +-
docs/topics/http/views.txt | 7 +-
docs/topics/testing/tools.txt | 2 +-
setup.cfg | 2 +-
tests/i18n/test_extraction.py | 7 +-
tests/migrations/test_operations.py | 26 +++++
tests/migrations/test_writer.py | 112 +++++++++-----------
tests/model_regress/tests.py | 18 ++--
tests/requests/tests.py | 3 +-
tests/schema/fields.py | 54 ++++++++++
tests/schema/models.py | 10 ++
tests/schema/tests.py | 153 ++++++++++++++++++++++++++-
tests/view_tests/tests/test_static.py | 10 +-
43 files changed, 627 insertions(+), 169 deletions(-)
diff --git a/Django.egg-info/PKG-INFO b/Django.egg-info/PKG-INFO
index acf7c27..9665a62 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.7.3
+Version: 1.7.4
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 92cd27d..1b23ece 100644
--- a/Django.egg-info/SOURCES.txt
+++ b/Django.egg-info/SOURCES.txt
@@ -3982,6 +3982,7 @@ docs/releases/1.4.15.txt
docs/releases/1.4.16.txt
docs/releases/1.4.17.txt
docs/releases/1.4.18.txt
+docs/releases/1.4.19.txt
docs/releases/1.4.2.txt
docs/releases/1.4.3.txt
docs/releases/1.4.4.txt
@@ -4018,6 +4019,7 @@ docs/releases/1.6.txt
docs/releases/1.7.1.txt
docs/releases/1.7.2.txt
docs/releases/1.7.3.txt
+docs/releases/1.7.4.txt
docs/releases/1.7.txt
docs/releases/index.txt
docs/releases/security.txt
@@ -4986,6 +4988,7 @@ tests/save_delete_hooks/__init__.py
tests/save_delete_hooks/models.py
tests/save_delete_hooks/tests.py
tests/schema/__init__.py
+tests/schema/fields.py
tests/schema/models.py
tests/schema/tests.py
tests/select_for_update/__init__.py
diff --git a/PKG-INFO b/PKG-INFO
index acf7c27..9665a62 100644
--- a/PKG-INFO
+++ b/PKG-INFO
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: Django
-Version: 1.7.3
+Version: 1.7.4
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 424dc1f..6b6cd79 100644
--- a/django/__init__.py
+++ b/django/__init__.py
@@ -1,4 +1,4 @@
-VERSION = (1, 7, 3, 'final', 0)
+VERSION = (1, 7, 4, 'final', 0)
def get_version(*args, **kwargs):
diff --git a/django/contrib/auth/management/__init__.py b/django/contrib/auth/management/__init__.py
index 18cdcce..683a8d5 100644
--- a/django/contrib/auth/management/__init__.py
+++ b/django/contrib/auth/management/__init__.py
@@ -11,6 +11,7 @@ from django.contrib.auth import models as auth_app, get_permission_codename
from django.core import exceptions
from django.core.management.base import CommandError
from django.db import DEFAULT_DB_ALIAS, router
+from django.db.migrations.loader import is_latest_migration_applied
from django.db.models import signals
from django.utils.encoding import DEFAULT_LOCALE_ENCODING
from django.utils import six
@@ -59,6 +60,10 @@ def _check_permission_clashing(custom, builtin, ctype):
def create_permissions(app_config, verbosity=2, interactive=True, using=DEFAULT_DB_ALIAS, **kwargs):
+ # TODO: Remove when migration plan / state is passed (#24100).
+ if not is_latest_migration_applied('auth'):
+ return
+
if not app_config.models_module:
return
diff --git a/django/contrib/auth/tests/test_management.py b/django/contrib/auth/tests/test_management.py
index 7fd41b9..a807aca 100644
--- a/django/contrib/auth/tests/test_management.py
+++ b/django/contrib/auth/tests/test_management.py
@@ -17,7 +17,7 @@ from django.core import checks
from django.core import exceptions
from django.core.management import call_command
from django.core.management.base import CommandError
-from django.test import TestCase, override_settings, override_system_checks
+from django.test import TestCase, override_settings, override_system_checks, skipUnlessDBFeature
from django.utils import six
from django.utils.encoding import force_str
@@ -506,3 +506,21 @@ class PermissionTestCase(TestCase):
six.assertRaisesRegex(self, exceptions.ValidationError,
"The verbose_name of permission is longer than 39 characters",
create_permissions, auth_app_config, verbosity=0)
+
+
+class MigrateTests(TestCase):
+
+ @skipUnlessDBFeature('can_rollback_ddl')
+ def test_unmigrating_first_migration_post_migrate_signal(self):
+ """
+ #24075 - When unmigrating an app before its first migration,
+ post_migrate signal handler must be aware of the missing tables.
+ """
+ try:
+ with override_settings(
+ INSTALLED_APPS=["django.contrib.auth", "django.contrib.contenttypes"],
+ MIGRATION_MODULES={'auth': 'django.contrib.auth.migrations'},
+ ):
+ call_command("migrate", "auth", "zero", verbosity=0)
+ finally:
+ call_command("migrate", verbosity=0)
diff --git a/django/contrib/contenttypes/management.py b/django/contrib/contenttypes/management.py
index f705330..91984a8 100644
--- a/django/contrib/contenttypes/management.py
+++ b/django/contrib/contenttypes/management.py
@@ -1,5 +1,6 @@
from django.apps import apps
from django.db import DEFAULT_DB_ALIAS, router
+from django.db.migrations.loader import is_latest_migration_applied
from django.db.models import signals
from django.utils.encoding import smart_text
from django.utils import six
@@ -11,6 +12,10 @@ def update_contenttypes(app_config, verbosity=2, interactive=True, using=DEFAULT
Creates content types for models in the given app, removing any model
entries that no longer have a matching model class.
"""
+ # TODO: Remove when migration plan / state is passed (#24100).
+ if not is_latest_migration_applied('contenttypes'):
+ return
+
if not app_config.models_module:
return
diff --git a/django/contrib/contenttypes/tests/tests.py b/django/contrib/contenttypes/tests/tests.py
index 924ffdc..dc3e8ba 100644
--- a/django/contrib/contenttypes/tests/tests.py
+++ b/django/contrib/contenttypes/tests/tests.py
@@ -3,8 +3,10 @@ from __future__ import unicode_literals
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes.views import shortcut
from django.contrib.sites.shortcuts import get_current_site
+from django.core.management import call_command
from django.http import HttpRequest, Http404
-from django.test import TestCase, override_settings
+from django.test import TestCase, override_settings, skipUnlessDBFeature
+from django.test.utils import override_system_checks
from django.utils import six
from .models import ConcreteModel, ProxyModel, FooWithoutUrl, FooWithUrl, FooWithBrokenAbsoluteUrl
@@ -241,3 +243,22 @@ class ContentTypesTests(TestCase):
# Instead, just return the ContentType object and let the app detect stale states.
ct_fetched = ContentType.objects.get_for_id(ct.pk)
self.assertIsNone(ct_fetched.model_class())
+
+
+class MigrateTests(TestCase):
+
+ @skipUnlessDBFeature('can_rollback_ddl')
+ @override_system_checks([])
+ def test_unmigrating_first_migration_post_migrate_signal(self):
+ """
+ #24075 - When unmigrating an app before its first migration,
+ post_migrate signal handler must be aware of the missing tables.
+ """
+ try:
+ with override_settings(
+ INSTALLED_APPS=["django.contrib.contenttypes"],
+ MIGRATION_MODULES={'contenttypes': 'django.contrib.contenttypes.migrations'},
+ ):
+ call_command("migrate", "contenttypes", "zero", verbosity=0)
+ finally:
+ call_command("migrate", verbosity=0)
diff --git a/django/contrib/sessions/tests.py b/django/contrib/sessions/tests.py
index 8cda7ea..8d63aaa 100644
--- a/django/contrib/sessions/tests.py
+++ b/django/contrib/sessions/tests.py
@@ -24,6 +24,7 @@ from django.test import TestCase, RequestFactory, override_settings
from django.test.utils import patch_logger
from django.utils import six
from django.utils import timezone
+from django.utils.six.moves import http_cookies
from django.contrib.sessions.exceptions import InvalidSessionKey
@@ -532,7 +533,7 @@ class SessionMiddlewareTests(unittest.TestCase):
response = middleware.process_response(request, response)
self.assertTrue(
response.cookies[settings.SESSION_COOKIE_NAME]['httponly'])
- self.assertIn('httponly',
+ self.assertIn(http_cookies.Morsel._reserved['httponly'],
str(response.cookies[settings.SESSION_COOKIE_NAME]))
@override_settings(SESSION_COOKIE_HTTPONLY=False)
@@ -549,7 +550,7 @@ class SessionMiddlewareTests(unittest.TestCase):
response = middleware.process_response(request, response)
self.assertFalse(response.cookies[settings.SESSION_COOKIE_NAME]['httponly'])
- self.assertNotIn('httponly',
+ self.assertNotIn(http_cookies.Morsel._reserved['httponly'],
str(response.cookies[settings.SESSION_COOKIE_NAME]))
def test_session_save_on_500(self):
diff --git a/django/db/backends/schema.py b/django/db/backends/schema.py
index f13bde8..12e2ab7 100644
--- a/django/db/backends/schema.py
+++ b/django/db/backends/schema.py
@@ -3,7 +3,6 @@ import operator
from django.db.backends.creation import BaseDatabaseCreation
from django.db.backends.utils import truncate_name
-from django.db.models.fields.related import ManyToManyField
from django.db.transaction import atomic
from django.utils.encoding import force_bytes
from django.utils.log import getLogger
@@ -359,7 +358,7 @@ class BaseDatabaseSchemaEditor(object):
table instead (for M2M fields)
"""
# Special-case implicit M2M tables
- if isinstance(field, ManyToManyField) and field.rel.through._meta.auto_created:
+ if field.get_internal_type() == 'ManyToManyField' and field.rel.through._meta.auto_created:
return self.create_model(field.rel.through)
# Get the column's definition
definition, params = self.column_sql(model, field, include_default=True)
@@ -403,7 +402,7 @@ class BaseDatabaseSchemaEditor(object):
but for M2Ms may involve deleting a table.
"""
# Special-case implicit M2M tables
- if isinstance(field, ManyToManyField) and field.rel.through._meta.auto_created:
+ if field.get_internal_type() == 'ManyToManyField' and field.rel.through._meta.auto_created:
return self.delete_model(field.rel.through)
# It might not actually have a column behind it
if field.db_parameters(connection=self.connection)['type'] is None:
@@ -457,18 +456,6 @@ class BaseDatabaseSchemaEditor(object):
def _alter_field(self, model, old_field, new_field, old_type, new_type, old_db_params, new_db_params, strict=False):
"""Actually perform a "physical" (non-ManyToMany) field update."""
- # Has unique been removed?
- if old_field.unique and (not new_field.unique or (not old_field.primary_key and new_field.primary_key)):
- # Find the unique constraint for this field
- constraint_names = self._constraint_names(model, [old_field.column], unique=True)
- if strict and len(constraint_names) != 1:
- raise ValueError("Found wrong number (%s) of unique constraints for %s.%s" % (
- len(constraint_names),
- model._meta.db_table,
- old_field.column,
- ))
- for constraint_name in constraint_names:
- self.execute(self._delete_constraint_sql(self.sql_delete_unique, model, constraint_name))
# Drop any FK constraints, we'll remake them later
fks_dropped = set()
if old_field.rel and old_field.db_constraint:
@@ -482,6 +469,18 @@ class BaseDatabaseSchemaEditor(object):
for fk_name in fk_names:
fks_dropped.add((old_field.column,))
self.execute(self._delete_constraint_sql(self.sql_delete_fk, model, fk_name))
+ # Has unique been removed?
+ if old_field.unique and (not new_field.unique or (not old_field.primary_key and new_field.primary_key)):
+ # Find the unique constraint for this field
+ constraint_names = self._constraint_names(model, [old_field.column], unique=True)
+ if strict and len(constraint_names) != 1:
+ raise ValueError("Found wrong number (%s) of unique constraints for %s.%s" % (
+ len(constraint_names),
+ model._meta.db_table,
+ old_field.column,
+ ))
+ for constraint_name in constraint_names:
+ self.execute(self._delete_constraint_sql(self.sql_delete_unique, model, constraint_name))
# Drop incoming FK constraints if we're a primary key and things are going
# to change.
if old_field.primary_key and new_field.primary_key and old_type != new_type:
diff --git a/django/db/backends/sqlite3/schema.py b/django/db/backends/sqlite3/schema.py
index 73c70ef..c5f56a0 100644
--- a/django/db/backends/sqlite3/schema.py
+++ b/django/db/backends/sqlite3/schema.py
@@ -4,7 +4,6 @@ from decimal import Decimal
from django.utils import six
from django.apps.registry import Apps
from django.db.backends.schema import BaseDatabaseSchemaEditor
-from django.db.models.fields.related import ManyToManyField
class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
@@ -70,7 +69,7 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
for field in create_fields:
body[field.name] = field
# Choose a default and insert it into the copy map
- if not isinstance(field, ManyToManyField):
+ if not field.get_internal_type() == 'ManyToManyField':
mapping[field.column] = self.quote_value(
self.effective_default(field)
)
@@ -93,7 +92,7 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
del body[field.name]
del mapping[field.column]
# Remove any implicit M2M tables
- if isinstance(field, ManyToManyField) and field.rel.through._meta.auto_created:
+ if field.get_internal_type() == 'ManyToManyField' and field.rel.through._meta.auto_created:
return self.delete_model(field.rel.through)
# Work inside a new app registry
apps = Apps()
@@ -172,7 +171,7 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
table instead (for M2M fields)
"""
# Special-case implicit M2M tables
- if isinstance(field, ManyToManyField) and field.rel.through._meta.auto_created:
+ if field.get_internal_type() == 'ManyToManyField' and field.rel.through._meta.auto_created:
return self.create_model(field.rel.through)
self._remake_table(model, create_fields=[field])
@@ -182,7 +181,7 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
but for M2Ms may involve deleting a table.
"""
# M2M fields are a special case
- if isinstance(field, ManyToManyField):
+ if field.get_internal_type() == 'ManyToManyField':
# For implicit M2M tables, delete the auto-created table
if field.rel.through._meta.auto_created:
self.delete_model(field.rel.through)
diff --git a/django/db/migrations/loader.py b/django/db/migrations/loader.py
index 923202a..b700616 100644
--- a/django/db/migrations/loader.py
+++ b/django/db/migrations/loader.py
@@ -5,6 +5,7 @@ import os
import sys
from django.apps import apps
+from django.db import connection
from django.db.migrations.recorder import MigrationRecorder
from django.db.migrations.graph import MigrationGraph
from django.utils import six
@@ -284,3 +285,14 @@ class AmbiguityError(Exception):
Raised when more than one migration matches a name prefix
"""
pass
+
+
+def is_latest_migration_applied(app_label):
+ # TODO: Remove when migration plan / state is passed (#24100).
+ loader = MigrationLoader(connection)
+ loader.load_disk()
+ leaf_nodes = loader.graph.leaf_nodes(app=app_label)
+ return (
+ leaf_nodes and leaf_nodes[0] in loader.applied_migrations or
+ app_label in loader.unmigrated_apps
+ )
diff --git a/django/db/migrations/operations/models.py b/django/db/migrations/operations/models.py
index bb7f11d..3d92b68 100644
--- a/django/db/migrations/operations/models.py
+++ b/django/db/migrations/operations/models.py
@@ -171,6 +171,27 @@ class RenameModel(Operation):
related_object.field,
to_field,
)
+ # Rename M2M fields whose name is based on this model's name.
+ fields = zip(old_model._meta.local_many_to_many, new_model._meta.local_many_to_many)
+ for (old_field, new_field) in fields:
+ # Skip self-referential fields as these are renamed above.
+ if new_field.model == new_field.related.parent_model or not new_field.rel.through._meta.auto_created:
+ continue
+ # Rename the M2M table that's based on this model's name.
+ old_m2m_model = old_field.rel.through
+ new_m2m_model = new_field.rel.through
+ schema_editor.alter_db_table(
+ new_m2m_model,
+ old_m2m_model._meta.db_table,
+ new_m2m_model._meta.db_table,
+ )
+ # Rename the column in the M2M table that's based on this
+ # model's name.
+ schema_editor.alter_field(
+ new_m2m_model,
+ old_m2m_model._meta.get_field(old_model._meta.model_name),
+ new_m2m_model._meta.get_field(new_model._meta.model_name),
+ )
def database_backwards(self, app_label, schema_editor, from_state, to_state):
self.new_name, self.old_name = self.old_name, self.new_name
diff --git a/django/http/__init__.py b/django/http/__init__.py
index fc5bd18..99a5233 100644
--- a/django/http/__init__.py
+++ b/django/http/__init__.py
@@ -1,7 +1,8 @@
from django.http.cookie import SimpleCookie, parse_cookie
from django.http.request import (HttpRequest, QueryDict,
RawPostDataException, UnreadablePostError, build_request_repr)
-from django.http.response import (HttpResponse, StreamingHttpResponse,
+from django.http.response import (
+ HttpResponse, StreamingHttpResponse, FileResponse,
HttpResponseRedirect, HttpResponsePermanentRedirect,
HttpResponseNotModified, HttpResponseBadRequest, HttpResponseForbidden,
HttpResponseNotFound, HttpResponseNotAllowed, HttpResponseGone,
@@ -16,5 +17,5 @@ __all__ = [
'HttpResponseBadRequest', 'HttpResponseForbidden', 'HttpResponseNotFound',
'HttpResponseNotAllowed', 'HttpResponseGone', 'HttpResponseServerError',
'Http404', 'BadHeaderError', 'fix_location_header', 'JsonResponse',
- 'conditional_content_removal',
+ 'FileResponse', 'conditional_content_removal',
]
diff --git a/django/http/response.py b/django/http/response.py
index b3f44cd..06126ed 100644
--- a/django/http/response.py
+++ b/django/http/response.py
@@ -382,6 +382,9 @@ class StreamingHttpResponse(HttpResponseBase):
@streaming_content.setter
def streaming_content(self, value):
+ self._set_streaming_content(value)
+
+ def _set_streaming_content(self, value):
# Ensure we can never iterate on "value" more than once.
self._iterator = iter(value)
if hasattr(value, 'close'):
@@ -391,6 +394,21 @@ class StreamingHttpResponse(HttpResponseBase):
return self.streaming_content
+class FileResponse(StreamingHttpResponse):
+ """
+ A streaming HTTP response class optimized for files.
+ """
+ block_size = 4096
+
+ def _set_streaming_content(self, value):
+ if hasattr(value, 'read'):
+ self._iterator = iter(lambda: value.read(self.block_size), b'')
+ if hasattr(value, 'close'):
+ self._closable_objects.append(value)
+ else:
+ super(FileResponse, self)._set_streaming_content(value)
+
+
class HttpResponseRedirectBase(HttpResponse):
allowed_schemes = ['http', 'https', 'ftp']
diff --git a/django/views/static.py b/django/views/static.py
index 0ce00a9..19f57b7 100644
--- a/django/views/static.py
+++ b/django/views/static.py
@@ -11,14 +11,12 @@ import posixpath
import re
from django.http import (Http404, HttpResponse, HttpResponseRedirect,
- HttpResponseNotModified, StreamingHttpResponse)
+ HttpResponseNotModified, FileResponse)
from django.template import loader, Template, Context, TemplateDoesNotExist
from django.utils.http import http_date, parse_http_date
from django.utils.six.moves.urllib.parse import unquote
from django.utils.translation import ugettext as _, ugettext_lazy
-STREAM_CHUNK_SIZE = 4096
-
def serve(request, path, document_root=None, show_indexes=False):
"""
@@ -63,9 +61,7 @@ def serve(request, path, document_root=None, show_indexes=False):
return HttpResponseNotModified()
content_type, encoding = mimetypes.guess_type(fullpath)
content_type = content_type or 'application/octet-stream'
- f = open(fullpath, 'rb')
- response = StreamingHttpResponse(iter(lambda: f.read(STREAM_CHUNK_SIZE), b''),
- content_type=content_type)
+ response = FileResponse(open(fullpath, 'rb'), content_type=content_type)
response["Last-Modified"] = http_date(statobj.st_mtime)
if stat.S_ISREG(statobj.st_mode):
response["Content-Length"] = statobj.st_size
diff --git a/docs/howto/custom-management-commands.txt b/docs/howto/custom-management-commands.txt
index 17fb74d..e477ee2 100644
--- a/docs/howto/custom-management-commands.txt
+++ b/docs/howto/custom-management-commands.txt
@@ -303,17 +303,15 @@ the :meth:`~BaseCommand.handle` method must be implemented.
.. method:: BaseCommand.get_version()
- Return the Django version, which should be correct for all
- built-in Django commands. User-supplied commands can
- override this method to return their own version.
+ Returns the Django version, which should be correct for all built-in Django
+ commands. User-supplied commands can override this method to return their
+ own version.
.. method:: BaseCommand.execute(*args, **options)
- Try to execute this command, performing model validation if
- needed (as controlled by the attribute
- :attr:`requires_model_validation`). If the command raises a
- :class:`CommandError`, intercept it and print it sensibly to
- stderr.
+ Tries to execute this command, performing system checks if needed (as
+ controlled by the :attr:`requires_system_checks` attribute). If the command
+ raises a :class:`CommandError`, it's intercepted and printed to stderr.
.. admonition:: Calling a management command in your code
diff --git a/docs/internals/deprecation.txt b/docs/internals/deprecation.txt
index 0b8d8c7..252db52 100644
--- a/docs/internals/deprecation.txt
+++ b/docs/internals/deprecation.txt
@@ -46,8 +46,8 @@ details on these changes.
* ``AppCommand.handle_app()`` will no longer be supported.
-* ``RequestSite`` will be located in ``django.contrib.sites.requests`` and
- ``get_current_site`` in ``django.contrib.sites.shortcuts``.
+* ``RequestSite`` and ``get_current_site()`` will no longer be importable from
+ ``django.contrib.sites.models``.
* FastCGI support via the ``runfcgi`` management command will be
removed. Please deploy your project using WSGI.
@@ -68,9 +68,9 @@ details on these changes.
* ``ModelAdmin.get_formsets`` will be removed.
-* Remove the backward compatible shims introduced to rename the
+* The backward compatibility shim introduced to rename the
``BaseMemcachedCache._get_memcache_timeout()`` method to
- ``get_backend_timeout()``.
+ ``get_backend_timeout()`` will be removed.
* The ``--natural`` and ``-n`` options for :djadmin:`dumpdata` will be removed.
Use :djadminopt:`--natural-foreign` instead.
@@ -78,7 +78,7 @@ details on these changes.
* The ``use_natural_keys`` argument for ``serializers.serialize()`` will be
removed. Use ``use_natural_foreign_keys`` instead.
-* ``django.forms.get_declared_fields`` will be removed.
+* Private API ``django.forms.forms.get_declared_fields()`` will be removed.
* The ability to use a ``SplitDateTimeWidget`` with ``DateTimeField`` will be
removed.
@@ -103,12 +103,16 @@ details on these changes.
``requires_system_checks``. Admin validators will be replaced by admin
checks.
-* ``ModelAdmin.validator`` will be removed in favor of the new ``checks``
- attribute.
+* The ``ModelAdmin.validator_class`` and ``default_validator_class`` attributes
+ will be removed.
+
+* ``ModelAdmin.validate()`` will be removed.
* ``django.db.backends.DatabaseValidation.validate_field`` will be removed in
favor of the ``check_field`` method.
+* The ``check`` management command will be removed.
+
* ``django.utils.module_loading.import_by_path`` will be removed in favor of
``django.utils.module_loading.import_string``.
@@ -120,6 +124,23 @@ details on these changes.
* Database test settings as independent entries in the database settings,
prefixed by ``TEST_``, will no longer be supported.
+* The `cache_choices` option to :class:`~django.forms.ModelChoiceField` and
+ :class:`~django.forms.ModelMultipleChoiceField` will be removed.
+
+* The default value of the
+ :attr:`RedirectView.permanent <django.views.generic.base.RedirectView.permanent>`
+ attribute will change from ``True`` to ``False``.
+
+* ``django.contrib.sitemaps.FlatPageSitemap`` will be removed in favor of
+ ``django.contrib.flatpages.sitemaps.FlatPageSitemap``.
+
+* Private API ``django.test.utils.TestTemplateLoader`` will be removed.
+
+* The ``django.contrib.contenttypes.generic`` module will be removed.
+
+* Private APIs ``django.db.models.sql.where.WhereNode.make_atom()`` and
+ ``django.db.models.sql.where.Constraint`` will be removed.
+
.. _deprecation-removed-in-1.8:
1.8
diff --git a/docs/internals/release-process.txt b/docs/internals/release-process.txt
index 3b6500e..180c3dc 100644
--- a/docs/internals/release-process.txt
+++ b/docs/internals/release-process.txt
@@ -134,7 +134,11 @@ regardless of the pace of releases afterwards.
The follow releases have been designated for long-term support:
-* Django 1.4, supported until at least March 2015.
+* Django 1.8, supported for at least 3 years after its release (scheduled for
+ April 2015).
+* Django 1.4, supported for 6 months after the release of Django 1.8. As
+ Django 1.8 is scheduled to be released around April 2015, support for 1.4
+ will end around October 2015.
.. _release-process:
diff --git a/docs/intro/tutorial01.txt b/docs/intro/tutorial01.txt
index 357ff33..4a57711 100644
--- a/docs/intro/tutorial01.txt
+++ b/docs/intro/tutorial01.txt
@@ -544,18 +544,10 @@ Now, run :djadmin:`migrate` again to create those model tables in your database:
.. code-block:: bash
$ python manage.py migrate
-
Operations to perform:
- Synchronize unmigrated apps: sessions, admin, messages, auth, staticfiles, contenttypes
- Apply all migrations: polls
- Synchronizing apps without migrations:
- Creating tables...
- Installing custom SQL...
- Installing indexes...
- Installed 0 object(s) from 0 fixture(s)
+ Apply all migrations: admin, contenttypes, polls, auth, sessions
Running migrations:
- Applying polls.0001_initial... OK
-
+ Applying <migration name>... OK
The :djadmin:`migrate` command takes all the migrations that haven't been
applied (Django tracks which ones are applied using a special table in your
diff --git a/docs/intro/tutorial03.txt b/docs/intro/tutorial03.txt
index 59e68ef..95f0dca 100644
--- a/docs/intro/tutorial03.txt
+++ b/docs/intro/tutorial03.txt
@@ -441,7 +441,7 @@ for a given poll. Here's the view:
try:
question = Question.objects.get(pk=question_id)
except Question.DoesNotExist:
- raise Http404
+ raise Http404("Question does not exist")
return render(request, 'polls/detail.html', {'question': question})
The new concept here: The view raises the :exc:`~django.http.Http404` exception
diff --git a/docs/ref/contrib/admin/index.txt b/docs/ref/contrib/admin/index.txt
index ea00cb3..d1585b9 100644
--- a/docs/ref/contrib/admin/index.txt
+++ b/docs/ref/contrib/admin/index.txt
@@ -668,7 +668,7 @@ subclass::
.. versionadded:: 1.7
- To indicate descending order with ``admin_model_field`` you can use a
+ To indicate descending order with ``admin_order_field`` you can use a
hyphen prefix on the field name. Using the above example, this would
look like::
@@ -1517,6 +1517,8 @@ templates used by the :class:`ModelAdmin` views:
.. method:: ModelAdmin.get_formsets_with_inlines(request, obj=None)
+ .. versionadded:: 1.7
+
Yields (``FormSet``, :class:`InlineModelAdmin`) pairs for use in admin add
and change views.
diff --git a/docs/ref/contrib/contenttypes.txt b/docs/ref/contrib/contenttypes.txt
index 37db9f1..eaa5531 100644
--- a/docs/ref/contrib/contenttypes.txt
+++ b/docs/ref/contrib/contenttypes.txt
@@ -300,10 +300,11 @@ model:
is ``True``. This mirrors the ``for_concrete_model`` argument to
:meth:`~django.contrib.contenttypes.models.ContentTypeManager.get_for_model`.
- .. versionchanged:: 1.7
+ .. deprecated:: 1.7
This class used to be defined in ``django.contrib.contenttypes.generic``.
-
+ Support for importing from this old location will be removed in Django
+ 1.9.
.. admonition:: Primary key type compatibility
@@ -369,9 +370,11 @@ Reverse generic relations
.. class:: GenericRelation
- .. versionchanged:: 1.7
+ .. deprecated:: 1.7
This class used to be defined in ``django.contrib.contenttypes.generic``.
+ Support for importing from this old location will be removed in Django
+ 1.9.
.. attribute:: related_query_name
@@ -496,9 +499,11 @@ The :mod:`django.contrib.contenttypes.forms` module provides:
.. class:: BaseGenericInlineFormSet
- .. versionchanged:: 1.7
+ .. deprecated:: 1.7
This class used to be defined in ``django.contrib.contenttypes.generic``.
+ Support for importing from this old location will be removed in Django
+ 1.9.
.. function:: generic_inlineformset_factory(model, form=ModelForm, formset=BaseGenericInlineFormSet, ct_field="content_type", fk_field="object_id", fields=None, exclude=None, extra=3, can_order=False, can_delete=True, max_num=None, formfield_callback=None, validate_max=False, for_concrete_model=True, min_num=None, validate_min=False)
@@ -517,9 +522,11 @@ The :mod:`django.contrib.contenttypes.forms` module provides:
:class:`~django.contrib.contenttypes.fields.GenericForeignKey.for_concrete_model`
argument on ``GenericForeignKey``.
- .. versionchanged:: 1.7
+ .. deprecated:: 1.7
This function used to be defined in ``django.contrib.contenttypes.generic``.
+ Support for importing from this old location will be removed in Django
+ 1.9.
.. versionchanged:: 1.7
@@ -559,9 +566,11 @@ information.
The name of the integer field that represents the ID of the related
object. Defaults to ``object_id``.
- .. versionchanged:: 1.7
+ .. deprecated:: 1.7
This class used to be defined in ``django.contrib.contenttypes.generic``.
+ Support for importing from this old location will be removed in Django
+ 1.9.
.. class:: GenericTabularInline
.. class:: GenericStackedInline
@@ -569,6 +578,8 @@ information.
Subclasses of :class:`GenericInlineModelAdmin` with stacked and tabular
layouts, respectively.
- .. versionchanged:: 1.7
+ .. deprecated:: 1.7
These classes used to be defined in ``django.contrib.contenttypes.generic``.
+ Support for importing from this old location will be removed in Django
+ 1.9.
diff --git a/docs/ref/contrib/sites.txt b/docs/ref/contrib/sites.txt
index b3f33c8..6f406e6 100644
--- a/docs/ref/contrib/sites.txt
+++ b/docs/ref/contrib/sites.txt
@@ -84,7 +84,7 @@ This accomplishes several things quite nicely:
try:
a = Article.objects.get(id=article_id, sites__id=get_current_site(request).id)
except Article.DoesNotExist:
- raise Http404
+ raise Http404("Article does not exist on this site")
# ...
.. _ljworld.com: http://www.ljworld.com/
@@ -473,9 +473,10 @@ a fallback when the database-backed sites framework is not available.
Sets the ``name`` and ``domain`` attributes to the value of
:meth:`~django.http.HttpRequest.get_host`.
- .. versionchanged:: 1.7
+ .. deprecated:: 1.7
- This class used to be defined in ``django.contrib.sites.models``.
+ This class used to be defined in ``django.contrib.sites.models``. The
+ old import location will work until Django 1.9.
A :class:`~django.contrib.sites.requests.RequestSite` object has a similar
interface to a normal :class:`~django.contrib.sites.models.Site` object,
@@ -499,6 +500,7 @@ Finally, to avoid repetitive fallback code, the framework provides a
object or a :class:`~django.contrib.sites.requests.RequestSite` object
based on the request.
- .. versionchanged:: 1.7
+ .. deprecated:: 1.7
This function used to be defined in ``django.contrib.sites.models``.
+ The old import location will work until Django 1.9.
diff --git a/docs/ref/models/querysets.txt b/docs/ref/models/querysets.txt
index ee7ea77..6d12389 100644
--- a/docs/ref/models/querysets.txt
+++ b/docs/ref/models/querysets.txt
@@ -57,11 +57,10 @@ You can evaluate a ``QuerySet`` in the following ways:
* **len().** A ``QuerySet`` is evaluated when you call ``len()`` on it.
This, as you might expect, returns the length of the result list.
- Note: *Don't* use ``len()`` on ``QuerySet``\s if all you want to do is
- determine the number of records in the set. It's much more efficient to
- handle a count at the database level, using SQL's ``SELECT COUNT(*)``,
- and Django provides a ``count()`` method for precisely this reason. See
- ``count()`` below.
+ Note: If you only need to determine the number of records in the set (and
+ don't need the actual objects), it's much more efficient to handle a count
+ at the database level using SQL's ``SELECT COUNT(*)``. Django provides a
+ :meth:`~QuerySet.count` method for precisely this reason.
* **list().** Force evaluation of a ``QuerySet`` by calling ``list()`` on
it. For example::
@@ -76,9 +75,8 @@ You can evaluate a ``QuerySet`` in the following ways:
if Entry.objects.filter(headline="Test"):
print("There is at least one Entry with the headline Test")
- Note: *Don't* use this if all you want to do is determine if at least one
- result exists, and don't need the actual objects. It's more efficient to
- use :meth:`~QuerySet.exists` (see below).
+ Note: If you only want to determine if at least one result exists (and don't
+ need the actual objects), it's more efficient to use :meth:`~QuerySet.exists`.
.. _pickling QuerySets:
@@ -1776,6 +1774,11 @@ Depending on which database you're using (e.g. PostgreSQL vs. MySQL),
is an underlying implementation quirk that shouldn't pose any real-world
problems.
+Note that if you want the number of items in a ``QuerySet`` and are also
+retrieving model instances from it (for example, by iterating over it), it's
+probably more efficient to use ``len(queryset)`` which won't cause an extra
+database query like ``count()`` would.
+
in_bulk
~~~~~~~
diff --git a/docs/ref/utils.txt b/docs/ref/utils.txt
index 1ecb8ee..335ad3a 100644
--- a/docs/ref/utils.txt
+++ b/docs/ref/utils.txt
@@ -155,7 +155,7 @@ The functions defined in this module share the following properties:
Parses a string and returns a :class:`datetime.datetime`.
UTC offsets are supported; if ``value`` describes one, the result's
- ``tzinfo`` attribute is a :class:`~django.utils.tzinfo.FixedOffset`
+ ``tzinfo`` attribute is a :class:`~django.utils.timezone.FixedOffset`
instance.
``django.utils.decorators``
@@ -790,6 +790,9 @@ appropriate entities.
Can be called multiple times on a single string.
+ For building up fragments of HTML, you should normally be using
+ :func:`django.utils.html.format_html` instead.
+
String marked safe will become unsafe again if modified. For example::
>>> mystr = '<b>Hello World</b> '
@@ -840,6 +843,13 @@ appropriate entities.
:class:`~datetime.tzinfo` instance that represents UTC.
+.. class:: FixedOffset(offset=None, name=None)
+
+ .. versionadded:: 1.7
+
+ A :class:`~datetime.tzinfo` subclass modeling a fixed offset from UTC.
+ ``offset`` is an integer number of minutes east of UTC.
+
.. function:: get_fixed_timezone(offset)
.. versionadded:: 1.7
diff --git a/docs/releases/1.4.19.txt b/docs/releases/1.4.19.txt
new file mode 100644
index 0000000..992fc6c
--- /dev/null
+++ b/docs/releases/1.4.19.txt
@@ -0,0 +1,16 @@
+===========================
+Django 1.4.19 release notes
+===========================
+
+*January 27, 2015*
+
+Django 1.4.19 fixes a regression in the 1.4.18 security release.
+
+Bugfixes
+========
+
+* ``GZipMiddleware`` now supports streaming responses. As part of the 1.4.18
+ security release, the ``django.views.static.serve()`` function was altered
+ to stream the files it serves. Unfortunately, the ``GZipMiddleware`` consumed
+ the stream prematurely and prevented files from being served properly
+ (`#24158 <http://code.djangoproject.com/ticket/24158>`_).
diff --git a/docs/releases/1.7.4.txt b/docs/releases/1.7.4.txt
new file mode 100644
index 0000000..8a92e47
--- /dev/null
+++ b/docs/releases/1.7.4.txt
@@ -0,0 +1,26 @@
+==========================
+Django 1.7.4 release notes
+==========================
+
+*January 27, 2015*
+
+Django 1.7.4 fixes several bugs in 1.7.3.
+
+Bugfixes
+========
+
+* Fixed a migration crash when unapplying ``contrib.contenttypes``’s or
+ ``contrib.auth``’s first migration (:ticket:`24075`).
+
+* Made the migration's ``RenameModel`` operation rename ``ManyToManyField``
+ tables (:ticket:`24135`).
+
+* Fixed a migration crash on MySQL when migrating from a ``OneToOneField`` to a
+ ``ForeignKey`` (:ticket:`24163`).
+
+* Prevented the ``static.serve`` view from producing ``ResourceWarning``\s in
+ certain circumstances (security fix regression, :ticket:`24193`).
+
+* Fixed schema check for ``ManyToManyField`` to look for internal type instead
+ of checking class instance, so you can write custom m2m-like fields with the
+ same behavior. (:ticket:`24104`).
diff --git a/docs/releases/1.7.txt b/docs/releases/1.7.txt
index 5ed1056..34e9a09 100644
--- a/docs/releases/1.7.txt
+++ b/docs/releases/1.7.txt
@@ -1698,10 +1698,16 @@ value of the former flag is used. Defining both ``requires_system_checks`` and
The ``check()`` method has replaced the old ``validate()`` method.
-``ModelAdmin.validator``
-~~~~~~~~~~~~~~~~~~~~~~~~
+``ModelAdmin`` validators
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The ``ModelAdmin.validator_class`` and ``default_validator_class`` attributes
+are deprecated in favor of the new ``checks_class`` attribute.
-``ModelAdmin.validator`` is deprecated in favor of new ``checks`` attribute.
+The ``ModelAdmin.validate()`` method is deprecated in favor of
+``ModelAdmin.check()``.
+
+The ``django.contrib.admin.validation`` module is deprecated.
``django.db.backends.DatabaseValidation.validate_field``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -1761,6 +1767,30 @@ FastCGI support
FastCGI support via the ``runfcgi`` management command will be removed in
Django 1.9. Please deploy your project using WSGI.
+Moved objects in ``contrib.sites``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Following the app-loading refactor, two objects in
+``django.contrib.sites.models`` needed to be moved because they must be
+available without importing ``django.contrib.sites.models`` when
+``django.contrib.sites`` isn't installed. Import ``RequestSite`` from
+``django.contrib.sites.requests`` and ``get_current_site()`` from
+``django.contrib.sites.shortcuts``. The old import locations will work until
+Django 1.9.
+
+``django.forms.forms.get_declared_fields()``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
... 682 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