Final releases. Django Software
Publicitate
Publicitate
CHAPTER
9
Release notes
Release notes for the official Django releases. Each release note will tell you what’s new in each version, and will also describe any backwards-incompatible changes made in that version.
For those
for each ‘final’ release from the one after your current Django version, up to and including the new version.
Final releases
Below are release notes through Django 2.0 and its patch releases. Newer versions of the documentation contain the release notes for any later releases.
2.0 release
Django 2.0 release notes - UNDER DEVELOPMENT
Welcome to Django 2.0!
These release notes cover the
backwards incompatible changes
you’ll want to be aware of when upgrading from Django 1.11 or earlier. We’ve
that have reached the end of their deprecation cycle, and we’ve
begun the deprecation process for some features .
This release starts Django’s use of a
loose form of semantic versioning , however, there aren’t any major backwards
incompatible changes that might be expected of a 2.0 release. Upgrading should be a similar amount of effort as past feature releases.
See the
Upgrading Django to a newer version
guide if you’re updating an existing project.
1399
Django Documentation, Release 2.0.dev20170914110741
Python compatibility
Django 2.0 supports Python 3.4, 3.5, and 3.6. We highly recommend and only officially support the latest release of each series.
The Django 1.11.x series is the last to support Python 2.7.
Django 2.0 will be the last release series to support Python 3.4. If you plan a deployment of Python 3.4 beyond the end-of-life for Django 2.0 (April 2019), stick with Django 1.11 LTS (supported until April 2020) instead. Note, however, that the end-of-life for Python 3.4 is March 2019.
Third-party library support for older version of Django
Following the release of Django 2.0, we suggest that third-party app authors drop support for all versions of Django prior to 1.11. At that time, you should be able to run your package’s tests using python -Wd so that deprecation warnings do appear. After making the deprecation warning fixes, your app should be compatible with Django 2.0.
What’s new in Django 2.0
Minor features django.contrib.admin
• ...
django.contrib.admindocs
• ...
django.contrib.auth
• The default iteration count for the PBKDF2 password hasher is increased from 36,000 to 100,000.
django.contrib.contenttypes
• ...
django.contrib.gis
• Added MySQL support for the
function,
function,
function,
lookup, and
• Added the
and
functions, supported on PostGIS and SpatiaLite.
• Any
imported from GeoJSON now has its SRID set.
• Added the
attribute to customize the map’s default zoom level.
• Made metadata readable and editable on rasters through the
attributes.
1400 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
• Allowed passing driver-specific creation options to
objects using papsz_options.
• Allowed creating
objects in GDAL’s internal virtual filesystem. Rasters can now be
created from and converted to binary data
in-memory.
django.contrib.messages
• ...
django.contrib.postgres
• The new distinct argument for
determines if concatenated values will be distinct.
• The new
database function returns a version 4 UUID. It requires use of PostgreSQL’s pgcrypto extension which can be activated using the new
migration operation.
•
django.contrib.postgres.indexes.GinIndex
now supports the fastupdate and gin_pending_list_limit parameters.
• The new
class allows creating GiST indexes in the database. The new
migration operation installs the btree_gist extension to add support for operator classes that aren’t built-in.
•
can now introspect JSONField and various RangeFields (django.contrib.postgres
must be in INSTALLED_APPS).
django.contrib.redirects
• ...
django.contrib.sessions
• ...
django.contrib.sitemaps
• Added the protocol keyword argument to the
constructor.
django.contrib.sites
• ...
django.contrib.staticfiles
• ...
django.contrib.syndication
• ...
9.1. Final releases 1401
Django Documentation, Release 2.0.dev20170914110741
Cache
• On memcached, cache.set_many() returns a list of keys that failed to be inserted.
CSRF
• ...
Database backends
• ...
• ...
File Storage
•
can be used as a context manager, e.g. with file.open() as f:.
File Uploads
• ...
Forms
• The new date_attrs and time_attrs arguments for
and
allow specifying different HTML attributes for the DateInput and TimeInput (or hidden) subwidgets.
• The new
method returns form errors as a dictionary suitable for including in a JSON response.
Generic Views
• The new
attribute allows adding context in View.as_view().
Internationalization
• ...
1402 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
Management Commands
•
now translates MySQL’s unsigned integer columns to PositiveIntegerField or
PositiveSmallIntegerField .
• The new
option controls the comment format in PO files.
•
can now
• The new
option allows formatting the output in a unified diff format.
• On Oracle,
can now introspect AutoField if the column is created as an identity column.
• On MySQL,
now supports client-side TLS certificates.
Migrations
• The new
squashmigrations --squashed-name
option allows naming the squashed migration.
Models
• The new
database function finds the starting index of a string inside another string.
• On Oracle, AutoField and BigAutoField are now created as identity columns .
• The new chunk_size parameter of
controls the number of rows fetched by the
Python database client when streaming results from the database. For databases that don’t support server-side cursors, it controls the number of results Django fetches from the database adapter.
•
now allow ordering by several fields.
• Added the
function to extract the quarter from
and
exposed it through the
lookup.
• Added the
function to truncate
and
to the first day of a quarter.
• Added the
parameter to class-based indexes.
• If the database supports a native duration field (Oracle and PostgreSQL),
now works with
• Added the of argument to
, supported on PostgreSQL and Oracle,
to lock only rows from specific tables rather than all selected tables. It may be helpful particularly when
is used in conjunction with
• The new field_name parameter of
allows fetching results based on any unique model field.
•
now takes an optional dictionary of keyword parameters, if the backend supports this feature. Of Django’s built-in backends, only Oracle supports it.
• The new filter argument for built-in aggregates allows
to multiple aggregations over the same fields or relations.
• Added support for expressions in
• The new named parameter of
allows fetching results as named tuples.
9.1. Final releases 1403
Django Documentation, Release 2.0.dev20170914110741
Pagination
• Added
to provide the documented pattern of handling invalid page numbers.
Requests and Responses
• The
Web server supports HTTP 1.1.
Serialization
• ...
Signals
• ...
Templates
• To increase the usefulness of
in third-party apps, it now returns the first engine if multiple DjangoTemplates engines are configured in TEMPLATES rather than raising
ImproperlyConfigured
.
• Custom template tags may now accept keyword-only arguments.
Tests
• Added threading support to
• Added settings that allow customizing the test tablespace parameters for Oracle:
URLs
• ...
Validators
• The new
ProhibitNullCharactersValidator
disallows the null character in the input of the
form field and its subclasses. Null character input was observed from vulnerability scanning tools. Most databases silently discard null characters, but psycopg2 2.7+ raises an exception when trying to save a null character to a char/text field with PostgreSQL.
1404 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
Backwards incompatible changes in 2.0
Removed support for bytestrings in some places
To support native Python 2 strings, older Django versions had to accept both bytestrings and unicode strings. Now that Python 2 support is dropped, bytestrings should only be encountered around input/output boundaries (handling of binary fields or HTTP streams, for example). You might have to update your code to limit bytestring usage to a minimum, as Django no longer accepts bytestrings in certain code paths.
Database backend API
This section describes changes that may be needed in third-party database backends.
• The
DatabaseOperations.datetime_cast_date_sql()
, datetime_cast_time_sql()
, datetime_trunc_sql()
, datetime_extract_sql(), and date_interval_sql() methods now return only the SQL to perform the operation instead of SQL and a list of parameters.
• Third-party database backends should add a DatabaseWrapper.display_name attribute with the name of the database that your backend works with. Django may use it in various messages, such as in system checks.
• The first argument of SchemaEditor._alter_column_type_sql() is now model rather than table.
• The first argument of SchemaEditor._create_index_name() is now table_name rather than model
.
• To enable FOR UPDATE OF support, set DatabaseFeatures.has_select_for_update_of =
True
.
If the database requires that the arguments to OF be columns rather than tables, set
DatabaseFeatures.select_for_update_of_column = True
.
• Third-party database backends should add a
DatabaseOperations.
cast_char_field_without_max_length attribute with the database data type that will be used in the
function for a CharField if the max_length argument isn’t provided.
• The first argument of DatabaseCreation._clone_test_db() and get_test_db_clone_settings() is now suffix rather than number (in case you want to rename the signatures in your backend for consistency). django.test also now passes those values as strings rather than as integers.
• Third-party database backends should add a DatabaseIntrospection.get_sequences() method based on the stub in BaseDatabaseIntrospection.
Dropped support for Oracle 11.2
The end of upstream support for Oracle 11.2 is Dec. 2020. Django 1.11 will be supported until April 2020 which almost reaches this date. Django 2.0 officially supports Oracle 12.1+.
Default MySQL isolation level is read committed
MySQL’s default isolation level, repeatable read, may cause data loss in typical Django usage. To prevent that and for consistency with other databases, the default isolation level is now read committed. You can use the
setting to
use a different isolation level
9.1. Final releases 1405
Django Documentation, Release 2.0.dev20170914110741
AbstractUser.last_name max_length increased to 150
A migration for
django.contrib.auth.models.User.last_name
is included. If you have a custom user model inheriting from AbstractUser, you’ll need to generate and apply a database migration for your user model.
If you want to preserve the 30 character limit for last names, use a custom form:
from
django.contrib.auth.forms
import
UserChangeForm
class MyUserChangeForm
(UserChangeForm): last_name = forms.CharField(max_length= 30 , required=False)
If you wish to keep this restriction in the admin when editing users, set UserAdmin.form to use this form:
from
django.contrib.auth.admin
import
UserAdmin
from
django.contrib.auth.models
import
User
class MyUserAdmin
(UserAdmin): form = MyUserChangeForm admin.site.unregister(User) admin.site.register(User, MyUserAdmin)
QuerySet.reverse() and last() are prohibited after slicing
Calling QuerySet.reverse() or last() on a sliced queryset leads to unexpected results due to the slice being applied after reordering. This is now prohibited, e.g.:
>>> Model.objects.all()[: 2 ].reverse()
Traceback (most recent call last):
...
TypeError : Cannot reverse a query once a slice has been taken.
Form fields no longer accept optional arguments as positional arguments
To help prevent runtime errors due to incorrect ordering of form field arguments, optional arguments of built-in form fields are no longer accepted as positional arguments. For example: forms.IntegerField( 25 , 10 ) raises an exception and should be replaced with: forms.IntegerField(max_value= 25 , min_value= 10 )
call_command() validates the options it receives
call_command() now validates that the argument parser of the command being called defines all of the options passed to call_command().
For custom management commands that use options not created using parser.add_argument(), add a stealth_options attribute on the command:
1406 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
class MyCommand
(BaseCommand): stealth_options = ( 'option_name' , ...)
Indexes no longer accept positional arguments
For example: models.Index([ 'headline' , '-pub_date' ], 'index_name' ) raises an exception and should be replaced with: models.Index(fields=[ 'headline' , '-pub_date' ], name= 'index_name' )
Foreign key constraints are now enabled on SQLite
This will appear as a backwards-incompatible change (IntegrityError:
FOREIGN KEY constraint failed
) if attempting to save an existing model instance that’s violating a foreign key constraint.
Foreign keys are now created with DEFERRABLE INITIALLY DEFERRED instead of DEFERRABLE
IMMEDIATE
. Thus, tables may need to be rebuilt to recreate foreign keys with the new definition, particularly if you’re using a pattern like this:
from
django.db
import
transaction
with
transaction.atomic():
Book.objects.create(author_id= 1 )
Author.objects.create( id
=
1 )
If you don’t recreate the foreign key as DEFERRED, the first create() would fail now that foreign key constraints are enforced.
Backup your database first! After upgrading to Django 2.0, you can then rebuild tables using a script similar to this:
from
django.apps
import
apps
from
django.db
import
connection
for
app in apps.get_app_configs():
for
model in app.get_models(include_auto_created=True):
if
model._meta.managed and not (model._meta.proxy or model._meta.swapped):
for
base in model. __bases__ :
if
hasattr (base, '_meta' ): base._meta.local_many_to_many = [] model._meta.local_many_to_many = []
with
connection.schema_editor() as editor: editor._remake_table(model)
This script hasn’t received extensive testing and needs adaption for various cases such as multiple databases. Feel free to contribute improvements.
Miscellaneous
• The SessionAuthenticationMiddleware class is removed. It provided no functionality since session authentication is unconditionally enabled in Django 1.10.
9.1. Final releases 1407
Django Documentation, Release 2.0.dev20170914110741
• The default HTTP error handlers (handler404, etc.) are now callables instead of dotted Python path strings.
Django favors callable references since they provide better performance and debugging experience.
•
no longer silences NoReverseMatch if the pattern_name doesn’t exist.
• When
is off,
and
now respect
and
during validation. For example, with the settings:
USE_L10N = False
USE_THOUSAND_SEPARATOR = True
DECIMAL_SEPARATOR = ','
THOUSAND_SEPARATOR = '.' an input of "1.345" is now converted to 1345 instead of 1.345.
• Subclasses of
are no longer required to implement get_short_name() and get_full_name() .
(The base implementations that raise NotImplementedError are removed.) django.contrib.admin
uses these methods if implemented but doesn’t require them. Third-party apps that use these methods may want to adopt a similar approach.
• The FIRST_DAY_OF_WEEK and NUMBER_GROUPING format settings are now kept as integers in JavaScript and JSON i18n view outputs.
•
now ignores connection configuration queries. Previously, if a test opened a new database connection, those queries could be included as part of the assertNumQueries() count.
• The PASSWORD_RESET_TIMEOUT_DAYS setting is more properly respected in contrib.auth password reset. Previously, resets were allowed for one day longer than expected. For example, with the default of
PASSWORD_RESET_TIMEOUT_DAYS = 3
, password reset tokens are now valid for 72 hours rather than 96 hours.
• The default size of the Oracle test tablespace is increased from 20M to 50M and the default autoextend size is increased from 10M to 25M.
• To improve performance when streaming large result sets from the database,
now fetches 2000 rows at a time instead of 100. The old behavior can be restored using the chunk_size parameter.
For example:
Book.objects.iterator(chunk_size= 100 )
• Providing unknown package names in the packages argument of the
view now raises ValueError instead of passing silently.
• A model instance’s primary key now appears in the default Model.__str__() method, e.g. Question object (1)
.
• makemigrations now detects changes to the model field limit_choices_to option. Add this to your existing migrations or accept an auto-generated migration for fields that use it.
• Performing queries that require
automatic spatial transformations
now raises NotImplementedError on
MySQL instead of silently using non-transformed geometries.
• django.core.exceptions.DjangoRuntimeWarning is removed. It was only used in the cache backend as an intermediate class in CacheKeyWarning‘s inheritance of RuntimeWarning.
• Renamed BaseExpression._output_field to output_field. You may need to update custom expressions.
• In older versions, forms and formsets combine their Media with widget Media by concatenating the two. The combining now tries to
preserve the relative order of elements in each list . MediaOrderConflictWarning
is issued if the order can’t be preserved.
1408 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
• django.contrib.gis.gdal.OGRException is removed. It’s been an alias for GDALException since Django 1.8.
• Support for GEOS 3.3.x is dropped.
Features deprecated in 2.0
context argument of Field.from_db_value() and Expression.convert_value()
The context argument of Field.from_db_value() and Expression.convert_value() is unused as it’s always an empty dictionary. The signature of both methods is now:
( self , value, expression, connection) instead of:
( self , value, expression, connection, context)
Support for the old signature in custom fields and expressions remains until Django 3.0.
Miscellaneous
• The django.db.backends.postgresql_psycopg2 module is deprecated in favor of django.
db.backends.postgresql
.
It’s been an alias since Django 1.9.
This only affects code that imports from the module directly.
The DATABASES setting can still use 'django.db.backends.
postgresql_psycopg2'
, though you can simplify that by using the 'django.db.backends.
postgresql' name added in Django 1.9.
• django.shortcuts.render_to_response() is deprecated in favor of
. render() takes the same arguments except that is also requires a request.
• The DEFAULT_CONTENT_TYPE setting is deprecated. It doesn’t interact well well with third-party apps and is obsolete since HTML5 has mostly superseded XHTML.
• HttpRequest.xreadlines() is deprecated in favor of iterating over the request.
• The field_name keyword argument to
and
is deprecated in favor of passing the field names as arguments. Write .earliest('pub_date') instead of .
earliest(field_name='pub_date') .
Features removed in 2.0
These features have reached the end of their deprecation cycle and are removed in Django 2.0. See
and
for details, including how to remove usage of these features.
• The weak argument to django.dispatch.signals.Signal.disconnect() is removed.
• django.db.backends.base.BaseDatabaseOperations.check_aggregate_support() is removed.
• The django.forms.extras package is removed.
• The assignment_tag helper is removed.
• The host argument to SimpleTestCase.assertsRedirects() is removed. The compatibility layer which allows absolute URLs to be considered equal to relative ones when the path is identical is also removed.
9.1. Final releases 1409
Django Documentation, Release 2.0.dev20170914110741
• Field.rel and Field.remote_field.to are removed.
• The on_delete argument for ForeignKey and OneToOneField are now required.
• django.db.models.fields.add_lazy_relation() is removed.
• When time zone support is enabled, database backends that don’t support time zones no longer convert aware datetimes to naive values in UTC anymore when such values are passed as parameters to SQL queries executed outside of the ORM, e.g. with cursor.execute().
• django.contrib.auth.tests.utils.skipIfCustomUser() is removed.
• The GeoManager and GeoQuerySet classes are removed.
• The django.contrib.gis.geoip module is removed.
• The supports_recursion check for template loaders is removed from:
– django.template.engine.Engine.find_template()
– django.template.loader_tags.ExtendsNode.find_template()
– django.template.loaders.base.Loader.supports_recursion()
– django.template.loaders.cached.Loader.supports_recursion()
• The load_template and load_template_sources template loader methods are removed.
• The template_dirs argument for template loaders is removed:
– django.template.loaders.base.Loader.get_template()
– django.template.loaders.cached.Loader.cache_key()
– django.template.loaders.cached.Loader.get_template()
– django.template.loaders.cached.Loader.get_template_sources()
– django.template.loaders.filesystem.Loader.get_template_sources()
• django.template.loaders.base.Loader.__call__() is removed.
• Support for custom error views that don’t accept an exception parameter is removed.
• The mime_type attribute of django.utils.feedgenerator.Atom1Feed and django.utils.
feedgenerator.RssFeed
is removed.
• The app_name argument to include() is removed.
• Support for passing a 3-tuple (including admin.site.urls) as the first argument to include() is removed.
• Support for setting a URL instance namespace without an application namespace is removed.
• Field._get_val_from_obj() is removed.
• django.template.loaders.eggs.Loader is removed.
• The current_app parameter to the contrib.auth function-based views is removed.
• The callable_obj keyword argument to SimpleTestCase.assertRaisesMessage() is removed.
• Support for the allow_tags attribute on ModelAdmin methods is removed.
• The enclosure keyword argument to SyndicationFeed.add_item() is removed.
• The django.template.loader.LoaderOrigin and django.template.base.StringOrigin
aliases for django.template.base.Origin are removed.
• The makemigrations --exit option is removed.
1410 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
• Support for direct assignment to a reverse foreign key or many-to-many relation is removed.
• The get_srid() and set_srid() methods of django.contrib.gis.geos.GEOSGeometry are removed.
• The get_x(), set_x(), get_y(), set_y(), get_z(), and set_z() methods of django.
contrib.gis.geos.Point
are removed.
• The get_coords() and set_coords() methods of django.contrib.gis.geos.Point are removed.
• The cascaded_union property of django.contrib.gis.geos.MultiPolygon is removed.
• django.utils.functional.allow_lazy() is removed.
• The shell --plain option is removed.
• The django.core.urlresolvers module is removed.
• CommaSeparatedIntegerField is removed, except for support in historical migrations.
• The template Context.has_key() method is removed.
• Support for the django.core.files.storage.Storage.accessed_time() , created_time() , and modified_time() methods is removed.
• Support for query lookups using the model name when Meta.default_related_name is set is removed.
• The MySQL __search lookup is removed.
• The shim for supporting custom related manager classes without a _apply_rel_filters() method is removed.
• Using User.is_authenticated() and User.is_anonymous() as methods rather than properties is no longer supported.
• The Model._meta.virtual_fields attribute is removed.
• The keyword arguments virtual_only in Field.contribute_to_class() and virtual in
Model._meta.add_field() are removed.
• The javascript_catalog() and json_catalog() views are removed.
• django.contrib.gis.utils.precision_wkt() is removed.
• In multi-table inheritance, implicit promotion of a OneToOneField to a parent_link is removed.
• Support for Widget._format_value() is removed.
• FileField methods get_directory_name() and get_filename() are removed.
• The mark_for_escaping() function and the classes it uses:
EscapeData
, EscapeBytes,
EscapeText
, EscapeString, and EscapeUnicode are removed.
• The escape filter now uses django.utils.html.conditional_escape().
• Manager.use_for_related_fields is removed.
• Model Manager inheritance follows MRO inheritance rules.
The requirement to use Meta.
manager_inheritance_from_future to opt-in to the behavior is removed.
• Support for old-style middleware using settings.MIDDLEWARE_CLASSES is removed.
9.1. Final releases 1411
Django Documentation, Release 2.0.dev20170914110741
1.11 release
Django 1.11.6 release notes
Expected October 2, 2017
Django 1.11.6 fixes several bugs in 1.11.5.
Bugfixes
• Made the CharField form field convert whitespace-only values to the empty_value when strip is enabled ( #28555 ).
Django 1.11.5 release notes
September 5, 2017
Django 1.11.5 fixes a security issue and several bugs in 1.11.4.
CVE-2017-12794: Possible XSS in traceback section of technical 500 debug page
In older versions, HTML autoescaping was disabled in a portion of the template for the technical 500 debug page.
Given the right circumstances, this allowed a cross-site scripting attack. This vulnerability shouldn’t affect most production sites since you shouldn’t run with DEBUG = True (which makes this page accessible) in your production settings.
Bugfixes
• Fixed GEOS version parsing if the version has a commit hash at the end (new in GEOS 3.6.2) ( #28441 ).
• Added compatibility for cx_Oracle 6 ( #28498 ).
• Fixed select widget rendering when option values are tuples ( #28502 ).
• Django 1.11 inadvertently changed the sequence and trigger naming scheme on Oracle. This causes errors on
INSERTs for some tables if 'use_returning_into':
False is in the OPTIONS part of DATABASES.
The pre-1.11 naming scheme is now restored. Unfortunately, it necessarily requires an update to Oracle tables created with Django 1.11.[1-4]. Use the upgrade script in #28451 comment 8 to update sequence and trigger names to use the pre-1.11 naming scheme.
• Added POST request support to LogoutView, for equivalence with the function-based logout() view
( #28513 ).
• Omitted pages_per_range from BrinIndex.deconstruct() if it’s None ( #25809 ).
• Fixed a regression where SelectDateWidget localized the years in the select box ( #28530 ).
• Fixed a regression in 1.11.4 where runserver crashed with non-Unicode system encodings on Python 2 +
Windows ( #28487 ).
• Fixed a regression in Django 1.10 where changes to a ManyToManyField weren’t logged in the admin change history ( #27998 ) and prevented ManyToManyField initial data in model forms from being affected by subsequent model changes ( #28543 ).
• Fixed non-deterministic results or an AssertionError crash in some queries with multiple joins ( #26522 ).
1412 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
• Fixed a regression in contrib.auth‘s login() and logout() views where they ignored positional arguments ( #28550 ).
Django 1.11.4 release notes
August 1, 2017
Django 1.11.4 fixes several bugs in 1.11.3.
Bugfixes
• Fixed a regression in 1.11.3 on Python 2 where non-ASCII format values for date/time widgets results in an empty value in the widget’s HTML ( #28355 ).
• Fixed
QuerySet.union() and difference() when combining with a queryset raising
EmptyResultSet
( #28378 ).
• Fixed a regression in pickling of LazyObject on Python 2 when the wrapped object doesn’t have
__reduce__()
( #28389 ).
• Fixed crash in runserver‘s autoreload with Python 2 on Windows with non-str environment variables
( #28174 ).
• Corrected Field.has_changed() to return False for disabled form fields: BooleanField ,
MultipleChoiceField , MultiValueField , FileField , ModelChoiceField , and
ModelMultipleChoiceField .
• Fixed QuerySet.count() for union(), difference(), and intersection() queries. ( #28399 ).
• Fixed ClearableFileInput rendering as a subwidget of MultiWidget ( #28414 ).
Custom clearable_file_input.html widget templates will need to adapt for the fact that context values checkbox_name, checkbox_id, is_initial, input_text, initial_text, and clear_checkbox_label are now attributes of widget rather than appearing in the top-level context.
• Fixed queryset crash when using a GenericRelation to a proxy model ( #28418 ).
Django 1.11.3 release notes
July 1, 2017
Django 1.11.3 fixes several bugs in 1.11.2.
Bugfixes
• Removed an incorrect deprecation warning about a missing renderer argument if a Widget.render() method accepts **kwargs ( #28265 ).
• Fixed a regression causing Model.__init__() to crash if a field has an instance only descriptor ( #28269 ).
• Fixed an incorrect DisallowedModelAdminLookup exception when using a nested reverse relation in list_filter
( #28262 ).
• Fixed admin’s FieldListFilter.get_queryset() crash on invalid input ( #28202 ).
• Fixed invalid HTML for a required AdminFileWidget ( #28278 ).
• Fixed model initialization to set the name of class-based model indexes for models that only inherit models.
Model
( #28282 ).
9.1. Final releases 1413
Django Documentation, Release 2.0.dev20170914110741
• Fixed crash in admin’s inlines when a model has an inherited non-editable primary key ( #27967 ).
• Fixed QuerySet.union(), intersection(), and difference() when combining with an
EmptyQuerySet ( #28293 ).
• Prevented Paginator’s unordered object list warning from evaluating a QuerySet ( #28284 ).
• Fixed the value of redirect_field_name in LoginView’s template context. It’s now an empty string (as it is for the original function-based login() view) if the corresponding parameter isn’t sent in a request (in particular, when the login page is accessed directly) ( #28229 ).
• Prevented attribute values in the django/forms/widgets/attrs.html template from being localized so that numeric attributes (e.g. max and min) of NumberInput work correctly ( #28303 ).
• Removed casting of the option value to a string in the template context of the CheckboxSelectMultiple,
NullBooleanSelect
, RadioSelect, SelectMultiple, and Select widgets ( #28176 ). In Django
1.11.1, casting was added in Python to avoid localization of numeric values in Django templates, but this made some use cases more difficult. Casting is now done in the template using the |stringformat:'s' filter.
• Prevented a primary key alteration from adding a foreign key constraint if db_constraint=False
( #28298 ).
• Fixed UnboundLocalError crash in RenameField with nonexistent field ( #28350 ).
• Fixed a regression preventing a model field’s limit_choices_to from being evaluated when a ModelForm is instantiated ( #28345 ).
Django 1.11.2 release notes
June 1, 2017
Django 1.11.2 adds a minor feature and fixes several bugs in 1.11.1. Also, the latest string translations from Transifex are incorporated.
Minor feature
The new LiveServerTestCase.port attribute reallows the use case of binding to a specific port following the
change in Django 1.11.
Bugfixes
• Added detection for GDAL 2.1 and 2.0, and removed detection for unsupported versions 1.7 and 1.8 ( #28181 ).
• Changed contrib.gis to raise ImproperlyConfigured rather than GDALException if gdal isn’t installed, to allow third-party apps to catch that exception ( #28178 ).
• Fixed django.utils.http.is_safe_url() crash on invalid IPv6 URLs ( #28142 ).
• Fixed regression causing pickling of model fields to crash ( #28188 ).
• Fixed django.contrib.auth.authenticate() when multiple authentication backends don’t accept a positional request argument ( #28207 ).
• Fixed introspection of index field ordering on PostgreSQL ( #28197 ).
• Fixed a regression where Model._state.adding wasn’t set correctly on multi-table inheritance parent models after saving a child model ( #28210 ).
1414 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
• Allowed
DjangoJSONEncoder to serialize django.utils.deprecation.CallableBool
( #28230 ).
• Relaxed the validation added in Django 1.11 of the fields in the defaults argument of QuerySet.
get_or_create() and update_or_create() to reallow settable model properties ( #28222 ).
• Fixed MultipleObjectMixin.paginate_queryset() crash on Python 2 if the InvalidPage message contains non-ASCII ( #28204 ).
• Prevented Subquery from adding an unnecessary CAST which resulted in invalid SQL ( #28199 ).
• Corrected detection of GDAL 2.1 on Windows ( #28181 ).
• Made date-based generic views return a 404 rather than crash when given an out of range date ( #28209 ).
• Fixed a regression where file_move_safe() crashed when moving files to a CIFS mount ( #28170 ).
• Moved the ImageField file extension validation added in Django 1.11 from the model field to the form field to reallow the use case of storing images without an extension ( #28242 ).
Django 1.11.1 release notes
May 6, 2017
Django 1.11.1 adds a minor feature and fixes several bugs in 1.11.
Allowed disabling server-side cursors on PostgreSQL
The change in Django 1.11 to make
use server-side cursors on PostgreSQL prevents running Django with pgBouncer in transaction pooling mode.
To reallow that, use the
setting in
See
Transaction pooling and server-side cursors
for more discussion.
Bugfixes
• Made migrations respect Index’s name argument.
If you created a named index with Django 1.11, makemigrations will create a migration to recreate the index with the correct name ( #28051 ).
• Fixed a crash when using a __icontains lookup on a ArrayField ( #28038 ).
• Fixed a crash when using a two-tuple in EmailMessage’s attachments argument ( #28042 ).
• Fixed QuerySet.filter() crash when it references the name of a OneToOneField primary key
( #28047 ).
• Fixed empty POST data table appearing instead of “No POST data” in HTML debug page ( #28079 ).
• Restored BoundFields without any choices evaluating to True ( #28058 ).
• Prevented SessionBase.cycle_key() from losing session data if _session_cache isn’t populated
( #28066 ).
• Fixed layout of ReadOnlyPasswordHashWidget (used in the admin’s user change page) ( #28097 ).
• Allowed prefetch calls on managers with custom ModelIterable subclasses ( #28096 ).
• Fixed change password link in the contrib.auth admin for el, es_MX, and pt translations ( #28100 ).
• Restored the output of the class attribute in the <ul> of widgets that use the multiple_input.html
template. This fixes ModelAdmin.radio_fields with admin.HORIZONTAL ( #28059 ).
9.1. Final releases 1415
Django Documentation, Release 2.0.dev20170914110741
• Fixed crash in BaseGeometryWidget.subwidgets() ( #28039 ).
• Fixed exception reraising in ORM query execution when cursor.execute() fails and the subsequent cursor.close() also fails ( #28091 ).
• Fixed a regression where CheckboxSelectMultiple, NullBooleanSelect, RadioSelect,
SelectMultiple
, and Select localized option values ( #28075 ).
• Corrected the stack level of unordered queryset pagination warnings ( #28109 ).
• Fixed a regression causing incorrect queries for __in subquery lookups when models use ForeignKey.
to_field
( #28101 ).
• Fixed crash when overriding the template of django.views.static.directory_index() ( #28122 ).
• Fixed a regression in formset min_num validation with unchanged forms that have initial data ( #28130 ).
• Prepared for cx_Oracle 6.0 support ( #28138 ).
• Updated the contrib.postgres SplitArrayWidget to use template-based widget rendering ( #28040 ).
• Fixed crash in BaseGeometryWidget.get_context() when overriding existing attrs ( #28105 ).
• Prevented AddIndex and RemoveIndex from mutating model state ( #28043 ).
• Prevented migrations from dropping database indexes from Meta.indexes when changing Field.
db_index to False ( #28052 ).
• Fixed a regression in choice ordering in form fields with grouped and non-grouped options ( #28157 ).
• Fixed crash in BaseInlineFormSet._construct_form() when using save_as_new ( #28159 ).
• Fixed a regression where Model._state.db wasn’t set correctly on multi-table inheritance parent models after saving a child model ( #28166 ).
• Corrected the return type of ArrayField(CITextField()) values retrieved from the database ( #28161 ).
• Fixed QuerySet.prefetch_related() crash when fetching relations in nested Prefetch objects
( #27554 ).
• Prevented hiding GDAL errors if it’s not installed when using contrib.gis ( #28160 ). (It’s a required dependency as of Django 1.11.)
• Fixed a regression causing __in lookups on a foreign key to fail when using the foreign key’s parent model as the lookup value ( #28175 ).
Django 1.11 release notes
April 4, 2017
Welcome to Django 1.11!
These release notes cover the
new features , as well as some
backwards incompatible changes
you’ll want to be aware of when upgrading from Django 1.10 or older versions. We’ve
begun the deprecation process for some features .
See the
Upgrading Django to a newer version
guide if you’re updating an existing project.
Django 1.11 is designated as a
long-term support release . It will receive security updates for at least three years after
its release. Support for the previous LTS, Django 1.8, will end in April 2018.
1416 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
Python compatibility
Django 1.11 requires Python 2.7, 3.4, 3.5, or 3.6. Django 1.11 is the first release to support Python 3.6. We highly recommend and only officially support the latest release of each series.
The Django 1.11.x series is the last to support Python 2. The next major release, Django 2.0, will only support Python
3.4+.
Deprecating warnings are no longer loud by default
Unlike older versions of Django, Django’s own deprecation warnings are no longer displayed by default. This is consistent with Python’s default behavior.
This change allows third-party apps to support both Django 1.11 LTS and Django 1.8 LTS without having to add code to avoid deprecation warnings.
Following the release of Django 2.0, we suggest that third-party app authors drop support for all versions of Django prior to 1.11. At that time, you should be able run your package’s tests using python -Wd so that deprecation warnings do appear. After making the deprecation warning fixes, your app should be compatible with Django 2.0.
What’s new in Django 1.11
Class-based model indexes
The new
module contains classes which ease creating database indexes. Indexes are added to models using the
option.
The
class creates a b-tree index, as if you used
on the model field or
on the model Meta class. It can be subclassed to support different index types, such as
the order (ASC/DESC) for the columns of the index.
Template-based widget rendering
To ease customizing widgets, form widget rendering is now done using the template system rather than in Python. See
You may need to adjust any custom widgets that you’ve written for a few
backwards incompatible changes .
Subquery expressions
The new
and
database expressions allow creating explicit subqueries. Subqueries may refer to fields from the outer queryset using the
class.
Minor features django.contrib.admin
•
can now reference fields across relations.
• The new
hook allows specifying the exclude fields based on the request or model instance.
9.1. Final releases 1417
Django Documentation, Release 2.0.dev20170914110741
• The popup_response.html template can now be overridden per app, per model, or by setting the
ModelAdmin.popup_response_template
attribute.
django.contrib.auth
• The default iteration count for the PBKDF2 password hasher is increased by 20%.
• The
and
class-based views supersede the deprecated login() and logout() function-based views.
• The
class-based views supersede the deprecated password_change(), password_change_done(), password_reset()
, password_reset_done()
, password_reset_confirm()
, and password_reset_complete() function-based views.
• The new post_reset_login attribute for
allows automatically logging in a user after a successful password reset. If you have multiple AUTHENTICATION_BACKENDS configured, use the post_reset_login_backend attribute to choose which one to use.
• To avoid the possibility of leaking a password reset token via the HTTP Referer header (for example, if the reset page includes a reference to CSS or JavaScript hosted on another domain), the
(but not the deprecated password_reset_confirm() function-based view) stores the token in a session and redirects to itself to present the password change form to the user without the token in the URL.
•
now rotates the session key to allow a password change to invalidate stolen session cookies.
• The new success_url_allowed_hosts attribute for
and
allows specifying a set of hosts that are safe for redirecting after login and logout.
• Added password validators help_text to
• The HttpRequest is now passed to
which in turn passes it to the authentication backend if it accepts a request argument.
• The
signal now receives a request argument.
•
supports custom user models that use an email field named something other than
'email'
. Set
to the name of the field.
•
can now be called at import time, even in modules that define models.
django.contrib.contenttypes
• When stale content types are detected in the
command, there’s now a list of related objects such as auth.Permissions that will also be deleted. Previously, only the content types were listed (and this prompt was after migrate rather than in a separate command).
django.contrib.gis
• The new
and
methods allow creating geometries from GML.
• Added support for the
lookup on SpatiaLite.
1418 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
• The
function,
function, and distance lookups now work with geodetic coordinates on SpatiaLite.
• The OpenLayers-based form widgets now use OpenLayers.js from https://cdnjs.cloudflare.
com which is more suitable for production use than the the old http://openlayers.org source. They are also updated to use OpenLayers 3.
• PostGIS migrations can now change field dimensions.
• Added the ability to pass the size, shape, and offset parameter when creating
objects.
• Added SpatiaLite support for the
function,
function, and
lookup.
• Added Oracle support for the
function,
function,
function, and
lookup.
django.contrib.postgres
• The new distinct argument for
determines if concatenated values will be distinct.
• The new
and
classes allow creating GIN and BRIN indexes in the database.
•
accepts a new encoder parameter to specify a custom class to encode data types not supported by the standard encoder.
• The new
mixin and
migration operation allow using PostgreSQL’s citext extension for case-insensitive lookups. Three fields are provided:
• The new
allows aggregating values as a JSON array.
• The
(model field) and
(form field) allow storing null values.
Cache
• Memcached backends now pass the contents of
as keyword arguments to the client constructors, allowing for more advanced control of client behavior. See the
documentation for examples.
• Memcached backends now allow defining multiple servers as a comma-delimited string in
convenience with third-party services that use such strings in environment variables.
CSRF
• Added the
setting to allow storing the CSRF token in the user’s session rather than in a cookie.
Database backends
• Added the skip_locked argument to
on PostgreSQL 9.5+ and
Oracle to execute queries with FOR UPDATE SKIP LOCKED.
• Added the
setting to let PostgreSQL users specify a template for creating the test database.
•
now uses server-side cursors on PostgreSQL. This feature transfers some of the worker memory load (used to hold query results) to the database and might increase database memory usage.
9.1. Final releases 1419
Django Documentation, Release 2.0.dev20170914110741
• Added MySQL support for the 'isolation_level' option in
to allow specifying the
repeatable read, to read committed.
• Added support for cx_Oracle 5.3.
• Added the
setting to allow sending SMTP date headers in the local time zone rather than in UTC.
• EmailMessage.attach() and attach_file() now fall back to MIME type application/ octet-stream when binary content that can’t be decoded as UTF-8 is specified for a text/* attachment.
File Storage
• To make it wrappable by io.TextIOWrapper
,
now has the readable(), writable(), and seekable() methods.
Forms
• The new
attribute allows specifying the Python value to use to represent
“empty”.
• The new
method returns initial data for a form field.
Internationalization
• Number formatting and the
setting support non-uniform digit grouping.
Management Commands
• The new
option allows excluding models and apps while loading data from fixtures.
• The new
option allows specifying a settings module other than Django’s default settings to compare against.
• app_labels arguments now limit the
output.
Migrations
• Added support for serialization of uuid.UUID objects.
Models
• Added support for callable values in the defaults argument of
and
•
now has a default
validator. (This validator moved to the form field in
1420 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
• Added support for time truncation to
functions.
• Added the
function to extract the week from
and
and exposed it through the
lookup.
• Added the
function to truncate
to its time component and exposed it through the
lookup.
• Added support for expressions in
and
• Added support for query expressions on lookups that take multiple arguments, such as range.
• You can now use the unique=True option with
• Added the nulls_first and nulls_last parameters to
and
to control the ordering of null values.
• The new F expression bitleftshift() and bitrightshift() methods allow
• Added
Requests and Responses
• Added
•
now sets the Content-Length response header for non-streaming responses.
• Added the
setting to allow appending the preload directive to the
Strict-Transport-Security header.
•
now adds the ETag header to responses.
Serialization
• The new django.core.serializers.base.Serializer.stream_class attribute allows subclasses to customize the default stream.
• The encoder used by the
can now be customized by passing a cls keyword argument to the serializers.serialize() function.
•
now serializes timedelta objects (used by
Templates
•
can now be used as a decorator.
• The
template backend now supports context processors by setting the 'context_processors' option in
• The
tag now returns namedtuples instead of dictionaries so you can unpack the group object directly in a loop, e.g. {% for grouper, list in regrouped %}.
• Added a
template tag to allow resetting the sequence of the
template tag.
• You can now specify specific directories for a particular
9.1. Final releases 1421
Django Documentation, Release 2.0.dev20170914110741
Tests
• Added
DiscoverRunner.get_test_runner_kwargs()
to allow customizing the keyword arguments passed to the test runner.
• Added the
option to help troubleshoot test failures by setting the
setting to
True
.
• The new
django.test.utils.setup_databases()
(moved from django.test.runner) and
functions make it easier to build custom test runners.
• Added support for unittest.TestCase.subTest()
’s when using the
option.
• DiscoverRunner now runs the system checks at the start of a test run. Override the
method if you want to disable that.
Validators
• Added
to validate
to validate image files.
file extensions and
Backwards incompatible changes in 1.11
django.contrib.gis
• To simplify the codebase and because it’s easier to install than when contrib.gis was first released,
is now a required dependency for GeoDjango. In older versions, it’s only required for SQLite.
• contrib.gis.maps is removed as it interfaces with a retired version of the Google Maps API and seems to be unmaintained. If you’re using it, let us know .
• The GEOSGeometry equality operator now also compares SRID.
• The OpenLayers-based form widgets now use OpenLayers 3, and the gis/openlayers.html and gis/ openlayers-osm.html
templates have been updated. Check your project if you subclass these widgets or extend the templates. Also, the new widgets work a bit differently than the old ones. Instead of using a toolbar in the widget, you click to draw, click and drag to move the map, and click and drag a point/vertex/corner to move it.
• Support for SpatiaLite < 4.0 is dropped.
• Support for GDAL 1.7 and 1.8 is dropped.
• The widgets in contrib.gis.forms.widgets and the admin’s OpenLayersWidget use the
rather than loader.render_to_string(). If you’re using a custom widget template, you’ll need to be sure your form renderer can locate it. For example, you could use the
renderer.
django.contrib.staticfiles
• collectstatic may now fail during post-processing when using a hashed static files storage if a reference loop exists (e.g. 'foo.css' references 'bar.css' which itself references 'foo.css') or if the chain of files referencing other files is too deep to resolve in several passes. In the latter case, increase the number of passes using
ManifestStaticFilesStorage.max_post_process_passes
1422 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
• When using ManifestStaticFilesStorage, static files not found in the manifest at runtime now raise a ValueError instead of returning an unchanged path.
You can revert to the old behavior by setting
ManifestStaticFilesStorage.manifest_strict
to False.
Database backend API
This section describes changes that may be needed in third-party database backends.
• The DatabaseOperations.time_trunc_sql() method is added to support TimeField truncation.
It accepts a lookup_type and field_name arguments and returns the appropriate SQL to truncate the given time field field_name to a time object with only the given specificity. The lookup_type argument can be either 'hour', 'minute', or 'second'.
• The DatabaseOperations.datetime_cast_time_sql() method is added to support the
lookup. It accepts a field_name and tzname arguments and returns the SQL necessary to cast a datetime value to time value.
• To enable FOR UPDATE SKIP LOCKED has_select_for_update_skip_locked = True .
support, set DatabaseFeatures.
• The new DatabaseFeatures.supports_index_column_ordering attribute specifies if a database allows defining ordering for columns in indexes.
The default value is True and the
DatabaseIntrospection.get_constraints() method should include an 'orders' key in each of the returned dictionaries with a list of 'ASC' and/or 'DESC' values corresponding to the the ordering of each column in the index.
•
no longer calls DatabaseIntrospection.get_indexes() which is deprecated. Custom database backends should ensure all types of indexes are returned by DatabaseIntrospection.
get_constraints()
.
• Renamed the ignores_quoted_identifier_case feature to ignores_table_name_case to more accurately reflect how it is used.
• The name keyword argument is added to the
DatabaseWrapper.create_cursor(self, name=None) method to allow usage of server-side cursors on backends that support it.
Dropped support for PostgreSQL 9.2 and PostGIS 2.0
Upstream support for PostgreSQL 9.2 ends in September 2017. As a consequence, Django 1.11 sets PostgreSQL 9.3
as the minimum version it officially supports.
Support for PostGIS 2.0 is also removed as PostgreSQL 9.2 is the last version to support it.
Also, the minimum supported version of psycopg2 is increased from 2.4.5 to 2.5.4.
LiveServerTestCase binds to port zero
Rather than taking a port range and iterating to find a free port, LiveServerTestCase binds to port zero and relies on the operating system to assign a free port. The DJANGO_LIVE_TEST_SERVER_ADDRESS environment variable is no longer used, and as it’s also no longer used, the manage.py test --liveserver option is removed.
If you need to bind LiveServerTestCase to a specific port, use the port attribute added in Django 1.11.2.
9.1. Final releases 1423
Django Documentation, Release 2.0.dev20170914110741
Protection against insecure redirects in django.contrib.auth and i18n views
LoginView , LogoutView (and the deprecated function-based equivalents), and
protect users from being redirected to non-HTTPS next URLs when the app is running over HTTPS.
QuerySet.get_or_create() and update_or_create() validate arguments
To prevent typos from passing silently,
and
check that their arguments are model fields. This should be backwards-incompatible only in the fact that it might expose a bug in your project.
pytz is a required dependency and support for settings.TIME_ZONE = None is removed
To simplify Django’s timezone handling, pytz is now a required dependency. It’s automatically installed along with
Django.
Support for settings.TIME_ZONE = None is removed as the behavior isn’t commonly used and is questionably useful. If you want to automatically detect the timezone based on the system timezone, you can use tzlocal :
from
tzlocal
import
get_localzone
TIME_ZONE = get_localzone().zone
This works similar to settings.TIME_ZONE = None except that it also sets os.environ['TZ'].
Let us know if there’s a use case where you find you can’t adapt your code to set a TIME_ZONE.
HTML changes in admin templates
<p class="help"> is replaced with a <div> tag to allow including lists inside help text.
Read-only fields are wrapped in <div class="readonly">...</div> instead of <p>...</p> to allow any kind of HTML as the field’s content.
Changes due to the introduction of template-based widget rendering
Some undocumented classes in django.forms.widgets are removed:
• SubWidget
• RendererMixin, ChoiceFieldRenderer, RadioFieldRenderer, CheckboxFieldRenderer
• ChoiceInput, RadioChoiceInput, CheckboxChoiceInput
The undocumented Select.render_option() method is removed.
The Widget.format_output() method is removed. Use a custom widget template instead.
Some widget values, such as <select> options, are now localized if settings.USE_L10N=True. You could revert to the old behavior with custom widget templates that uses the
template tag to turn off localization.
1424 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
django.template.backends.django.Template.render() prohibits non-dict context
For compatibility with multiple template engines, django.template.backends.django.Template.
render() (returned from high-level template loader APIs such as loader.get_template()) must receive a dictionary of context rather than Context or RequestContext. If you were passing either of the two classes, pass a dictionary instead – doing so is backwards-compatible with older versions of Django.
Model state changes in migration operations
To improve the speed of applying migrations, rendering of related models is delayed until an operation that needs them (e.g. RunPython). If you have a custom operation that works with model classes or model instances from the from_state argument in database_forwards() or database_backwards(), you must render model states using the clear_delayed_apps_cache() method as described in
writing your own migration operation .
Miscellaneous
• If no items in the feed have a pubdate or updateddate attribute,
now returns the current UTC date/time, instead of a datetime without any timezone information.
• CSRF failures are logged to the django.security.csrf logger instead of django.request.
•
validation is no longer disabled when running tests. If your application includes tests with custom host names, you must include those host names in
Tests and multiple host names .
• Using a foreign key’s id (e.g. 'field_id') in ModelAdmin.list_display displays the related object’s
ID. Remove the _id suffix if you want the old behavior of the string representation of the object.
• In model forms,
with null=True now saves NULL for blank values instead of empty strings.
• On Oracle,
no longer checks empty strings for uniqueness as the database interprets the value as NULL.
• If you subclass
and override clean(), be sure it calls super().
is called in a new
method so that normalization is applied in cases like model form validation.
• EmailField and URLField no longer accept the strip keyword argument. Remove it because it doesn’t have an effect in older versions of Django as these fields always strip whitespace.
• The checked and selected attribute rendered by form widgets now uses HTML5 boolean syntax rather than XHTML’s checked='checked' and selected='selected'.
•
now clear the prefetch_related() cache.
• To prevent possible loss of saved settings,
now raises an exception if called a second time before calling
• The undocumented DateTimeAwareJSONEncoder alias for
(renamed in Django
1.0) is removed.
• The
is now enabled if
is False and
isn’t specified. This could be backwards-incompatible if you have some
template tags that aren’t thread safe
• The prompt for stale content type deletion no longer occurs after running the migrate command. Use the new
command instead.
9.1. Final releases 1425
Django Documentation, Release 2.0.dev20170914110741
• The admin’s widget for IntegerField uses type="number" rather than type="text".
• Conditional HTTP headers are now parsed and compared according to the RFC 7232 Conditional Requests specification rather than the older
RFC 2616
.
•
no longer adds a Last-Modified header.
According to the
RFC 7234#section-4.2.2
, this header is useless alongside other caching headers that provide an explicit expiration time, e.g.
Expires or Cache-Control.
and
call patch_response_headers() and therefore are also affected by this change.
• In the admin templates, <p class="help"> is replaced with a <div> tag to allow including lists inside help text.
•
no longer sets the Date header as Web servers set that header. It also no longer sets the Content-Length header as this is now done by
•
and
now raise
if they’re called before models of all applications have been loaded. Previously they only required the target application’s models to be loaded and thus could return models without all their relations set up. If you need the old behavior of get_model(), set the require_ready argument to False.
• The unused BaseCommand.can_import_settings attribute is removed.
• The undocumented django.utils.functional.lazy_property is removed.
• For consistency with non-multipart requests, MultiPartParser.parse() now leaves request.POST
immutable. If you’re modifying that QueryDict, you must now first copy it, e.g. request.POST.copy().
• Support for cx_Oracle < 5.2 is removed.
• Support for IPython < 1.0 is removed from the shell command.
• The signature of private API Widget.build_attrs() changed from extra_attrs=None,
**kwargs to base_attrs, extra_attrs=None.
• File-like objects (e.g.,
StringIO and
BytesIO
) uploaded to an
using the test client now require a name attribute with a value that passes the
validator. See the note in
Features deprecated in 1.11
models.permalink() decorator
Use
instead. For example:
from
django.db
import
models
class MyModel
(models.Model):
...
@models.permalink
def url
( self ):
return
( 'guitarist_detail' , [ self
.
slug]) becomes:
from
django.db
import
models
from
django.urls
import
reverse
1426 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
class MyModel
(models.Model):
...
def url
( self ):
return
reverse( 'guitarist_detail' , args=[ self
.
slug])
Miscellaneous
• contrib.auth’s login() and logout() function-based views are deprecated in favor of new class-based views
and
• The unused extra_context parameter of contrib.auth.views.logout_then_login() is deprecated.
• contrib.auth’s password_reset()
, password_change() , password_reset_done()
, and password_reset_complete() function-based views vor of new class-based views
password_change_done() , password_reset_confirm()
, are deprecated in fa-
and
• django.test.runner.setup_databases()
. The old location is deprecated.
is moved to
• django.utils.translation.string_concat() is deprecated in favor of
. string_concat(*strings) can be replaced by format_lazy('{}' *
len(strings), *strings).
• For the PyLibMCCache cache backend, passing pylibmc behavior settings as top-level attributes of
OPTIONS is deprecated. Set them under a behaviors key within OPTIONS instead.
• The host parameter of django.utils.http.is_safe_url() is deprecated in favor of the new allowed_hosts parameter.
• Silencing exceptions raised while rendering the
template tag is deprecated as the behavior is often more confusing than helpful. In Django 2.1, the exception will be raised.
• DatabaseIntrospection.get_indexes() is deprecated in favor of DatabaseIntrospection.
get_constraints()
.
•
now passes a request argument to the authenticate() method of authentication backends. Support for methods that don’t accept request as the first positional argument will be removed in
Django 2.1.
• The USE_ETAGS setting is deprecated in favor of
which now adds the
ETag header to responses regardless of the setting. CommonMiddleware and django.utils.cache.
patch_response_headers() will no longer set ETags when the deprecation ends.
• Model._meta.has_auto_field is deprecated in favor of checking if Model._meta.auto_field
is not None
.
• Using regular expression groups with iLmsu# in url() is deprecated. The only group that’s useful is (?i) for case-insensitive URLs, however, case-insensitive URLs aren’t a good practice because they create multiple entries for search engines, for example. An alternative solution could be to create a
that looks for uppercase characters in the URL and redirects to a lowercase equivalent.
• The renderer argument is added to the
method. Methods that don’t accept that argument will work through a deprecation period.
9.1. Final releases 1427
Django Documentation, Release 2.0.dev20170914110741
1.10 release
Django 1.10.8 release notes
September 5, 2017
Django 1.10.8 fixes a security issue in 1.10.7.
CVE-2017-12794: Possible XSS in traceback section of technical 500 debug page
In older versions, HTML autoescaping was disabled in a portion of the template for the technical 500 debug page.
Given the right circumstances, this allowed a cross-site scripting attack. This vulnerability shouldn’t affect most production sites since you shouldn’t run with DEBUG = True (which makes this page accessible) in your production settings.
Django 1.10.7 release notes
April 4, 2017
Django 1.10.7 fixes two security issues and a bug in 1.10.6.
CVE-2017-7233: Open redirect and possible XSS attack via user-supplied numeric redirect URLs
Django relies on user input in some cases (e.g.
django.contrib.auth.views.login()
and
rect the user to an “on success” URL. The security check for these redirects (namely django.utils.http.
is_safe_url()
) considered some numeric URLs (e.g. http:999999999) “safe” when they shouldn’t be.
Also, if a developer relies on is_safe_url() to provide safe redirect targets and puts such a URL into a link, they could suffer from an XSS attack.
CVE-2017-7234: Open redirect vulnerability in django.views.static.serve()
A maliciously crafted URL to a Django site using the
view could redirect to any other domain. The view no longer does any redirects as they don’t provide any known, useful functionality.
Note, however, that this view has always carried a warning that it is not hardened for production use and should be used only as a development aid.
Bugfixes
• Made admin’s
RelatedFieldWidgetWrapper value_omitted_from_data() method ( #27905 ).
use
• Fixed model form default fallback for SelectMultiple ( #27993 ).
the
Django 1.10.6 release notes
March 1, 2017
Django 1.10.6 fixes several bugs in 1.10.5.
wrapped widget’s
1428 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
Bugfixes
• Fixed ClearableFileInput’s “Clear” checkbox on model form fields where the model field has a default ( #27805 ).
• Fixed RequestDataTooBig and TooManyFieldsSent exceptions crashing rather than generating a bad request response ( #27820 ).
• Fixed a crash on Oracle and PostgreSQL when subtracting DurationField or IntegerField from
DateField
( #27828 ).
• Fixed query expression date subtraction accuracy on PostgreSQL for differences larger than a month ( #27856 ).
• Fixed a GDALException raised by GDALClose on GDAL ≥ 2.0 ( #27479 ).
Django 1.10.5 release notes
January 4, 2017
Django 1.10.5 fixes several bugs in 1.10.4.
Bugfixes
• Fixed a crash in the debug view if request.user can’t be retrieved, such as if the database is unavailable
( #27567 ).
• Fixed occasional missing plural forms in JavaScriptCatalog ( #27418 ).
• Fixed a regression in the timesince and timeuntil filters that caused incorrect results for dates in a leap year ( #27637 ).
• Fixed a regression where collectstatic overwrote newer files in remote storages ( #27658 ).
Django 1.10.4 release notes
December 1, 2016
Django 1.10.4 fixes several bugs in 1.10.3.
Bugfixes
• Quoted the Oracle test user’s password in queries to fix the “ORA-00922: missing or invalid option” error when the password starts with a number or special character ( #27420 ).
• Fixed incorrect app_label / model_name arguments for allow_migrate() in makemigrations migration consistency checks ( #27461 ).
• Made Model.delete(keep_parents=True) preserve parent reverse relationships in multi-table inheritance ( #27407 ).
• Fixed a QuerySet.update() crash on SQLite when updating a DateTimeField with an F() expression and a timedelta ( #27544 ).
• Prevented LocaleMiddleware from redirecting on URLs that should return 404 when using prefix_default_language=False ( #27402 ).
9.1. Final releases 1429
Django Documentation, Release 2.0.dev20170914110741
• Prevented an unnecessary index from being created on an InnoDB ForeignKey when the field was added after the model was created ( #27558 ).
Django 1.10.3 release notes
November 1, 2016
Django 1.10.3 fixes two security issues and several bugs in 1.10.2.
User with hardcoded password created when running tests on Oracle
When running tests with an Oracle database, Django creates a temporary database user. In older versions, if a password isn’t manually specified in the database settings TEST dictionary, a hardcoded password is used. This could allow an attacker with network access to the database server to connect.
This user is usually dropped after the test suite completes, but not when using the manage.py test --keepdb option or if the user has an active session (such as an attacker’s connection).
A randomly generated password is now used for each test run.
DNS rebinding vulnerability when DEBUG=True
Older versions of Django don’t validate the Host header against settings.ALLOWED_HOSTS when settings.
DEBUG=True
. This makes them vulnerable to a DNS rebinding attack .
While Django doesn’t ship a module that allows remote code execution, this is at least a cross-site scripting vector, which could be quite serious if developers load a copy of the production database in development or connect to some production services for which there’s no development instance, for example. If a project uses a package like the django-debug-toolbar , then the attacker could execute arbitrary SQL, which could be especially bad if the developers connect to the database with a superuser account.
settings.ALLOWED_HOSTS
is now validated regardless of DEBUG. For convenience, if ALLOWED_HOSTS is empty and DEBUG=True, the following variations of localhost are allowed ['localhost', '127.0.0.1',
'::1']
. If your local settings file has your production ALLOWED_HOSTS value, you must now omit it to get those fallback values.
Bugfixes
• Allowed User.is_authenticated and User.is_anonymous properties to be tested for set membership ( #27309 ).
• Fixed a performance regression when running migrate in projects with RenameModel operations ( #27279 ).
• Added model_name to the allow_migrate() calls in makemigrations ( #27200 ).
• Made the JavaScriptCatalog view respect the packages argument; previously it was ignored ( #27374 ).
• Fixed QuerySet.bulk_create() on PostgreSQL when the number of objects is a multiple plus one of batch_size
( #27385 ).
• Prevented i18n_patterns() from using too much of the URL as the language to fix a use case for prefix_default_language=False
( #27063 ).
• Replaced a possibly incorrect redirect from SessionMiddleware when a session is destroyed in a concurrent request with a SuspiciousOperation to indicate that the request can’t be completed ( #27363 ).
1430 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
Django 1.10.2 release notes
October 1, 2016
Django 1.10.2 fixes several bugs in 1.10.1.
Bugfixes
• Fixed a crash in MySQL database validation where SELECT @@sql_mode doesn’t return a result ( #27180 ).
• Allowed combining contrib.postgres.search.SearchQuery with more than one & or | operators
( #27143 ).
• Disabled system check for URL patterns beginning with a ‘/’ when APPEND_SLASH=False ( #27238 ).
• Fixed model form default fallback for CheckboxSelectMultiple, MultiWidget, FileInput,
SplitDateTimeWidget
, SelectDateWidget, and SplitArrayWidget ( #27186 ). Custom widgets affected by this issue should implement
• Fixed a crash in runserver logging during a “Broken pipe” error ( #27271 ).
• Fixed a regression where unchanged localized date/time fields were listed as changed in the admin’s model history messages ( #27302 ).
Django 1.10.1 release notes
September 1, 2016
Django 1.10.1 fixes several bugs in 1.10.
Bugfixes
• Fixed a crash in MySQL connections where SELECT @@SQL_AUTO_IS_NULL doesn’t return a result
( #26991 ).
• Allowed User.is_authenticated and User.is_anonymous properties to be compared using ==, !=, and | ( #26988 , #27154 ).
• Removed the broken BaseCommand.usage() method which was for optparse support ( #27000 ).
• Fixed a checks framework crash with an empty Meta.default_permissions ( #26997 ).
• Fixed a regression in the number of queries when using RadioSelect with a ModelChoiceField form field ( #27001 ).
• Fixed a crash if request.META['CONTENT_LENGTH'] is an empty string ( #27005 ).
• Fixed the isnull lookup on a ForeignKey with its to_field pointing to a CharField or pointing to a
CharField defined with primary_key=True ( #26983 ).
• Prevented the migrate command from raising InconsistentMigrationHistory in the presence of unapplied squashed migrations ( #27004 ).
• Fixed a regression in Client.force_login() which required specifying a backend rather than automatically using the first one if multiple backends are configured ( #27027 ).
• Made QuerySet.bulk_create() properly initialize model instances on backends, such as PostgreSQL, that support returning the IDs of the created records so that many-to-many relationships can be used on the new objects ( #27026 ).
9.1. Final releases 1431
Django Documentation, Release 2.0.dev20170914110741
• Fixed crash of django.views.static.serve() with show_indexes enabled ( #26973 ).
• Fixed ClearableFileInput to avoid the required HTML attribute when initial data exists ( #27037 ).
• Fixed annotations with database functions when combined with lookups on PostGIS ( #27014 ).
• Reallowed the {% for %} tag to unpack any iterable ( #27058 ).
• Made makemigrations skip inconsistent history checks on non-default databases if database routers aren’t in use or if no apps can be migrated to the database ( #27054 , #27110 , #27142 ).
• Removed duplicated managers in Model._meta.managers ( #27073 ).
• Fixed contrib.admindocs crash when a view is in a class, such as some of the admin views ( #27018 ).
• Reverted a few admin checks that checked field.many_to_many back to isinstance(field, models.ManyToManyField) since it turned out the checks weren’t suitable to be generalized like that
( #26998 ).
• Added the database alias to the
InconsistentMigrationHistory message raised by makemigrations and migrate ( #27089 ).
• Fixed the creation of ContentType and Permission objects for models of applications without migrations when calling the migrate command with no migrations to apply ( #27044 ).
• Included the already applied migration state changes in the Apps instance provided to the pre_migrate signal receivers to allow ContentType renaming to be performed on model rename ( #27100 ).
• Reallowed subclassing UserCreationForm without USERNAME_FIELD in Meta.fields ( #27111 ).
• Fixed a regression in model forms where model fields with a default that didn’t appear in POST data no longer used the default ( #27039 ).
Django 1.10 release notes
August 1, 2016
Welcome to Django 1.10!
These release notes cover the
new features , as well as some
backwards incompatible changes
you’ll want to be aware of when upgrading from Django 1.9 or older versions. We’ve
that have reached the end of their deprecation cycle, and we’ve
begun the deprecation process for some features .
See the
Upgrading Django to a newer version
guide if you’re updating an existing project.
Python compatibility
Like Django 1.9, Django 1.10 requires Python 2.7, 3.4, or 3.5. We highly recommend and only officially support the latest release of each series.
What’s new in Django 1.10
Full text search for PostgreSQL
django.contrib.postgres
now includes a
collection of database functions
to allow the use of the full text search engine. You can search across multiple fields in your relational database, combine the searches with other lookups, use different language configurations and weightings, and rank the results by relevance.
1432 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
It also now includes trigram support, using the
lookup, and the
and
expressions.
New-style middleware
A new style of middleware is introduced
to solve the lack of strict request/response layering of the old-style of middleware described in DEP 0005 .
You’ll need to
and switch from the
MIDDLEWARE_CLASSES setting to the new
setting to take advantage of the improvements.
Official support for Unicode usernames
The
model in django.contrib.auth originally only accepted ASCII letters and numbers in usernames.
Although it wasn’t a deliberate choice, Unicode characters have always been accepted when using Python 3.
The username validator now explicitly accepts Unicode characters by default on Python 3 only. This default behavior can be overridden by changing the
attribute of the User model, or to any proxy of that model, using either
or
UnicodeUsernameValidator . Custom user models
may also use those validators.
Minor features django.contrib.admin
• For sites running on a subpath, the default
at the top of each admin page will now point to request.META['SCRIPT_NAME'] if set, instead of /.
• The success message that appears after adding or editing an object now contains a link to the object’s change form.
• All inline JavaScript is removed so you can enable the Content-Security-Policy HTTP header if you wish.
• The new
attribute allows specifying classes on inline fieldsets. Inlines with a collapse class will be initially collapsed and their header will have a small “show” link.
• If a user doesn’t have the add permission, the object-tools block on a model’s changelist will now be rendered (without the add button, of course). This makes it easier to add custom tools in this case.
• The
model now stores change messages in a JSON structure so that the message can be dynamically translated using the current active language. A new LogEntry.get_change_message() method is now the preferred way of retrieving the change message.
• Selected objects for fields in ModelAdmin.raw_id_fields now have a link to object’s change form.
• Added “No date” and “Has date” choices for DateFieldListFilter if the field is nullable.
• The jQuery library embedded in the admin is upgraded from version 2.1.4 to 2.2.3.
django.contrib.auth
• Added support for the
. It’s recommended over PBKDF2, however, it’s not the default as
it requires a third-party library.
9.1. Final releases 1433
Django Documentation, Release 2.0.dev20170914110741
• The default iteration count for the PBKDF2 password hasher has been increased by 25%.
This backwards compatible change will not affect users who have subclassed django.contrib.auth.hashers.
PBKDF2PasswordHasher to change the default value.
• The
view sends “no-cache” headers to prevent an issue where Safari caches redirects and prevents a user from being able to log out.
• Added the optional backend argument to
to allow using it without credentials.
• The new
setting controls the redirect of the
view, if the view doesn’t get a next_page argument.
• The new redirect_authenticated_user parameter for the
view allows redirecting authenticated users visiting the login page.
• The new
and
AllowAllUsersRemoteUserBackend
ignore the value of User.is_active, while
and
now reject inactive users.
django.contrib.gis
•
now accept expressions as the distance value parameter.
• The new
property computes the union of all the elements of this geometry.
• Added the
binary predicate.
• Added the
method and
and
attributes.
• Added support for the
aggregate and
function on SpatiaLite.
• Added support for the
functions on MySQL.
• Added support for instantiating empty GEOS geometries.
• The new
and
properties of
allow controlling output of the fractional part of the coordinates in WKT.
• Added the
and
properties.
• The
now outputs the primary key of objects in the properties dictionary if specific fields aren’t specified.
• The ability to replicate input data on the
method was added. Band data can now be updated with repeated values efficiently.
• Added database functions
and
lookup, all for PostGIS. This allows filtering and repairing invalid geometries on the database side.
• Added raster support for all
django.contrib.postgres
• For convenience,
now casts its keys and values to strings.
django.contrib.sessions
• The
management command now removes file-based sessions.
1434 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
django.contrib.sites
• The
model now supports
django.contrib.staticfiles
• The
template tag now uses django.contrib.staticfiles if it’s in INSTALLED_APPS.
This is especially useful for third-party apps which can now always use {% load static %} (instead of
{% load staticfiles %} or {% load static from staticfiles %}) and not worry about whether or not the staticfiles app is installed.
• You can
the collectstatic --ignore option with a custom AppConfig.
Cache
• The file-based cache backend now uses the highest pickling protocol.
CSRF
• The default
, views.csrf.csrf_failure() now accepts an optional
template_name parameter, defaulting to '403_csrf.html', to control the template used to render the page.
• To protect against BREACH attacks, the CSRF protection mechanism now changes the form token value on every request (while keeping an invariant secret which can be used to validate the different tokens).
Database backends
• Temporal data subtraction was unified on all backends.
• If the database supports it, can_return_ids_from_bulk_insert=True backends and can implement set DatabaseFeatures.
DatabaseOperations.
fetch_returned_insert_ids() to set primary keys on objects created using QuerySet.
bulk_create()
.
• Added keyword arguments to the as_sql() methods of various expressions (Func, When, Case, and
OrderBy
) to allow database backends to customize them without mutating self, which isn’t safe when using different database backends. See the arg_joiner and **extra_context parameters of
for an example.
File Storage
• Storage backends now present a timezone-aware API with new methods
is True and a naive datetime in the local timezone otherwise.
• The new
method makes it easier to implement custom storages that don’t use the os.path calls previously in
9.1. Final releases 1435
Django Documentation, Release 2.0.dev20170914110741
Forms
• Form and widget Media is now served using
if installed.
• The <input> tag rendered by
now includes a minlength attribute if the field has a min_length
.
• Required form fields now have the required
HTML attribute.
Set the new
attribute to False to disable it. The required attribute isn’t included on forms of formsets because the browser validation may not be correct when adding and deleting formsets.
Generic Views
• The
class can now be imported from django.views.
Internationalization
• The
helper function can now be used in a root URLConf specified using
• By setting the new prefix_default_language parameter for
to False, you can allow accessing the default language without a URL prefix.
•
now returns a 204 status code (No Content) for AJAX requests when there is no next parameter in POST or GET.
• The
and
class-based views supersede the deprecated javascript_catalog() and json_catalog() function-based views.
The new views are almost equivalent to the old ones except that by default the new views collect all JavaScript strings in the djangojs translation domain from all installed apps rather than only the JavaScript strings from
Management Commands
•
now returns the value returned from the command.handle() method.
• The new
option allows specifying the message level that will cause the command to exit with a non-zero status.
• The new
option makes the command exit with a non-zero status when model changes without migrations are detected.
•
now displays the path to the migration files that it generates.
• The
option now accepts python to force use of the “plain” Python interpreter.
• The new
option lets you run a command as Django and exit, instead of opening the interactive shell.
• Added a warning to
if a proxy model is specified (which results in no output) without its concrete parent.
• The new
BaseCommand.requires_migrations_checks
attribute may be set to True if you want your command to print a warning, like
does, if the set of migrations on disk don’t match the migrations in the database.
• To assist with testing,
now accepts a command object as the first argument.
• The
command supports tab completion on systems using libedit, e.g. macOS.
1436 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
• The
command lets you choose what tables should be inspected by specifying their names as arguments.
Migrations
• Added support for serialization of enum.Enum objects.
• Added the elidable argument to the
and
operations to allow them to be removed when squashing migrations.
• Added support for
by setting the atomic attribute on a Migration.
• The migrate and makemigrations commands now
check for a consistent migration history . If they find
some unapplied dependencies of an applied migration, InconsistentMigrationHistory is raised.
• The
and
signals now dispatch their migration plan and apps.
Models
• Reverse foreign keys from proxy models are now propagated to their concrete class. The reverse relation attached by a
pointing to a proxy model is now accessible as a descriptor on the proxied model class and may be referenced in queryset filtering.
• The new
method returns the database column data type for fields such as
ForeignKey and OneToOneField that point to another field.
• The
class attribute is added to
. This attribute can be used to set the number of arguments the
function accepts.
• Added
which acts much like an
except that it is guaranteed to fit numbers from
1 to 9223372036854775807.
•
may be called without any arguments to return all objects in the queryset.
•
now supports app label and class interpolation using the '%(app_label)s' and
'%(class)s' strings.
• Allowed overriding model fields inherited from abstract base classes.
• The
function is now a public API.
•
sets the primary key on objects when using PostgreSQL.
• Added the
database function.
• A proxy model may now inherit multiple proxy models that share a common non-abstract parent class.
• Added
functions to extract datetime components as integers, such as year and hour.
• Added
functions to truncate a date or datetime to a significant component. They enable queries like sales-per-day or sales-per-hour.
• Model.__init__() now sets values of virtual fields from its keyword arguments.
• The new
and
options allow controlling the
and
_default_manager , respectively.
9.1. Final releases 1437
Django Documentation, Release 2.0.dev20170914110741
Requests and Responses
• Added request.user to the debug view.
• Added
methods
and
to make an instance a stream-like object and allow wrapping it with io.TextIOWrapper
.
• Added the
and
attributes which are parsed from the
CONTENT_TYPE header.
• The parser for request.COOKIES is simplified to better match the behavior of browsers. request.
COOKIES may now contain cookies that are invalid according to RFC 6265 but are possible to set via document.cookie
.
Serialization
• The django.core.serializers.json.DjangoJSONEncoder now knows how to serialize lazy strings, typically used for translatable content.
Templates
• Added the autoescape option to the
backend and the
class.
• Added the is and is not comparison operators to the
tag.
• Allowed
to order a list of lists by an element at a specified index.
• The
context processor contains queries for all database aliases instead of only the default alias.
• Added relative path support for string arguments of the
and
template tags.
Tests
• To better catch bugs,
now checks deferrable database constraints at the end of each test.
• Tests and test cases can be
and run selectively with the new
and
options.
• You can now login and use sessions with the test client even if
is not in
URLs
• An addition in
allows URL resolving that happens outside of the request/response cycle
(e.g. in management commands and standalone scripts) to take
into account when it is set.
Validators
•
now limits the length of domain name labels to 63 characters and the total length of domain names to 253 characters per RFC 1034 .
•
now accepts an optional allow_negative boolean parameter, defaulting to
False , to allow negative integers.
1438 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
Backwards incompatible changes in 1.10
Warning: In addition to the changes outlined in this section, be sure to review the
for the features that have reached the end of their deprecation cycle and therefore been removed. If you haven’t updated your code within the deprecation timeline for a given feature, its removal may appear as a backwards incompatible change.
Database backend API
• GIS’s AreaField uses an unspecified underlying numeric type that could in practice be any numeric Python type. decimal.Decimal values retrieved from the database are now converted to float to make it easier to combine them with values used by the GIS libraries.
• In order to enable temporal subtraction you must set the supports_temporal_subtraction database feature flag to True and implement the DatabaseOperations.subtract_temporals() method.
This method should return the SQL and parameters required to compute the difference in microseconds between the lhs and rhs arguments in the datatype used to store
select_related() prohibits non-relational fields for nested relations
Django 1.8 added validation for non-relational fields in select_related():
>>> Book.objects.select_related( 'title' )
Traceback (most recent call last):
...
FieldError : Non-relational field given in select_related: 'title'
But it didn’t prohibit nested non-relation fields as it does now:
>>> Book.objects.select_related( 'author__name' )
Traceback (most recent call last):
...
FieldError : Non-relational field given in select_related: 'name'
_meta.get_fields() returns consistent reverse fields for proxy models
Before Django 1.10, the
method returned different reverse fields when called on a proxy model compared to its proxied concrete class. This inconsistency was fixed by returning the full set of fields pointing to a concrete class or one of its proxies in both cases.
AbstractUser.username max_length increased to 150
A migration for
django.contrib.auth.models.User.username
is included. If you have a custom user model inheriting from AbstractUser, you’ll need to generate and apply a database migration for your user model.
We considered an increase to 254 characters to more easily allow the use of email addresses (which are limited to 254 characters) as usernames but rejected it due to a MySQL limitation. When using the utf8mb4 encoding
(recommended for proper Unicode support), MySQL can only create unique indexes with 191 characters by default.
Therefore, if you need a longer length, please use a custom user model.
9.1. Final releases 1439
Django Documentation, Release 2.0.dev20170914110741
If you want to preserve the 30 character limit for usernames, use a custom form when creating a user or changing usernames:
from
django.contrib.auth.forms
import
UserCreationForm
class MyUserCreationForm
(UserCreationForm): username = forms.CharField( max_length= 30 , help_text= 'Required. 30 characters or fewer. Letters, digits and @/./+/-/_
˓→ only.' ,
)
If you wish to keep this restriction in the admin, set UserAdmin.add_form to use this form:
from
django.contrib.auth.admin
import
UserAdmin as BaseUserAdmin
from
django.contrib.auth.models
import
User
class UserAdmin
(BaseUserAdmin): add_form = MyUserCreationForm admin.site.unregister(User) admin.site.register(User, UserAdmin)
Dropped support for PostgreSQL 9.1
Upstream support for PostgreSQL 9.1 ends in September 2016. As a consequence, Django 1.10 sets PostgreSQL 9.2
as the minimum version it officially supports.
runserver output goes through logging
Request and response handling of the runserver command is sent to the
logger instead of to sys.
stderr
. If you disable Django’s logging configuration or override it with your own, you’ll need to add the appropriate logging configuration if you want to see that output:
'formatters' : {
'django.server' : {
'()' : 'django.utils.log.ServerFormatter' ,
'format' : '[%(server_time)s] %(message)s' ,
}
},
'handlers' : {
'django.server' : {
'level' : 'INFO' ,
'class' : 'logging.StreamHandler' ,
'formatter' : 'django.server' ,
},
},
'loggers' : {
'django.server' : {
'handlers' : [ 'django.server' ],
'level' : 'INFO' ,
'propagate' : False,
}
}
1440 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
auth.CustomUser
and auth.ExtensionUser test models were removed
Since the introduction of migrations for the contrib apps in Django 1.8, the tables of these custom user test models were not created anymore making them unusable in a testing context.
Apps registry is no longer auto-populated when unpickling models outside of Django
The apps registry is no longer auto-populated when unpickling models. This was added in Django 1.7.2 as an attempt to allow unpickling models outside of Django, such as in an RQ worker, without calling django.setup(), but it creates the possibility of a deadlock. To adapt your code in the case of RQ, you can provide your own worker script that calls django.setup().
Removed null assignment check for non-null foreign key fields
In older versions, assigning None to a non-nullable ForeignKey or OneToOneField raised
ValueError('Cannot assign None: "model.field" does not allow null values.') .
For consistency with other model fields which don’t have a similar check, this check is removed.
Removed weak password hashers from the default PASSWORD_HASHERS setting
Django 0.90 stored passwords as unsalted MD5. Django 0.91 added support for salted SHA1 with automatic upgrade of passwords when a user logs in. Django 1.4 added PBKDF2 as the default password hasher.
If you have an old Django project with MD5 or SHA1 (even salted) encoded passwords, be aware that these can be cracked fairly easily with today’s hardware. To make Django users acknowledge continued use of weak hashers, the following hashers are removed from the default
setting:
'django.contrib.auth.hashers.SHA1PasswordHasher'
'django.contrib.auth.hashers.MD5PasswordHasher'
'django.contrib.auth.hashers.UnsaltedSHA1PasswordHasher'
'django.contrib.auth.hashers.UnsaltedMD5PasswordHasher'
'django.contrib.auth.hashers.CryptPasswordHasher'
Consider using a
to strengthen the hashes in your database. If that’s not feasible, add the
setting to your project and add back any hashers that you need.
You can check if your database has any of the removed hashers like this:
from
django.contrib.auth
import
get_user_model
User = get_user_model()
# Unsalted MD5/SHA1:
User.objects.filter(password__startswith= 'md5$$' )
User.objects.filter(password__startswith= 'sha1$$' )
# Salted MD5/SHA1:
User.objects.filter(password__startswith= 'md5$' ).exclude(password__startswith= 'md5$$' )
User.objects.filter(password__startswith= 'sha1$' ).exclude(password__startswith= 'sha1$$
˓→
' )
# Crypt hasher:
User.objects.filter(password__startswith= 'crypt$$' )
from
django.db.models
import
CharField
from
django.db.models.functions
import
Length
CharField.register_lookup(Length)
9.1. Final releases 1441
Django Documentation, Release 2.0.dev20170914110741
# Unsalted MD5 passwords might not have an 'md5$$' prefix:
User.objects.filter(password__length= 32 )
Field.get_prep_lookup() and Field.get_db_prep_lookup() methods are removed
If you have a custom field that implements either of these methods, register a custom lookup for it. For example:
from
django.db.models
import
Field
from
django.db.models.lookups
import
Exact
class MyField
(Field):
...
class MyFieldExact
(Exact):
def get_prep_lookup
( self ):
# do_custom_stuff_for_myfield
....
MyField.register_lookup(MyFieldExact)
django.contrib.gis
• Support for SpatiaLite < 3.0 and GEOS < 3.3 is dropped.
• The add_postgis_srs() backwards compatibility alias for django.contrib.gis.utils.
add_srs_entry() is removed.
• On Oracle/GIS, the
aggregate function now returns a float instead of decimal.Decimal. (It’s still wrapped in a measure of square meters.)
• The default
representation (WKT output) is trimmed by default. That is, instead of POINT
(23.0000000000000000 5.5000000000000000) , you’ll get POINT (23 5.5).
Maximum size of a request body and the number of GET/POST parameters is limited
Two new settings help mitigate denial-of-service attacks via large requests:
•
limits the size that a request body may be. File uploads don’t count towards this limit.
•
limits the number of GET/POST parameters that are parsed.
Applications that receive unusually large form posts may need to tune these settings.
Miscellaneous
• The repr() of a QuerySet is wrapped in <QuerySet > to disambiguate it from a plain list when debugging.
• utils.version.get_version() returns PEP 440 compliant release candidate versions (e.g. ‘1.10rc1’ instead of ‘1.10c1’).
1442 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
• CSRF token values are now required to be strings of 64 alphanumerics; values of 32 alphanumerics, as set by older versions of Django by default, are automatically replaced by strings of 64 characters. Other values are considered invalid. This should only affect developers or users who replace these tokens.
• The LOGOUT_URL setting is removed as Django hasn’t made use of it since pre-1.0. If you use it in your project, you can add it to your project’s settings. The default value was '/accounts/logout/'.
• Objects with a close() method such as files and generators passed to
are now closed immediately instead of when the WSGI server calls close() on the response.
• A redundant transaction.atomic() call in QuerySet.update_or_create() is removed. This may affect query counts tested by TransactionTestCase.assertNumQueries().
• Support for skip_validation in BaseCommand.execute(**options) is removed.
skip_checks
(added in Django 1.7) instead.
Use
•
now raises a CommandError instead of showing a warning when the specified fixture file is not found.
• Instead of directly accessing the LogEntry.change_message attribute, it’s now better to call the
LogEntry.get_change_message() method which will provide the message in the current language.
• The default error views now raise TemplateDoesNotExist if a nonexistent template_name is specified.
• The unused choices keyword argument of the Select and SelectMultiple widgets’ render() method is removed. The choices argument of the render_options() method is also removed, making selected_choices the first argument.
• Tests that violate deferrable database constraints will now error when run on a database that supports deferrable constraints.
• Built-in management commands now use indexing of keys in options, e.g. options['verbosity'], instead of options.get() and no longer perform any type coercion. This could be a problem if you’re calling commands using Command.execute() (which bypasses the argument parser that sets a default value) instead of
. Instead of calling Command.execute(), pass the command object as the
first argument to call_command().
•
and
now reject inactive users. This means that inactive users can’t login and will be logged out if they are switched from is_active=True to False. If you need the previous behavior, use the new
or
AllowAllUsersRemoteUserBackend
in
instead.
• In light of the previous change, the test client’s
method no longer always rejects inactive users but instead delegates this decision to the authentication backend.
also delegates the decision to the authentication backend, so if you’re using the default backends, you need to use an active user.
•
django.views.i18n.set_language()
may now return a 204 status code for AJAX requests.
• The base_field attribute of
is now a type of field, not an instance of a field. If you have created a custom subclass of
, you should change the base_field attribute.
• Middleware classes are now initialized when the server starts rather than during the first request.
• If you override is_authenticated() or is_anonymous() in a custom user model, you must convert them to attributes or properties as described in
• When using
ModelAdmin.save_as=True , the “Save as new” button now redirects to the change view
for the new object instead of to the model’s changelist.
If you need the previous behavior, set the new
attribute to False.
• Required form fields now have the required
HTML attribute.
Set the
attribute to False to disable it. You could also add the novalidate
9.1. Final releases 1443
Django Documentation, Release 2.0.dev20170914110741
attribute to <form> if you don’t want browser validation. To disable the required attribute on custom widgets, override the
Widget.use_required_attribute()
method.
• The WSGI handler no longer removes content of responses from HEAD requests or responses with a status_code of 100-199, 204, or 304. Most Web servers already implement this behavior. Responses retrieved using the Django test client continue to have these “response fixes” applied.
• Model.__init__() now receives django.db.models.DEFERRED as the value of deferred fields.
• The Model._deferred attribute is removed as dynamic model classes when using QuerySet.defer() and only() is removed.
•
no longer replaces '\' with '/'. This behavior is moved to
since this is a storage specific implementation detail. Any Windows user with a custom storage implementation that relies on this behavior will need to implement it in the custom storage’s save() method.
• Private
methods get_directory_name() and get_filename() are no longer called
(and are now deprecated) which is a backwards incompatible change for users overriding those methods on custom fields. To adapt such code, override FileField.generate_filename() or
instead. It might be possible to use
also.
• The subject of mail sent by AdminEmailHandler is no longer truncated at 989 characters. If you were counting on a limited length, truncate the subject yourself.
• Private expressions django.db.models.expressions.Date and DateTime are removed. The new
expressions provide the same functionality.
• The _base_manager and _default_manager attributes are removed from model instances. They remain accessible on the model class.
• Accessing a deleted field on a model instance, e.g. after del obj.field, reloads the field’s value instead of raising AttributeError.
• If you subclass
AbstractBaseUser and override clean()
, be sure it calls super()
.
AbstractBaseUser.normalize_username()
is called in a new
method.
• Private API django.forms.models.model_to_dict() returns a queryset rather than a list of primary keys for ManyToManyFields.
• If django.contrib.staticfiles is installed, the
template tag uses the staticfiles storage to construct the URL rather than simply joining the value with STATIC_ROOT. The new approach encodes the URL, which could be backwards-incompatible in cases such as including a fragment in a path, e.g. {% static 'img.svg#fragment' %}
, since the # is encoded as %23. To adapt, move the fragment outside the template tag: {% static 'img.svg' %}#fragment.
• When
is True, localization is now applied for the
and
filters when no format string is specified. The DATE_FORMAT and TIME_FORMAT specifiers from the active locale are used instead of the settings of the same name.
Features deprecated in 1.10
Direct assignment to a reverse foreign key or many-to-many relation
Instead of assigning related objects using direct assignment:
>>> new_list = [obj1, obj2, obj3]
>>> e.related_set = new_list
1444 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
Use the
method added in Django 1.9:
>>> e.related_set.set([obj1, obj2, obj3])
This prevents confusion about an assignment resulting in an implicit save.
Non-timezone-aware Storage API
The old, non-timezone-aware methods accessed_time(), created_time(), and modified_time() are deprecated in favor of the new get_*_time() methods.
Third-party storage backends should implement the new methods and mark the old ones as deprecated. Until then, the new get_*_time() methods on the base
class convert datetimes from the old methods as required and emit a deprecation warning as they do so.
Third-party storage backends may retain the old methods as long as they wish to support earlier versions of Django.
django.contrib.gis
• The get_srid() and set_srid() methods of
are deprecated in favor of the
property.
• The get_x(), set_x(), get_y(), set_y(), get_z(), and set_z() methods of
are deprecated in favor of the x, y, and z properties.
• The get_coords() and set_coords() methods of
are deprecated in favor of the tuple property.
• The cascaded_union property of
is deprecated in favor of the
property.
• The django.contrib.gis.utils.precision_wkt() function is deprecated in favor of
CommaSeparatedIntegerField model field
CommaSeparatedIntegerField is deprecated in favor of
validate_comma_separated_integer_list()
validator:
from
django.core.validators
import
validate_comma_separated_integer_list
from
django.db
import
models with
class MyModel
(models.Model): numbers = models.CharField(..., validators=[validate_comma_separated_integer_
˓→ list]) the
If you’re using Oracle,
CharField uses a different database field type (NVARCHAR2) than
CommaSeparatedIntegerField
(VARCHAR2).
Depending on your database settings, this might imply a different encoding, and thus a different length (in bytes) for the same contents. If your stored values are longer than the 4000 byte limit of NVARCHAR2, you should use TextField (NCLOB) instead. In this case, if you have any queries that group by the field (e.g. annotating the model with an aggregation or using distinct()) you’ll need to change them (to defer the field).
Using a model name as a query lookup when default_related_name is set
Assume the following models:
9.1. Final releases 1445
Django Documentation, Release 2.0.dev20170914110741
from
django.db
import
models
class Foo
(models.Model):
pass class Bar
(models.Model): foo = models.ForeignKey(Foo)
class Meta
: default_related_name = 'bars'
In older versions,
couldn’t be used as a query lookup. This is fixed and support for the old lookup name is deprecated. For example, since default_related_name is set in model Bar, instead of using the model name bar as the lookup:
>>> bar = Bar.objects.get(pk= 1 )
>>> Foo.objects.get(bar=bar) use the default_related_name bars:
>>> Foo.objects.get(bars=bar)
__search query lookup
The search lookup, which supports MySQL only and is extremely limited in features, is deprecated. Replace it with a custom lookup:
from
django.db
import
models
class Search
(models.Lookup): lookup_name = 'search'
def as_mysql
( self , compiler, connection): lhs, lhs_params = self
.
process_lhs(compiler, connection) rhs, rhs_params = self
.
process_rhs(compiler, connection) params = lhs_params + rhs_params
return
'MATCH (%s) AGAINST (%s IN BOOLEAN MODE)'
%
(lhs, rhs), params models.CharField.register_lookup(Search) models.TextField.register_lookup(Search)
Using User.is_authenticated() and User.is_anonymous() as methods
The is_authenticated() and is_anonymous() methods of
and
classes are now properties. They will still work as methods until Django 2.0, but all usage in Django now uses attribute access.
For example, if you use
and want to know whether the user is currently logged-in you would use:
if
request.user.is_authenticated:
...
# Do something for logged-in users.
else
:
...
# Do something for anonymous users.
1446 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
instead of request.user.is_authenticated().
This change avoids accidental information leakage if you forget to call the method, e.g.:
if
request.user.is_authenticated:
return
sensitive_information
If you override these methods in a custom user model, you must change them to properties or attributes.
Django uses a CallableBool object to allow these attributes to work as both a property and a method. Thus, until the deprecation period ends, you cannot compare these properties using the is operator. That is, the following won’t work:
if
request.user.is_authenticated is True:
...
Custom manager classes available through prefetch_related must define a
_apply_rel_filters() method
If you defined a custom manager class available through
you must make sure it defines a
_apply_rel_filters() method.
This method must accept a
instance as its single argument and return a filtered version of the queryset for the model instance the manager is bound to.
The “escape” half of django.utils.safestring
The mark_for_escaping() function and the classes it uses: EscapeData, EscapeBytes, EscapeText,
EscapeString
, and EscapeUnicode are deprecated.
As a result, the “lazy” behavior of the escape filter (where it would always be applied as the last filter no matter where in the filter chain it appeared) is deprecated. The filter will change to immediately apply
in Django 2.0.
Manager.use_for_related_fields
and inheritance changes
Manager.use_for_related_fields
is deprecated in favor of setting
on the model.
Model Manager inheritance will follow MRO inheritance rules in Django 2.0, changing the current behavior where managers defined on non-abstract base classes aren’t inherited by child classes. A deprecating warning with instructions on how to adapt your code is raised if you have any affected managers. You’ll either redeclare a manager from an abstract model on the child class to override the manager from the concrete model, or you’ll set the model’s
Meta.manager_inheritance_from_future=True option to opt-in to the new inheritance behavior.
During the deprecation period, use_for_related_fields will be honored and raise a warning, even if a base_manager_name is set. This allows third-party code to preserve legacy behavior while transitioning to the new
API. The warning can be silenced by setting silence_use_for_related_fields_deprecation=True on the manager.
Miscellaneous
• The makemigrations --exit option is deprecated in favor of the
option.
9.1. Final releases 1447
Django Documentation, Release 2.0.dev20170914110741
• django.utils.functional.allow_lazy() is deprecated in favor of the new
function which can be used with a more natural decorator syntax.
• The shell --plain option is deprecated in favor of -i python or --interface python.
• Importing from the django.core.urlresolvers module is deprecated in favor of its new location,
• The template Context.has_key() method is deprecated in favor of in.
• The private attribute virtual_fields of Model._meta is deprecated in favor of private_fields.
• The private keyword arguments virtual_only in Field.contribute_to_class() and virtual in
Model._meta.add_field() are deprecated in favor of private_only and private, respectively.
• The javascript_catalog() and json_catalog() views are deprecated in favor of class-based views
and
• In multi-table inheritance, implicit promotion of a OneToOneField to a parent_link is deprecated. Add parent_link=True to such fields.
• The private API Widget._format_value() is made public and renamed to
name will work through a deprecation period.
• Private FileField methods get_directory_name() and get_filename() are deprecated in favor of performing this work in
• Old-style middleware that uses settings.MIDDLEWARE_CLASSES are deprecated.
and use the new
setting.
Features removed in 1.10
These features have reached the end of their deprecation cycle and are removed in Django 1.10. See
for details, including how to remove usage of these features.
• Support for calling a SQLCompiler directly as an alias for calling its quote_name_unless_alias method is removed.
• The cycle and firstof template tags are removed from the future template tag library.
• django.conf.urls.patterns() is removed.
• Support for the prefix argument to django.conf.urls.i18n.i18n_patterns() is removed.
• SimpleTestCase.urls is removed.
• Using an incorrect count of unpacked values in the for template tag raises an exception rather than failing silently.
• The ability to
URLs using a dotted Python path is removed.
• The ability to use a dotted Python path for the LOGIN_URL and LOGIN_REDIRECT_URL settings is removed.
• Support for optparse is dropped for custom management commands.
• The class django.core.management.NoArgsCommand is removed.
• django.core.context_processors module is removed.
• django.db.models.sql.aggregates module is removed.
• django.contrib.gis.db.models.sql.aggregates module is removed.
• The following methods and properties of django.db.sql.query.Query are removed:
1448 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
– Properties: aggregates and aggregate_select
– Methods: add_aggregate, set_aggregate_mask, and append_aggregate_mask.
• django.template.resolve_variable is removed.
• The following private APIs are removed from
django.db.models.options.Options
(Model.
_meta
):
– get_field_by_name()
– get_all_field_names()
– get_fields_with_model()
– get_concrete_fields_with_model()
– get_m2m_with_model()
– get_all_related_objects()
– get_all_related_objects_with_model()
– get_all_related_many_to_many_objects()
– get_all_related_m2m_objects_with_model()
• The error_message argument of django.forms.RegexField is removed.
• The unordered_list filter no longer supports old style lists.
• Support for string view arguments to url() is removed.
• The backward compatible shim to rename django.forms.Form._has_changed() to has_changed() is removed.
• The removetags template filter is removed.
• The remove_tags() and strip_entities() functions in django.utils.html is removed.
• The is_admin_site argument to django.contrib.auth.views.password_reset() is removed.
• django.db.models.field.subclassing.SubfieldBase is removed.
• django.utils.checksums is removed.
• The original_content_type_id attribute on django.contrib.admin.helpers.
InlineAdminForm is removed.
• The backwards compatibility shim to allow FormMixin.get_form() to be defined with no default value for its form_class argument is removed.
• The following settings are removed, and you must upgrade to the
setting:
– ALLOWED_INCLUDE_ROOTS
– TEMPLATE_CONTEXT_PROCESSORS
– TEMPLATE_DEBUG
– TEMPLATE_DIRS
– TEMPLATE_LOADERS
– TEMPLATE_STRING_IF_INVALID
• The backwards compatibility alias django.template.loader.BaseLoader is removed.
9.1. Final releases 1449
Django Documentation, Release 2.0.dev20170914110741
• Django template objects returned by
and
no longer accept a
in their
method.
•
enforce the use of dict and backend-dependent template objects instead of
and
respectively.
• The current_app parameter for the following function and classes is removed:
– django.shortcuts.render()
– django.template.Context()
– django.template.RequestContext()
– django.template.response.TemplateResponse()
• The dictionary and context_instance parameters for the following functions are removed:
– django.shortcuts.render()
– django.shortcuts.render_to_response()
– django.template.loader.render_to_string()
• The dirs parameter for the following functions is removed:
– django.template.loader.get_template()
– django.template.loader.select_template()
– django.shortcuts.render()
– django.shortcuts.render_to_response()
• Session verification is enabled regardless of whether or not
'django.contrib.auth.
middleware.SessionAuthenticationMiddleware' is in
MIDDLEWARE_CLASSES
.
SessionAuthenticationMiddleware no longer has any purpose and can be removed from
MIDDLEWARE_CLASSES
. It’s kept as a stub until Django 2.0 as a courtesy for users who don’t read this note.
• Private attribute django.db.models.Field.related is removed.
• The --list option of the migrate management command is removed.
• The ssi template tag is removed.
• Support for the = comparison operator in the if template tag is removed.
• The backwards compatibility shims to allow Storage.get_available_name() and Storage.
save() to be defined without a max_length argument are removed.
• Support for the legacy %(<foo>)s syntax in ModelFormMixin.success_url is removed.
• GeoQuerySet aggregate methods collect(), extent(), extent3d(), make_line(), and unionagg() are removed.
• The ability to specify ContentType.name when creating a content type instance is removed.
• Support for the old signature of allow_migrate is removed.
• Support for the syntax of {% cycle %} that uses comma-separated arguments is removed.
• The warning that
issued when given an invalid separator is now a ValueError.
1450 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
1.9 release
Django 1.9.13 release notes
April 4, 2017
Django 1.9.13 fixes two security issues and a bug in 1.9.12. This is the final release of the 1.9.x series.
CVE-2017-7233: Open redirect and possible XSS attack via user-supplied numeric redirect URLs
Django relies on user input in some cases (e.g.
django.contrib.auth.views.login()
and
rect the user to an “on success” URL. The security check for these redirects (namely django.utils.http.
is_safe_url()
) considered some numeric URLs (e.g. http:999999999) “safe” when they shouldn’t be.
Also, if a developer relies on is_safe_url() to provide safe redirect targets and puts such a URL into a link, they could suffer from an XSS attack.
CVE-2017-7234: Open redirect vulnerability in django.views.static.serve()
A maliciously crafted URL to a Django site using the
view could redirect to any other domain. The view no longer does any redirects as they don’t provide any known, useful functionality.
Note, however, that this view has always carried a warning that it is not hardened for production use and should be used only as a development aid.
Bugfixes
• Fixed a regression in the timesince and timeuntil filters that caused incorrect results for dates in a leap year ( #27637 ).
Django 1.9.12 release notes
December 1, 2016
Django 1.9.12 fixes a regression in 1.9.11.
Bugfixes
• Quoted the Oracle test user’s password in queries to fix the “ORA-00922: missing or invalid option” error when the password starts with a number or special character ( #27420 ).
Django 1.9.11 release notes
November 1, 2016
Django 1.9.11 fixes two security issues in 1.9.10.
9.1. Final releases 1451
Django Documentation, Release 2.0.dev20170914110741
User with hardcoded password created when running tests on Oracle
When running tests with an Oracle database, Django creates a temporary database user. In older versions, if a password isn’t manually specified in the database settings TEST dictionary, a hardcoded password is used. This could allow an attacker with network access to the database server to connect.
This user is usually dropped after the test suite completes, but not when using the manage.py test --keepdb option or if the user has an active session (such as an attacker’s connection).
A randomly generated password is now used for each test run.
DNS rebinding vulnerability when DEBUG=True
Older versions of Django don’t validate the Host header against settings.ALLOWED_HOSTS when settings.
DEBUG=True
. This makes them vulnerable to a DNS rebinding attack .
While Django doesn’t ship a module that allows remote code execution, this is at least a cross-site scripting vector, which could be quite serious if developers load a copy of the production database in development or connect to some production services for which there’s no development instance, for example. If a project uses a package like the django-debug-toolbar , then the attacker could execute arbitrary SQL, which could be especially bad if the developers connect to the database with a superuser account.
settings.ALLOWED_HOSTS
is now validated regardless of DEBUG. For convenience, if ALLOWED_HOSTS is empty and DEBUG=True, the following variations of localhost are allowed ['localhost', '127.0.0.1',
'::1']
. If your local settings file has your production ALLOWED_HOSTS value, you must now omit it to get those fallback values.
Django 1.9.10 release notes
September 26, 2016
Django 1.9.10 fixes a security issue in 1.9.9.
CSRF protection bypass on a site with Google Analytics
An interaction between Google Analytics and Django’s cookie parsing could allow an attacker to set arbitrary cookies leading to a bypass of CSRF protection.
The parser for request.COOKIES is simplified to better match the behavior of browsers and to mitigate this attack.
request.COOKIES
may now contain cookies that are invalid according to RFC 6265 but are possible to set via document.cookie
.
Django 1.9.9 release notes
August 1, 2016
Django 1.9.9 fixes several bugs in 1.9.8.
Bugfixes
• Fixed invalid HTML in template postmortem on the debug page ( #26938 ).
• Fixed some GIS database function crashes on MySQL 5.7 ( #26657 ).
1452 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
Django 1.9.8 release notes
July 18, 2016
Django 1.9.8 fixes a security issue and several bugs in 1.9.7.
XSS in admin’s add/change related popup
Unsafe usage of JavaScript’s Element.innerHTML could result in XSS in the admin’s add/change related popup.
Element.textContent
is now used to prevent execution of the data.
The debug view also used innerHTML. Although a security issue wasn’t identified there, out of an abundance of caution it’s also updated to use textContent.
Bugfixes
• Fixed missing varchar/text_pattern_ops index on CharField and TextField respectively when using AddField on PostgreSQL ( #26889 ).
• Fixed makemessages crash on Python 2 with non-ASCII file names ( #26897 ).
Django 1.9.7 release notes
June 4, 2016
Django 1.9.7 fixes several bugs in 1.9.6.
Bugfixes
• Removed the need for the request context processor on the admin login page to fix a regression in 1.9
( #26558 ).
• Fixed translation of password validators’ help_text in forms ( #26544 ).
• Fixed a regression causing the cached template loader to crash when using lazy template names ( #26603 ).
• Fixed on_commit callbacks execution order when callbacks make transactions ( #26627 ).
• Fixed HStoreField to raise a ValidationError instead of crashing on non-dictionary JSON input
( #26672 ).
• Fixed dbshell crash on PostgreSQL with an empty database name ( #26698 ).
• Fixed a regression in queries on a OneToOneField that has to_field and primary_key=True
( #26667 ).
Django 1.9.6 release notes
May 2, 2016
Django 1.9.6 fixes several bugs in 1.9.5.
9.1. Final releases 1453
Django Documentation, Release 2.0.dev20170914110741
Bugfixes
• Added support for relative path redirects to the test client and to SimpleTestCase.assertRedirects() because Django 1.9 no longer converts redirects to absolute URIs ( #26428 ).
• Fixed TimeField microseconds round-tripping on MySQL and SQLite ( #26498 ).
• Prevented makemigrations from generating infinite migrations for a model field that references a functools.partial
( #26475 ).
• Fixed a regression where SessionBase.pop() returned None rather than raising a KeyError for nonexistent values ( #26520 ).
• Fixed a regression causing the cached template loader to crash when using template names starting with a dash
( #26536 ).
• Restored conversion of an empty string to null when saving values of GenericIPAddressField on SQLite and MySQL ( #26557 ).
• Fixed a makemessages regression where temporary .py extensions were leaked in source file paths ( #26341 ).
Django 1.9.5 release notes
April 1, 2016
Django 1.9.5 fixes several bugs in 1.9.4.
Bugfixes
• Made MultiPartParser ignore filenames that normalize to an empty string to fix crash in
MemoryFileUploadHandler on specially crafted user input ( #26325 ).
• Fixed a race condition in BaseCache.get_or_set() ( #26332 ). It now returns the default value instead of False if there’s an error when trying to add the value to the cache.
• Fixed data loss on SQLite where DurationField values with fractional seconds could be saved as None
( #26324 ).
• The forms in contrib.auth no longer strip trailing and leading whitespace from the password fields
( #26334 ). The change requires users who set their password to something with such whitespace after a site updated to Django 1.9 to reset their password. It provides backwards-compatibility for earlier versions of Django.
• Fixed a memory leak in the cached template loader ( #26306 ).
• Fixed a regression that caused collectstatic --clear to fail if the storage doesn’t implement path()
( #26297 ).
• Fixed a crash when using a reverse lookup with a subquery when a ForeignKey has a to_field set to something other than the primary key ( #26373 ).
• Fixed a regression in CommonMiddleware that caused spurious warnings in logs on requests missing a trailing slash ( #26293 ).
• Restored the functionality of the admin’s raw_id_fields in list_editable ( #26387 ).
• Fixed a regression with abstract model inheritance and explicit parent links ( #26413 ).
• Fixed a migrations crash on SQLite when renaming the primary key of a model containing a ForeignKey to
'self'
( #26384 ).
1454 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
• Fixed JSONField inadvertently escaping its contents when displaying values after failed form validation
( #25532 ).
Django 1.9.4 release notes
March 5, 2016
Django 1.9.4 fixes a regression on Python 2 in the 1.9.3 security release where utils.http.is_safe_url() crashes on bytestring URLs ( #26308 ).
Django 1.9.3 release notes
March 1, 2016
Django 1.9.3 fixes two security issues and several bugs in 1.9.2.
CVE-2016-2512: Malicious redirect and possible XSS attack via user-supplied redirect URLs containing basic auth
Django relies on user input in some cases (e.g.
django.contrib.auth.views.login()
and
rect the user to an “on success” URL. The security check for these redirects (namely django.utils.http.
is_safe_url() ) considered some URLs with basic authentication credentials “safe” when they shouldn’t be.
For example, a URL like http://mysite.example.com\@attacker.com would be considered safe if the request’s host is http://mysite.example.com, but redirecting to this URL sends the user to attacker.com.
Also, if a developer relies on is_safe_url() to provide safe redirect targets and puts such a URL into a link, they could suffer from an XSS attack.
CVE-2016-2513: User enumeration through timing difference on password hasher work factor upgrade
In each major version of Django since 1.6, the default number of iterations for the PBKDF2PasswordHasher and its subclasses has increased. This improves the security of the password as the speed of hardware increases, however, it also creates a timing difference between a login request for a user with a password encoded in an older number of iterations and login request for a nonexistent user (which runs the default hasher’s default number of iterations since
Django 1.6).
This only affects users who haven’t logged in since the iterations were increased. The first time a user logs in after an iterations increase, their password is updated with the new iterations and there is no longer a timing difference.
The new BasePasswordHasher.harden_runtime() method allows hashers to bridge the runtime gap between the work factor (e.g. iterations) supplied in existing encoded passwords and the default work factor of the hasher. This method is implemented for PBKDF2PasswordHasher and BCryptPasswordHasher. The number of rounds for the latter hasher hasn’t changed since Django 1.4, but some projects may subclass it and increase the work factor as needed.
A warning will be emitted for any
third-party password hashers that don’t implement
a harden_runtime() method.
If you have different password hashes in your database (such as SHA1 hashes from users who haven’t logged in since the default hasher switched to PBKDF2 in Django 1.4), the timing difference on a login request for these users may be even greater and this fix doesn’t remedy that difference (or any difference when changing hashers). You may be able to
to prevent a timing attack for that case.
9.1. Final releases 1455
Django Documentation, Release 2.0.dev20170914110741
Bugfixes
• Skipped URL checks (new in 1.9) if the ROOT_URLCONF setting isn’t defined ( #26155 ).
• Fixed a crash on PostgreSQL that prevented using TIME_ZONE=None and USE_TZ=False ( #26177 ).
• Added system checks for query name clashes of hidden relationships ( #26162 ).
• Fixed a regression for cases where ForeignObject.get_extra_descriptor_filter() returned a
Q object ( #26153 ).
• Fixed regression with an __in=qs lookup for a ForeignKey with to_field set ( #26196 ).
• Made forms.FileField and utils.translation.lazy_number() picklable ( #26212 ).
• Fixed
and
serialization with None values ( #26215 ).
• Fixed a crash when filtering by a Decimal in RawQuery ( #26219 ).
• Reallowed dashes in top-level domain names of URLs checked by URLValidator to fix a regression in
Django 1.8 ( #26204 ).
• Fixed some crashing deprecation shims in SimpleTemplateResponse that regressed in Django 1.9
( #26253 ).
• Fixed BoundField to reallow slices of subwidgets ( #26267 ).
• Changed the admin’s “permission denied” message in the login template to use get_username instead of username to support custom user models ( #26231 ).
• Fixed a crash when passing a nonexistent template name to the cached template loader’s load_template() method ( #26280 ).
• Prevented ContentTypeManager instances from sharing their cache ( #26286 ).
• Reverted a change in Django 1.9.2 ( #25858 ) that prevented relative lazy relationships defined on abstract models to be resolved according to their concrete model’s app_label ( #26186 ).
Django 1.9.2 release notes
February 1, 2016
Django 1.9.2 fixes a security regression in 1.9 and several bugs in 1.9.1. It also makes a small backwards incompatible change that hopefully doesn’t affect any users.
Security issue: User with “change” but not “add” permission can create objects for ModelAdmin’s with save_as=True
If a ModelAdmin uses save_as=True (not the default), the admin provides an option when editing objects to
“Save as new”. A regression in Django 1.9 prevented that form submission from raising a “Permission Denied” error for users without the “add” permission.
Backwards incompatible change: .py-tpl files rewritten in project/app templates
The addition of some Django template language syntax to the default app template in Django 1.9 means those files now have some invalid Python syntax. This causes difficulties for packaging systems that unconditionally byte-compile *.
py files.
1456 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
To remedy this, a .py-tpl suffix is now used for the project and app template files included in Django. The .
py-tpl suffix is replaced with .py by the startproject and startapp commands. For example, a template with the filename manage.py-tpl will be created as manage.py.
Please file a ticket if you have a custom project template containing .py-tpl files and find this behavior problematic.
Bugfixes
• Fixed a regression in ConditionalGetMiddleware causing If-None-Match checks to always return
HTTP 200 ( #26024 ).
• Fixed a regression that caused the “user-tools” items to display on the admin’s logout page ( #26035 ).
• Fixed a crash in the translations system when the current language has no translations ( #26046 ).
• Fixed a regression that caused the incorrect day to be selected when opening the admin calendar widget for timezones from GMT+0100 to GMT+1200 ( #24980 ).
• Fixed a regression in the admin’s edit related model popup that caused an escaped value to be displayed in the select dropdown of the parent window ( #25997 ).
• Fixed a regression in 1.8.8 causing incorrect index handling in migrations on PostgreSQL when adding db_index=True or unique=True to a CharField or TextField that already had the other specified, or when removing one of them from a field that had both, or when adding unique=True to a field already listed in unique_together ( #26034 ).
• Fixed a regression where defining a relation on an abstract model’s field using a string model name without an app_label no longer resolved that reference to the abstract model’s app if using that model in another application
( #25858 ).
• Fixed a crash when destroying an existing test database on MySQL or PostgreSQL ( #26096 ).
• Fixed CSRF cookie check on POST requests when USE_X_FORWARDED_PORT=True ( #26094 ).
• Fixed a QuerySet.order_by() crash when ordering by a relational field of a ManyToManyField through model ( #26092 ).
• Fixed a regression that caused an exception when making database queries on SQLite with more than 2000 parameters when
is True on distributions that increase the SQLITE_MAX_VARIABLE_NUMBER compile-time limit to over 2000, such as Debian ( #26063 ).
• Fixed a crash when using a reverse OneToOneField in ModelAdmin.readonly_fields ( #26060 ).
• Fixed a crash when calling the migrate command in a test case with the available_apps attribute pointing to an application with migrations disabled using the MIGRATION_MODULES setting ( #26135 ).
• Restored the ability for testing and debugging tools to determine the template from which a node came from, even during template inheritance or inclusion. Prior to Django 1.9, debugging tools could access the template origin from the node via Node.token.source[0]. This was an undocumented, private API. The origin is now available directly on each node using the Node.origin attribute ( #25848 ).
• Fixed a regression in Django 1.8.5 that broke copying a SimpleLazyObject with copy.copy() ( #26122 ).
• Always included geometry_field in the GeoJSON serializer output regardless of the fields parameter
( #26138 ).
• Fixed the contrib.gis map widgets when using USE_THOUSAND_SEPARATOR=True ( #20415 ).
• Made invalid forms display the initial of values of their disabled fields ( #26129 ).
9.1. Final releases 1457
Django Documentation, Release 2.0.dev20170914110741
Django 1.9.1 release notes
January 2, 2016
Django 1.9.1 fixes several bugs in 1.9.
Bugfixes
• Fixed BaseCache.get_or_set() with the DummyCache backend ( #25840 ).
• Fixed a regression in FormMixin causing forms to be validated twice ( #25548 , #26018 ).
• Fixed a system check crash with nested ArrayFields ( #25867 ).
• Fixed a state bug when migrating a SeparateDatabaseAndState operation backwards ( #25896 ).
• Fixed a regression in CommonMiddleware causing If-None-Match checks to always return HTTP 200
( #25900 ).
• Fixed missing varchar/text_pattern_ops index on CharField and TextField respectively when using AlterField on PostgreSQL ( #25412 ).
• Fixed admin’s delete confirmation page’s summary counts of related objects ( #25883 ).
• Added from __future__ import unicode_literals to the default apps.py created by startapp on Python 2 ( #25909 ). Add this line to your own apps.py files created using Django 1.9 if you want your migrations to work on both Python 2 and Python 3.
• Prevented QuerySet.delete() from crashing on MySQL when querying across relations ( #25882 ).
• Fixed evaluation of zero-length slices of QuerySet.values() ( #25894 ).
• Fixed a state bug when using an AlterModelManagers operation ( #25852 ).
• Fixed TypedChoiceField change detection with nullable fields ( #25942 ).
• Fixed incorrect timezone warnings in custom admin templates that don’t have a data-admin-utc-offset attribute in the body tag. ( #25845 ).
• Fixed a regression which prevented using a language not in Django’s default language list (
( #25915 ).
• Avoided hiding some exceptions, like an invalid
INSTALLED_APPS setting, behind
AppRegistryNotReady when starting runserver ( #25510 ).
This regression appeared in 1.8.5 as a side effect of fixing #24704 and by mistake the fix wasn’t applied to the stable/1.9.x branch.
• Fixed migrate --fake-initial detection of many-to-many tables ( #25922 ).
• Restored the functionality of the admin’s list_editable add and change buttons ( #25903 ).
• Fixed isnull query lookup for ForeignObject ( #25972 ).
• Fixed a regression in the admin which ignored line breaks in read-only fields instead of converting them to <br>
( #25465 ).
• Fixed incorrect object reference in SingleObjectMixin.get_context_object_name() ( #26006 ).
• Made loaddata skip disabling and enabling database constraints when it doesn’t load any fixtures ( #23372 ).
• Restored contrib.auth hashers compatibility with py-bcrypt ( #26016 ).
• Fixed a crash in QuerySet.values()/values_list() after an annotate() and order_by() when values()/values_list() includes a field not in the order_by() ( #25316 ).
1458 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
Django 1.9 release notes
December 1, 2015
Welcome to Django 1.9!
These release notes cover the
new features , as well as some
backwards incompatible changes
you’ll want to be aware of when upgrading from Django 1.8 or older versions. We’ve
that have reached the end of their deprecation cycle, and we’ve
begun the deprecation process for some features .
See the
Upgrading Django to a newer version
guide if you’re updating an existing project.
Python compatibility
Django 1.9 requires Python 2.7, 3.4, or 3.5. We highly recommend and only officially support the latest release of each series.
The Django 1.8 series is the last to support Python 3.2 and 3.3.
What’s new in Django 1.9
Performing actions after a transaction commit
The new
hook allows performing actions after a database transaction is successfully committed. This is useful for tasks such as sending notification emails, creating queued tasks, or invalidating caches.
This functionality from the django-transaction-hooks package has been integrated into Django.
Password validation
Django now offers password validation to help prevent the usage of weak passwords by users. The validation is integrated in the included password change and reset forms and is simple to integrate in any other code. Validation is performed by one or more validators, configured in the new
setting.
Four validators are included in Django, which can enforce a minimum length, compare the password to the user’s attributes like their name, ensure passwords aren’t entirely numeric, or check against an included list of common passwords. You can combine multiple validators, and some validators have custom configuration options. For example, you can choose to provide a custom list of common passwords. Each validator provides a help text to explain its requirements to the user.
By default, no validation is performed and all passwords are accepted, so if you don’t set
AUTH_PASSWORD_VALIDATORS , you will not see any change.
In new projects created with the default
template, a simple set of validators is enabled. To enable basic validation in the included auth forms for your project, you could set, for example:
AUTH_PASSWORD_VALIDATORS = [
{
'NAME' : 'django.contrib.auth.password_validation.
˓→
UserAttributeSimilarityValidator' ,
},
{
'NAME' : 'django.contrib.auth.password_validation.MinimumLengthValidator' ,
},
{
'NAME' : 'django.contrib.auth.password_validation.CommonPasswordValidator' ,
9.1. Final releases 1459
Django Documentation, Release 2.0.dev20170914110741
},
{
},
'NAME' : 'django.contrib.auth.password_validation.NumericPasswordValidator' ,
]
See
for more details.
Permission mixins for class-based views
Django now ships with the mixins
and
to provide the functionality of the django.contrib.auth.decorators for class-based views. These mixins have been taken from, or are at least inspired by, the django-braces project.
There are a few differences between Django’s and django-braces‘ implementation, though:
• The
attribute can only be True or False. Custom exceptions or callables are not supported.
• The
method does not take a request argument. The current request is available in self.request.
• The custom test_func() of
does not take a user argument. The current user is available in self.request.user.
• The
attribute supports a string (defining one permission) or a list/tuple of strings
(defining multiple permissions) that need to be fulfilled to grant access.
• The new
attribute allows passing a message to the PermissionDenied exception.
New styling for contrib.admin
The admin sports a modern, flat design with new SVG icons which look perfect on HiDPI screens. It still provides a fully-functional experience to YUI’s A-grade browsers. Older browser may experience varying levels of graceful degradation.
Running tests in parallel
The
command now supports a
option to run a project’s tests in multiple processes in parallel.
Each process gets its own database. You must ensure that different test cases don’t access the same resources. For instance, test cases that touch the filesystem should create a temporary directory for their own use.
This option is enabled by default for Django’s own test suite provided:
• the OS supports it (all but Windows)
• the database backend supports it (all the built-in backends but Oracle)
Minor features django.contrib.admin
• Admin views now have model_admin or admin_site attributes.
1460 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
• The URL of the admin change view has been changed (was at /admin/<app>/<model>/<pk>/ by default and is now at /admin/<app>/<model>/<pk>/change/). This should not affect your application unless you have hardcoded admin URLs. In that case, replace those links by
instead. Note that the old URL still redirects to the new one for backwards compatibility, but it may be removed in a future version.
•
ModelAdmin.get_list_select_related()
was added to allow changing the select_related() values used in the admin’s changelist query based on the request.
• The available_apps context variable, which lists the available applications for the current user, has been added to the
method.
•
and
ModelAdmin.empty_value_display
were added to override the display of empty values in admin change list. You can also customize the value for each field.
• Added jQuery events
when an inline form is added or removed
on the change form page.
• The time picker widget includes a ‘6 p.m’ option for consistency of having predefined options every 6 hours.
• JavaScript slug generation now supports Romanian characters.
django.contrib.admindocs
• The model section of the admindocs now also describes methods that take arguments, rather than ignoring them.
django.contrib.auth
• The default iteration count for the PBKDF2 password hasher has been increased by 20%.
This backwards compatible change will not affect users who have subclassed django.contrib.auth.hashers.
PBKDF2PasswordHasher to change the default value.
• The BCryptSHA256PasswordHasher will now update passwords if its rounds attribute is changed.
• AbstractBaseUser and BaseUserManager were moved to a new django.contrib.auth.
base_user module so that they can be imported without including django.contrib.auth in
(doing so raised a deprecation warning in older versions and is no longer supported in
Django 1.9).
• The permission argument of
accepts all kinds of iterables, not only list and tuples.
• The new
PersistentRemoteUserMiddleware
makes it possible to use REMOTE_USER for setups where the header is only populated on login pages instead of every request in the session.
• The
view accepts an extra_email_context parameter.
django.contrib.contenttypes
• It’s now possible to use
with a GenericForeignKey.
django.contrib.gis
• All GeoQuerySet methods have been deprecated and replaced by
equivalent database functions . As soon
as the legacy methods have been replaced in your code, you should even be able to remove the special
GeoManager from your GIS-enabled classes.
9.1. Final releases 1461
Django Documentation, Release 2.0.dev20170914110741
• The GDAL interface now supports instantiating file-based and in-memory
from raw data.
Setters for raster properties such as projection or pixel values have been added.
• For PostGIS users, the new
allows
storing GDALRaster objects . It supports automatic spatial
index creation and reprojection when saving a model. It does not yet support spatial querying.
• The new
method allows warping a raster by specifying target raster properties such as origin, width, height, or pixel size (amongst others).
• The new
method allows transforming a raster into a different spatial reference system by specifying a target srid.
• The new
class allows using MaxMind’s GeoLite2 databases which includes support for IPv6 addresses.
• The default OpenLayers library version included in widgets has been updated from 2.13 to 2.13.1.
django.contrib.postgres
• Added support for the
lookup for some built in fields which correspond to the range fields.
• Added
• Added
PostgreSQL specific aggregation functions
• Added the
database function.
django.contrib.sessions
• The session model and SessionStore classes for the db and cached_db backends are refactored to allow a custom database session backend to build upon them. See
Extending database-backed session engines
for more details.
django.contrib.sites
•
now handles the case where request.get_host() returns domain:port, e.g. example.com:80. If the lookup fails because the host does not match a record in the database and the host has a port, the port is stripped and the lookup is retried with the domain part only.
django.contrib.syndication
• Support for multiple enclosures per feed item has been added. If multiple enclosures are defined on a RSS feed, an exception is raised as RSS feeds, unlike Atom feeds, do not support multiple enclosures per feed item.
Cache
• django.core.cache.backends.base.BaseCache now has a get_or_set() method.
•
django.views.decorators.cache.never_cache()
now sends more persuasive headers (added no-cache, no-store, must-revalidate to Cache-Control) to better prevent caching. This was also added in Django 1.8.8.
1462 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
CSRF
• The request header’s name used for CSRF authentication can be customized with
• The CSRF referer header is now validated against the
setting if set. See
for details.
• The new
setting provides a way to allow cross-origin unsafe requests (e.g. POST) over HTTPS.
Database backends
• The PostgreSQL backend (django.db.backends.postgresql_psycopg2) is also available as django.db.backends.postgresql
. The old name will continue to be available for backwards compatibility.
File Storage
•
is now called when the
is a callable.
•
now has the seekable() method when using Python 3.
Forms
•
accepts the new Meta option field_classes to customize the type of the fields. See
for details.
• You can now specify the order in which form fields are rendered with the
attribute, the field_order constructor argument , or the
method.
• A form prefix can be specified inside a form class, not only when instantiating a form. See
for details.
• You can now
that you want to pass to the constructor of forms in a formset.
•
now accepts an
argument to allow Unicode characters in slugs.
•
now accepts a
argument to strip input data of leading and trailing whitespace. As this defaults to True this is different behavior from previous releases.
• Form fields now support the
argument, allowing the field widget to be displayed disabled by browsers.
• It’s now possible to customize bound fields by overriding a field’s
method.
Generic Views
• Class-based views generated using as_view() now have view_class and view_initkwargs attributes.
•
can now be used with a list or tuple of decorators. It can also be used to
decorate classes instead of methods
9.1. Final releases 1463
Django Documentation, Release 2.0.dev20170914110741
Internationalization
• The
django.views.i18n.set_language()
view now properly redirects to
available.
• The django.views.i18n.javascript_catalog() view now works correctly if used multiple times with different configurations on the same page.
• The
django.utils.timezone.make_aware()
function gained an is_dst argument to help resolve ambiguous times during DST transitions.
• You can now use locale variants supported by gettext. These are usually used for languages which can be written in different scripts, for example Latin and Cyrillic (e.g. be@latin).
• Added the django.views.i18n.json_catalog() view to help build a custom client-side i18n library upon Django translations. It returns a JSON object containing a translations catalog, formatting settings, and a plural rule.
• Added the name_translated attribute to the object returned by the
template tag.
Also added a corresponding template filter:
• You can now run
from the root directory of your project and it will find all the app message files that were created by
•
now calls xgettext once per locale directory rather than once per translatable file. This speeds up localization builds.
•
supports assigning its output to a variable using asvar.
• Two new languages are available: Colombian Spanish and Scottish Gaelic.
Management Commands
• The new
command lets you send a test email to easily confirm that email sending through
Django is working.
• To increase the readability of the SQL code generated by
sqlmigrate , the SQL code generated for each
migration operation is preceded by the operation’s description.
• The
command output is now deterministically ordered. Moreover, when the --output option is specified, it also shows a progress bar in the terminal.
• The
command now has a --dry-run flag to print out the SQL rather than execute it.
• The
command creates an apps.py file.
'polls.apps.PollsConfig'
, in
for it to be used (instead of just 'polls').
• When using the PostgreSQL backend, the
command can connect to the database using the password from your settings file (instead of requiring it to be manually entered).
• The django package may be run as a script, i.e. python -m django, which will behave the same as django-admin .
• Management commands that have the --noinput option now also take --no-input as an alias for that option.
1464 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
Migrations
• Initial migrations are now marked with an
class attribute which allows
to more easily detect initial migrations.
• Added support for serialization of functools.partial and LazyObject instances.
• When supplying None as a value in
, Django will consider the app an app without
migrations.
• When applying migrations, the “Rendering model states” step that’s displayed when running migrate with verbosity 2 or higher now computes only the states for the migrations that have already been applied. The model states for migrations being applied are generated on demand, drastically reducing the amount of required memory.
However, this improvement is not available when unapplying migrations and therefore still requires the precomputation and storage of the intermediate migration states.
This improvement also requires that Django no longer supports mixed migration plans. Mixed plans consist of a list of migrations where some are being applied and others are being unapplied. This was never officially supported and never had a public API that supports this behavior.
• The
command now supports specifying the starting migration from which migrations will be squashed.
Models
•
now works on proxy models.
• Database configuration gained a
option for interacting with databases that store datetimes in local time and don’t support time zones when
is True.
• Added the
method to the related managers created by ForeignKey,
GenericForeignKey
, and ManyToManyField.
• The
method on a reverse foreign key now has a bulk parameter to allow executing one query regardless of the number of objects being added rather than one query per object.
• Added the keep_parents parameter to
to allow deleting only a child’s data in a model that uses multi-table inheritance.
•
and
return the number of objects deleted.
• Added a system check to prevent defining both Meta.ordering and order_with_respect_to on the same model.
•
lookups can be chained with other lookups (such as
Entry.objects.filter(pub_date__month__gt=6)
.
• Time lookups (hour, minute, second) are now supported by
for all database backends. Support for backends other than SQLite was added but undocumented in Django 1.7.
• You can specify the output_field parameter of the
aggregate in order to aggregate over non-numeric columns, such as DurationField.
• Added the
lookup to
to allow querying the field by only the date portion.
• Added the
and
database functions.
• Added the
database function, which returns the current date and time.
9.1. Final releases 1465
Django Documentation, Release 2.0.dev20170914110741
•
is now a subclass of
which allows Transforms to be used on the right hand side of an expression, just like regular Funcs. This allows registering some database functions like
as transforms.
•
now accepts an
argument to allow Unicode characters in slugs.
• Added support for referencing annotations in QuerySet.distinct().
• connection.queries shows queries with substituted parameters on SQLite.
•
can now be used when creating new model instances using save(), create(), and bulk_create()
.
Requests and Responses
• Unless
is explicitly set, it now is determined by the current value of
. Modifying the value of status_code outside of the constructor will
also modify the value of reason_phrase.
• The debug view now shows details of chained exceptions on Python 3.
• The default 40x error views now accept a second positional parameter, the exception that triggered the view.
• View error handlers now support
, commonly used with class-based views.
• Exceptions raised by the render() method are now passed to the process_exception() method of each middleware.
• Request middleware can now set
to None to revert any changes made by previous middleware and return to using the
• The
check in
now raises a
exception as opposed to returning an
so that
is invoked.
• Added
to fetch the originating port of the request.
• Added the json_dumps_params parameter to
to allow passing keyword arguments to the json.dumps() call used to generate the response.
• The
now ignores 404s when the referer is equal to the requested URL.
To circumvent the empty referer check already implemented, some Web bots set the referer to the requested
URL.
Templates
• Template tags created with the
helper can now store results in a template variable by using the as argument.
• Added a
method.
• The
logger was added and includes the following messages:
– A DEBUG level message for missing context variables.
– A WARNING level message for uncaught exceptions raised during the rendering of an {% include %} when debug mode is off (helpful since {% include %} silences the exception and returns an empty string).
• The
template tag supports storing the output in a variable using ‘as’.
•
can now be used as a context manager.
1466 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
• Django template loaders can now extend templates recursively.
• The debug page template postmortem now include output from each engine that is installed.
•
for custom template engines was added.
• The
backend gained the ability to register libraries and builtins explicitly through the template
• The timesince and timeuntil filters were improved to deal with leap years when given large time spans.
• The include tag now caches parsed templates objects during template rendering, speeding up reuse in places such as for loops.
Tests
• Added the
method to test client responses to give access to the response body as JSON.
• Added the
method to the test client. Use this method to simulate the effect of a user logging into the site while skipping the authentication and verification steps of
URLs
• Regular expression lookaround assertions are now allowed in URL patterns.
• The application namespace can now be set using an app_name attribute on the included module or object. It can also be set by passing a 2-tuple of (<list of patterns>, <application namespace>) as the first argument to
• System checks have been added for common URL pattern mistakes.
Validators
• Added
django.core.validators.int_list_validator()
to generate validators of strings containing integers separated with a custom character.
•
now limits the length of domain name labels to 63 characters per RFC 1034 .
• Added
to validate slugs that may contain Unicode characters.
Backwards incompatible changes in 1.9
Warning: In addition to the changes outlined in this section, be sure to review the
for the features that have reached the end of their deprecation cycle and therefore been removed. If you haven’t updated your code within the deprecation timeline for a given feature, its removal may appear as a backwards incompatible change.
Database backend API
• A couple of new tests rely on the ability of the backend to introspect column defaults (returning the result as Field.default). You can set the can_introspect_default database feature to False if your backend doesn’t implement this. You may want to review the implementation on the backends that Django includes for reference ( #24245 ).
9.1. Final releases 1467
Django Documentation, Release 2.0.dev20170914110741
• Registering a global adapter or converter at the level of the DB-API module to handle time zone information of datetime values passed as query parameters or returned as query results on databases that don’t support time zones is discouraged. It can conflict with other libraries.
The recommended way to add a time zone to datetime values fetched from the database is to register a converter for DateTimeField in DatabaseOperations.get_db_converters().
The needs_datetime_string_cast database feature was removed. Database backends that set it must register a converter instead, as explained above.
• The
DatabaseOperations.value_to_db_<type>() methods were renamed adapt_<type>field_value() to mirror the convert_<type>field_value() methods.
to
• To use the new date lookup, third-party database backends may need to implement the
DatabaseOperations.datetime_cast_date_sql() method.
• The DatabaseOperations.time_extract_sql() method was added.
It calls the existing date_extract_sql() method. This method is overridden by the SQLite backend to add time lookups
(hour, minute, second) to
, and may be needed by third-party database backends.
• The DatabaseOperations.datetime_cast_sql() method (not to be confused with
DatabaseOperations.datetime_cast_date_sql() mentioned above) has been removed.
This method served to format dates on Oracle long before 1.0, but hasn’t been overridden by any core backend in years and hasn’t been called anywhere in Django’s code or tests.
• In order to support test parallelization, you must implement the
DatabaseCreation.
_clone_test_db() method and set DatabaseFeatures.can_clone_databases = True.
You may have to adjust DatabaseCreation.get_test_db_clone_settings().
Default settings that were tuples are now lists
The default settings in django.conf.global_settings were a combination of lists and tuples. All settings that were formerly tuples are now lists.
is_usable attribute on template loaders is removed
Django template loaders previously required an is_usable attribute to be defined. If a loader was configured in the template settings and this attribute was False, the loader would be silently ignored. In practice, this was only used by the egg loader to detect if setuptools was installed. The is_usable attribute is now removed and the egg loader instead fails at runtime if setuptools is not installed.
Related set direct assignment
Direct assignment of related objects in the ORM used to perform a clear() followed by a call to add(). This caused needlessly large data changes and prevented using the
signal to track individual changes in many-to-many relations.
Direct assignment now relies on the the new
method on related managers which by default only processes changes between the existing related set and the one that’s newly assigned. The previous behavior can be restored by replacing direct assignment by a call to set() with the keyword argument clear=True.
ModelForm
, and therefore ModelAdmin, internally rely on direct assignment for many-to-many relations and as a consequence now use the new behavior.
1468 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
Filesystem-based template loaders catch more specific exceptions
When using the
or
template loaders, earlier versions of
Django raised a
error if a template source existed but was unreadable. This could happen under many circumstances, such as if Django didn’t have permissions to open the file, or if the template source was a directory. Now, Django only silences the exception if the template source does not exist. All other situations result in the original IOError being raised.
HTTP redirects no longer forced to absolute URIs
Relative redirects are no longer converted to absolute URIs.
RFC 2616 required the Location header in redirect responses to be an absolute URI, but it has been superseded by RFC 7231 which allows relative URIs in Location, recognizing the actual practice of user agents, almost all of which support them.
Consequently, the expected URLs passed to assertRedirects should generally no longer include the scheme and domain part of the URLs. For example, self.assertRedirects(response, 'http://testserver/ some-url/') should be replaced by self.assertRedirects(response, '/some-url/') (unless the redirection specifically contained an absolute URL, of course).
In the rare case that you need the old behavior (discovered with an ancient version of Apache with mod_scgi that interprets a relative redirect as an “internal redirect”), you can restore it by writing a custom middleware:
class LocationHeaderFix
( object ):
def process_response
( self , request, response):
if
'Location'
in
response: response[ 'Location' ] = request.build_absolute_uri(response[ 'Location' ])
return
response
Dropped support for PostgreSQL 9.0
Upstream support for PostgreSQL 9.0 ended in September 2015. As a consequence, Django 1.9 sets 9.1 as the minimum PostgreSQL version it officially supports.
Dropped support for Oracle 11.1
Upstream support for Oracle 11.1 ended in August 2015. As a consequence, Django 1.9 sets 11.2 as the minimum
Oracle version it officially supports.
Bulk behavior of add() method of related managers
To improve performance, the add() methods of the related managers created by ForeignKey and
GenericForeignKey changed from a series of Model.save() calls to a single QuerySet.update() call.
The change means that pre_save and post_save signals aren’t sent anymore. You can use the bulk=False keyword argument to revert to the previous behavior.
Template LoaderOrigin and StringOrigin are removed
In previous versions of Django, when a template engine was initialized with debug as True, an instance of django.
template.loader.LoaderOrigin
or django.template.base.StringOrigin was set as the origin attribute on the template object. These classes have been combined into
and is now always set regardless of
9.1. Final releases 1469
Django Documentation, Release 2.0.dev20170914110741
the engine debug setting. For a minimal level of backwards compatibility, the old class names will be kept as aliases to the new Origin class until Django 2.0.
Changes to the default logging configuration
To make it easier to write custom logging configurations, Django’s default logging configuration no longer defines django.request
and django.security loggers. Instead, it defines a single django logger, filtered at the
INFO level, with two handlers:
• console: filtered at the INFO level and only active if DEBUG=True.
• mail_admins: filtered at the ERROR level and only active if DEBUG=False.
If you aren’t overriding Django’s default logging, you should see minimal changes in behavior, but you might see some new logging to the runserver console, for example.
If you are overriding Django’s default logging, you should check to see how your configuration merges with the new defaults.
HttpRequest details in error reporting
It was redundant to display the full details of the
each time it appeared as a stack frame variable in the HTML version of the debug page and error email. Thus, the HTTP request will now display the same standard representation as other variables (repr(request)). As a result, the ExceptionReporterFilter.
get_request_repr() method and the undocumented django.http.build_request_repr() function were removed.
The contents of the text version of the email were modified to provide a traceback of the same structure as in the case of AJAX requests. The traceback details are rendered by the ExceptionReporter.get_traceback_text() method.
Removal of time zone aware global adapters and converters for datetimes
Django no longer registers global adapters and converters for managing time zone information on datetime values sent to the database as query parameters or read from the database in query results. This change affects projects that meet all the following conditions:
• The
setting is True.
• The database is SQLite, MySQL, Oracle, or a third-party database that doesn’t support time zones. In doubt, you can check the value of connection.features.supports_timezones.
• The code queries the database outside of the ORM, typically with cursor.execute(sql, params).
If you’re passing aware datetime parameters to such queries, you should turn them into naive datetimes in UTC:
from
django.utils
import
timezone param = timezone.make_naive(param, timezone.utc)
If you fail to do so, the conversion will be performed as in earlier versions (with a deprecation warning) up until
Django 1.11. Django 2.0 won’t perform any conversion, which may result in data corruption.
If you’re reading datetime values from the results, they will be naive instead of aware. You can compensate as follows:
1470 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
from
django.utils
import
timezone value = timezone.make_aware(value, timezone.utc)
You don’t need any of this if you’re querying the database through the ORM, even if you’re using
queries. The
ORM takes care of managing time zone information.
Template tag modules are imported when templates are configured
The
backend now performs discovery on installed template tag modules when instantiated.
This update enables libraries to be provided explicitly via the 'libraries' key of
when defining a
backend. Import or syntax errors in template tag modules now fail early at instantiation time rather than when a template with a
tag is first compiled.
django.template.base.add_to_builtins() is removed
Although it was a private API, projects commonly used add_to_builtins() to make template tags and filters available without using the
tag. This API has been formalized. Projects should now define built-in libraries via the 'builtins' key of
when defining a
backend.
simple_tag now wraps tag output in conditional_escape
In general, template tags do not autoescape their contents, and this behavior is
For tags like
, this is not a problem because the included template will perform autoescaping.
For assignment_tag()
, the output will be escaped when it is used as a variable in the template.
For the intended use cases of
, however, it is very easy to end up with incorrect HTML and possibly an
XSS exploit. For example:
@register.simple_tag(takes_context=True)
def greeting
(context):
return
"Hello {0}!"
.
format(context[ 'request' ].user.first_name)
In older versions of Django, this will be an XSS issue because user.first_name is not escaped.
In Django 1.9, this is fixed: if the template context has autoescape=True set (the default), then simple_tag will wrap the output of the tag function with
To fix your simple_tags, it is best to apply the following practices:
• Any code that generates HTML should use either the template system or
• If the output of a simple_tag needs escaping, use
or
• If you are absolutely certain that you are outputting HTML from a trusted source (e.g. a CMS field that stores
HTML entered by admins), you can mark it as such using
Tags that follow these rules will be correct and safe whether they are run on Django 1.9+ or earlier.
Paginator.page_range
is now an iterator instead of a list.
In versions of Django previous to 1.8, Paginator.page_range returned a list in Python 2 and a range in
Python 3. Django 1.8 consistently returned a list, but an iterator is more efficient.
9.1. Final releases 1471
Django Documentation, Release 2.0.dev20170914110741
Existing code that depends on list specific features, such as indexing, can be ported by converting the iterator into a list using list().
Implicit QuerySet __in lookup removed
In earlier versions, queries such as:
Model.objects.filter(related_id=RelatedModel.objects.all()) would implicitly convert to:
Model.objects.filter(related_id__in=RelatedModel.objects.all()) resulting in SQL like "related_id IN (SELECT id FROM ...)".
This implicit __in no longer happens so the “IN” SQL is now “=”, and if the subquery returns multiple results, at least some databases will throw an error.
contrib.admin
browser support
The admin no longer supports Internet Explorer 8 and below, as these browsers have reached end-of-life.
CSS and images to support Internet Explorer 6 and 7 have been removed. PNG and GIF icons have been replaced with
SVG icons, which are not supported by Internet Explorer 8 and earlier.
The jQuery library embedded in the admin has been upgraded from version 1.11.2 to 2.1.4. jQuery 2.x has the same
API as jQuery 1.x, but does not support Internet Explorer 6, 7, or 8, allowing for better performance and a smaller file size. If you need to support IE8 and must also use the latest version of Django, you can override the admin’s copy of jQuery with your own by creating a Django application with this structure: app/static/admin/js/vendor/ jquery.js jquery.min.js
SyntaxError when installing Django setuptools 5.5.x
When installing Django 1.9 or 1.9.1 with setuptools 5.5.x, you’ll see:
Compiling django/conf/app_template/apps.py ...
File "django/conf/app_template/apps.py", line 4 class {{ camel_case_app_name }}Config(AppConfig):
^
SyntaxError: invalid syntax
Compiling django/conf/app_template/models.py ...
File "django/conf/app_template/models.py", line 1
{{ unicode_literals }}from django.db import models
^
SyntaxError: invalid syntax
It’s safe to ignore these errors (Django will still install just fine), but you can avoid them by upgrading setuptools to a more recent version. If you’re using pip, you can upgrade pip using pip install -U pip which will also upgrade setuptools. This is resolved in later versions of Django as described in the
1472 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
Miscellaneous
• The jQuery static files in contrib.admin have been moved into a vendor/jquery subdirectory.
• The text displayed for null columns in the admin changelist list_display cells has changed from (None)
(or its translated equivalent) to - (a dash).
• django.http.responses.REASON_PHRASES
and django.core.handlers.wsgi.
STATUS_CODE_TEXT have been removed. Use Python’s stdlib instead: http.client.responses
for
Python 3 and httplib.responses
for Python 2.
• ValuesQuerySet and ValuesListQuerySet have been removed.
• The admin/base.html template no longer sets window.__admin_media_prefix__ or window.
__admin_utc_offset__
. Image references in JavaScript that used that value to construct absolute URLs have been moved to CSS for easier customization. The UTC offset is stored on a data attribute of the <body> tag.
• CommaSeparatedIntegerField validation has been refined to forbid values like ',', ',1', and '1,,
2' .
• Form initialization was moved from the
method to the new
method.
This may be backwards incompatible if you have overridden the get_context_data() method without calling super().
• Support for PostGIS 1.5 has been dropped.
• The django.contrib.sites.models.Site.domain field was changed to be
• In order to enforce test isolation, database queries are not allowed by default in
tests anymore. You can disable this behavior by setting the
class attribute to True on your test class.
• ResolverMatch.app_name was changed to contain the full namespace path in the case of nested namespaces. For consistency with ResolverMatch.namespace, the empty value is now an empty string instead of None.
• For security hardening, session keys must be at least 8 characters.
• Private function django.utils.functional.total_ordering() has been removed. It contained a workaround for a functools.total_ordering() bug in Python versions older than 2.7.3.
• XML serialization (either through
or the syndication framework) used to output any characters it received. Now if the content to be serialized contains any control characters not allowed in the XML 1.0
standard, the serialization will fail with a
ValueError
.
•
now strips input of leading and trailing whitespace by default. This can be disabled by setting the new
argument to False.
• Template text that is translated and uses two or more consecutive percent signs, e.g. "%%", may have a new msgid after makemessages is run (most likely the translation will be marked fuzzy). The new msgid will be marked "#, python-format".
• If neither
nor
are set, the
template tag will now use the namespace of the current request. Set request.current_app to None if you don’t want to use a namespace hint.
• The
setting now silences messages of all levels. Previously, messages of
ERROR level or higher were printed to the console.
• The FlatPage.enable_comments field is removed from the FlatPageAdmin as it’s unused by the application. If your project or a third-party app makes use of it,
to add it back.
9.1. Final releases 1473
Django Documentation, Release 2.0.dev20170914110741
• The return value of
and the first argument of
changed.
They used to be (old_names, mirrors) tuples. Now they’re just the first item, old_names.
• By default
attempts to find an available port in the 8081-8179 range instead of just trying port 8081.
• The system checks for
now check instances rather than classes.
• The private API to apply mixed migration plans has been dropped for performance reasons. Mixed plans consist of a list of migrations where some are being applied and others are being unapplied.
• The related model object descriptor classes in django.db.models.fields.related (private API) are moved from the related module to related_descriptors and renamed as follows:
– ReverseSingleRelatedObjectDescriptor is ForwardManyToOneDescriptor
– SingleRelatedObjectDescriptor is ReverseOneToOneDescriptor
– ForeignRelatedObjectsDescriptor is ReverseManyToOneDescriptor
– ManyRelatedObjectsDescriptor is ManyToManyDescriptor
• If you implement a custom
view, it must return a response with an HTTP 404 status code. Use
or pass status=404 to the
won’t work correctly with DEBUG=False.
Features deprecated in 1.9
assignment_tag()
Django 1.4 added the assignment_tag helper to ease the creation of template tags that store results in a template variable. The
helper has gained this same ability, making the assignment_tag obsolete. Tags that use assignment_tag should be updated to use simple_tag.
{% cycle %} syntax with comma-separated arguments
The
tag supports an inferior old syntax from previous Django versions:
{% cycle
row1
,
row2
,
row3
%}
Its parsing caused bugs with the current syntax, so support for the old syntax will be removed in Django 1.10 following an accelerated deprecation.
ForeignKey and OneToOneField on_delete argument
In order to increase awareness about cascading model deletion, the on_delete argument of ForeignKey and
OneToOneField will be required in Django 2.0.
Update models and existing migrations to explicitly set the argument. Since the default is models.CASCADE, add on_delete=models.CASCADE
to all ForeignKey and OneToOneFields that don’t use a different option.
You can also pass it as the second positional argument if you don’t care about compatibility with older versions of
Django.
1474 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
Field.rel
changes
Field.rel
and its methods and attributes have changed to match the related fields API. The Field.rel attribute is renamed to remote_field and many of its methods and attributes are either changed or renamed.
The aim of these changes is to provide a documented API for relation fields.
GeoManager and GeoQuerySet custom methods
All custom GeoQuerySet methods (area(), distance(), gml(), ...) have been replaced by equivalent geographic expressions in annotations (see in new features). Hence the need to set a custom GeoManager to GIS-enabled models is now obsolete. As soon as your code doesn’t call any of the deprecated methods, you can simply remove the objects = GeoManager() lines from your models.
Template loader APIs have changed
Django template loaders have been updated to allow recursive template extending. This change necessitated a new template loader API. The old load_template() and load_template_sources() methods are now deprecated. Details about the new API can be found
in the template loader documentation
Passing a 3-tuple or an app_name to include()
The instance namespace part of passing a tuple as an argument to include() has been replaced by passing the namespace argument to include(). For example: polls_patterns = [ url(...),
] urlpatterns = [ url( r'^polls/' , include((polls_patterns, 'polls' , 'author-polls' ))),
] becomes: polls_patterns = ([ url(...),
], 'polls' ) # 'polls' is the app_name urlpatterns = [ url( r'^polls/' , include(polls_patterns, namespace= 'author-polls' )),
]
The app_name argument to include() has been replaced by passing a 2-tuple (as above), or passing an object or module with an app_name attribute (as below). If the app_name is set in this new way, the namespace argument is no longer required. It will default to the value of app_name. For example, the URL patterns in the tutorial are changed from: mysite/urls.py
urlpatterns = [ url( r'^polls/' , include( 'polls.urls' , namespace= "polls" )),
...
]
9.1. Final releases 1475
Django Documentation, Release 2.0.dev20170914110741
to: mysite/urls.py
urlpatterns = [ url( r'^polls/' , include( 'polls.urls' )), # 'namespace="polls"' removed
...
] polls/urls.py
app_name = 'polls' # added urlpatterns = [...]
This change also means that the old way of including an AdminSite instance is deprecated. Instead, pass admin.
site.urls
directly to
urls.py
from
django.conf.urls
import
url
from
django.contrib
import
admin urlpatterns = [ url( r'^admin/' , admin.site.urls),
]
URL application namespace required if setting an instance namespace
In the past, an instance namespace without an application namespace would serve the same purpose as the application namespace, but it was impossible to reverse the patterns if there was an application namespace with the same name.
Includes that specify an instance namespace require that the included URLconf sets an application namespace.
current_app parameter to contrib.auth views
All views in django.contrib.auth.views have the following structure:
def view
(request, ..., current_app=None, ...):
...
if
current_app is not None: request.current_app = current_app
return
TemplateResponse(request, template_name, context)
As of Django 1.8, current_app is set on the request object. For consistency, these views will require the caller to set current_app on the request instead of passing it in a separate argument.
django.contrib.gis.geoip
The
module supersedes django.contrib.gis.geoip. The new module provides a similar API except that it doesn’t provide the legacy GeoIP-Python API compatibility methods.
1476 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
Miscellaneous
• The weak argument to django.dispatch.signals.Signal.disconnect() has been deprecated as it has no effect.
• The check_aggregate_support() method of django.db.backends.base.
BaseDatabaseOperations has been deprecated and will be removed in Django 2.0.
The more general check_expression_support() should be used instead.
• django.forms.extras is deprecated.
You can find
in django.forms.
widgets
(or simply django.forms) instead.
• Private API django.db.models.fields.add_lazy_relation() is deprecated.
• The django.contrib.auth.tests.utils.skipIfCustomUser() decorator is deprecated. With the test discovery changes in Django 1.6, the tests for django.contrib apps are no longer run as part of the user’s project. Therefore, the @skipIfCustomUser decorator is no longer needed to decorate tests in django.contrib.auth
.
• If you customized some
error handlers , the view signatures with only one request parameter are deprecated.
The views should now also accept a second exception positional parameter.
• The django.utils.feedgenerator.Atom1Feed.mime_type
and django.utils.
feedgenerator.RssFeed.mime_type
attributes are deprecated in favor of content_type.
•
now issues a warning if an invalid separator is used. This will become an exception in Django 1.10.
• django.db.models.Field._get_val_from_obj() is deprecated in favor of
Field.
value_from_object()
.
• django.template.loaders.eggs.Loader is deprecated as distributing applications as eggs is not recommended.
• The callable_obj keyword argument to SimpleTestCase.assertRaisesMessage() is deprecated. Pass the callable as a positional argument instead.
• The allow_tags attribute on methods of ModelAdmin has been deprecated. Use
when constructing the method’s return value instead.
• The enclosure keyword argument to SyndicationFeed.add_item() is deprecated. Use the new enclosures argument which accepts a list of Enclosure objects instead of a single one.
• The django.template.loader.LoaderOrigin and django.template.base.StringOrigin
aliases for django.template.base.Origin are deprecated.
Features removed in 1.9
These features have reached the end of their deprecation cycle and are removed in Django 1.9. See
for details, including how to remove usage of these features.
• django.utils.dictconfig is removed.
• django.utils.importlib is removed.
• django.utils.tzinfo is removed.
• django.utils.unittest is removed.
• The syncdb command is removed.
• django.db.models.signals.pre_syncdb and django.db.models.signals.post_syncdb
is removed.
9.1. Final releases 1477
Django Documentation, Release 2.0.dev20170914110741
• Support for allow_syncdb on database routers is removed.
• Automatic syncing of apps without migrations is removed. Migrations are compulsory for all apps unless you pass the
option.
• The SQL management commands for apps without migrations, sql , sqlall , sqlclear , sqldropindexes
, and sqlindexes, are removed.
• Support for automatic loading of initial_data fixtures and initial SQL data is removed.
• All models need to be defined inside an installed application or declare an explicit
it isn’t possible to import them before their application is loaded. In particular, it isn’t possible to import models inside the root package of an application.
• The model and form IPAddressField is removed. A stub field remains for compatibility with historical migrations.
• AppCommand.handle_app() is no longer supported.
• RequestSite and get_current_site() are no longer importable from django.contrib.sites.
models .
• FastCGI support via the runfcgi management command is removed.
• django.utils.datastructures.SortedDict is removed.
• ModelAdmin.declared_fieldsets is removed.
• The util modules that provided backwards compatibility are removed:
– django.contrib.admin.util
– django.contrib.gis.db.backends.util
– django.db.backends.util
– django.forms.util
• ModelAdmin.get_formsets is removed.
• The backward compatible shims introduced to rename the BaseMemcachedCache.
_get_memcache_timeout() method to get_backend_timeout() is removed.
• The --natural and -n options for
are removed.
• The use_natural_keys argument for serializers.serialize() is removed.
• Private API django.forms.forms.get_declared_fields() is removed.
• The ability to use a SplitDateTimeWidget with DateTimeField is removed.
• The WSGIRequest.REQUEST property is removed.
• The class django.utils.datastructures.MergeDict is removed.
• The zh-cn and zh-tw language codes are removed.
• The internal django.utils.functional.memoize() is removed.
• django.core.cache.get_cache is removed.
• django.db.models.loading is removed.
• Passing callable arguments to querysets is no longer possible.
• BaseCommand.requires_model_validation
is removed requires_system_checks
. Admin validators is replaced by admin checks.
in favor
• The ModelAdmin.validator_class and default_validator_class attributes are removed.
of
1478 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
• ModelAdmin.validate() is removed.
• django.db.backends.DatabaseValidation.validate_field is removed in favor of the check_field method.
• The validate management command is removed.
• django.utils.module_loading.import_by_path is removed in favor of django.utils.
module_loading.import_string
.
• ssi and url template tags are removed from the future template tag library.
• django.utils.text.javascript_quote() is removed.
• Database test settings as independent entries in the database settings, prefixed by TEST_, are no longer supported.
• The cache_choices option to
and
is removed.
• The default value of the
attribute has changed from True to False.
• django.contrib.sitemaps.FlatPageSitemap is removed in favor of django.contrib.
flatpages.sitemaps.FlatPageSitemap
.
• Private API django.test.utils.TestTemplateLoader is removed.
• The django.contrib.contenttypes.generic module is removed.
1.8 release
Django 1.8.18 release notes
April 4, 2017
Django 1.8.18 fixes two security issues in 1.8.17.
CVE-2017-7233: Open redirect and possible XSS attack via user-supplied numeric redirect URLs
Django relies on user input in some cases (e.g.
django.contrib.auth.views.login()
and
rect the user to an “on success” URL. The security check for these redirects (namely django.utils.http.
is_safe_url()
) considered some numeric URLs (e.g. http:999999999) “safe” when they shouldn’t be.
Also, if a developer relies on is_safe_url() to provide safe redirect targets and puts such a URL into a link, they could suffer from an XSS attack.
CVE-2017-7234: Open redirect vulnerability in django.views.static.serve()
A maliciously crafted URL to a Django site using the
view could redirect to any other domain. The view no longer does any redirects as they don’t provide any known, useful functionality.
Note, however, that this view has always carried a warning that it is not hardened for production use and should be used only as a development aid.
Django 1.8.17 release notes
December 1, 2016
Django 1.8.17 fixes a regression in 1.8.16.
9.1. Final releases 1479
Django Documentation, Release 2.0.dev20170914110741
Bugfixes
• Quoted the Oracle test user’s password in queries to fix the “ORA-00922: missing or invalid option” error when the password starts with a number or special character ( #27420 ).
Django 1.8.16 release notes
November 1, 2016
Django 1.8.16 fixes two security issues in 1.8.15.
User with hardcoded password created when running tests on Oracle
When running tests with an Oracle database, Django creates a temporary database user. In older versions, if a password isn’t manually specified in the database settings TEST dictionary, a hardcoded password is used. This could allow an attacker with network access to the database server to connect.
This user is usually dropped after the test suite completes, but not when using the manage.py test --keepdb option or if the user has an active session (such as an attacker’s connection).
A randomly generated password is now used for each test run.
DNS rebinding vulnerability when DEBUG=True
Older versions of Django don’t validate the Host header against settings.ALLOWED_HOSTS when settings.
DEBUG=True . This makes them vulnerable to a DNS rebinding attack .
While Django doesn’t ship a module that allows remote code execution, this is at least a cross-site scripting vector, which could be quite serious if developers load a copy of the production database in development or connect to some production services for which there’s no development instance, for example. If a project uses a package like the django-debug-toolbar
, then the attacker could execute arbitrary SQL, which could be especially bad if the developers connect to the database with a superuser account.
settings.ALLOWED_HOSTS
is now validated regardless of DEBUG. For convenience, if ALLOWED_HOSTS is empty and DEBUG=True, the following variations of localhost are allowed ['localhost', '127.0.0.1',
'::1']
. If your local settings file has your production ALLOWED_HOSTS value, you must now omit it to get those fallback values.
Django 1.8.15 release notes
September 26, 2016
Django 1.8.15 fixes a security issue in 1.8.14.
CSRF protection bypass on a site with Google Analytics
An interaction between Google Analytics and Django’s cookie parsing could allow an attacker to set arbitrary cookies leading to a bypass of CSRF protection.
The parser for request.COOKIES is simplified to better match the behavior of browsers and to mitigate this attack.
request.COOKIES
may now contain cookies that are invalid according to
RFC 6265 but are possible to set via document.cookie
.
1480 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
Django 1.8.14 release notes
July 18, 2016
Django 1.8.14 fixes a security issue and a bug in 1.8.13.
XSS in admin’s add/change related popup
Unsafe usage of JavaScript’s Element.innerHTML could result in XSS in the admin’s add/change related popup.
Element.textContent
is now used to prevent execution of the data.
The debug view also used innerHTML. Although a security issue wasn’t identified there, out of an abundance of caution it’s also updated to use textContent.
Bugfixes
• Fixed missing varchar/text_pattern_ops index on CharField and TextField respectively when using AddField on PostgreSQL ( #26889 ).
Django 1.8.13 release notes
May 2, 2016
Django 1.8.13 fixes several bugs in 1.8.12.
Bugfixes
• Fixed TimeField microseconds round-tripping on MySQL and SQLite ( #26498 ).
• Restored conversion of an empty string to null when saving values of GenericIPAddressField on SQLite and MySQL ( #26557 ).
Django 1.8.12 release notes
April 1, 2016
Django 1.8.12 fixes several bugs in 1.8.11.
Bugfixes
• Made MultiPartParser ignore filenames that normalize to an empty string to fix crash in
MemoryFileUploadHandler on specially crafted user input ( #26325 ).
• Fixed data loss on SQLite where DurationField values with fractional seconds could be saved as None
( #26324 ).
• Restored the functionality of the admin’s raw_id_fields in list_editable ( #26387 ).
9.1. Final releases 1481
Django Documentation, Release 2.0.dev20170914110741
Django 1.8.11 release notes
March 5, 2016
Django 1.8.11 fixes a regression on Python 2 in the 1.8.10 security release where utils.http.is_safe_url() crashes on bytestring URLs ( #26308 ).
Django 1.8.10 release notes
March 1, 2016
Django 1.8.10 fixes two security issues and several bugs in 1.8.9.
CVE-2016-2512: Malicious redirect and possible XSS attack via user-supplied redirect URLs containing basic auth
Django relies on user input in some cases (e.g.
django.contrib.auth.views.login()
and
rect the user to an “on success” URL. The security check for these redirects (namely django.utils.http.
is_safe_url()
) considered some URLs with basic authentication credentials “safe” when they shouldn’t be.
For example, a URL like http://mysite.example.com\@attacker.com would be considered safe if the request’s host is http://mysite.example.com, but redirecting to this URL sends the user to attacker.com.
Also, if a developer relies on is_safe_url() to provide safe redirect targets and puts such a URL into a link, they could suffer from an XSS attack.
CVE-2016-2513: User enumeration through timing difference on password hasher work factor upgrade
In each major version of Django since 1.6, the default number of iterations for the PBKDF2PasswordHasher and its subclasses has increased. This improves the security of the password as the speed of hardware increases, however, it also creates a timing difference between a login request for a user with a password encoded in an older number of iterations and login request for a nonexistent user (which runs the default hasher’s default number of iterations since
Django 1.6).
This only affects users who haven’t logged in since the iterations were increased. The first time a user logs in after an iterations increase, their password is updated with the new iterations and there is no longer a timing difference.
The new BasePasswordHasher.harden_runtime() method allows hashers to bridge the runtime gap between the work factor (e.g. iterations) supplied in existing encoded passwords and the default work factor of the hasher. This method is implemented for PBKDF2PasswordHasher and BCryptPasswordHasher. The number of rounds for the latter hasher hasn’t changed since Django 1.4, but some projects may subclass it and increase the work factor as needed.
A warning will be emitted for any
third-party password hashers that don’t implement
a harden_runtime() method.
If you have different password hashes in your database (such as SHA1 hashes from users who haven’t logged in since the default hasher switched to PBKDF2 in Django 1.4), the timing difference on a login request for these users may be even greater and this fix doesn’t remedy that difference (or any difference when changing hashers). You may be able to
to prevent a timing attack for that case.
1482 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
Bugfixes
• Fixed a crash on PostgreSQL that prevented using TIME_ZONE=None and USE_TZ=False ( #26177 ).
• Added system checks for query name clashes of hidden relationships ( #26162 ).
• Made forms.FileField and utils.translation.lazy_number() picklable ( #26212 ).
• Fixed
and
serialization with None values ( #26215 ).
• Reallowed dashes in top-level domain names of URLs checked by URLValidator to fix a regression in
Django 1.8 ( #26204 ).
• Fixed BoundField to reallow slices of subwidgets ( #26267 ).
• Prevented ContentTypeManager instances from sharing their cache ( #26286 ).
Django 1.8.9 release notes
February 1, 2016
Django 1.8.9 fixes several bugs in 1.8.8.
Bugfixes
• Fixed a regression that caused the “user-tools” items to display on the admin’s logout page ( #26035 ).
• Fixed a crash in the translations system when the current language has no translations ( #26046 ).
• Fixed a regression that caused the incorrect day to be selected when opening the admin calendar widget for timezones from GMT+0100 to GMT+1200 ( #24980 ).
• Fixed a regression in 1.8.8 causing incorrect index handling in migrations on PostgreSQL when adding db_index=True or unique=True to a CharField or TextField that already had the other specified, or when removing one of them from a field that had both, or when adding unique=True to a field already listed in unique_together ( #26034 ).
• Fixed a crash when using an __in lookup inside a Case expression ( #26071 ).
• Fixed a crash when using a reverse OneToOneField in ModelAdmin.readonly_fields ( #26060 ).
• Fixed a regression in Django 1.8.5 that broke copying a SimpleLazyObject with copy.copy() ( #26122 ).
• Fixed the contrib.gis map widgets when using USE_THOUSAND_SEPARATOR=True ( #20415 ).
Django 1.8.8 release notes
January 2, 2016
Django 1.8.8 fixes several bugs in 1.8.7.
Python 3.2 users, please be advised that we’ve decided to drop support for Python 3.2 in Django 1.8.x at the end of
2016. We won’t break things intentionally after that, but we won’t test subsequent releases against Python 3.2 either.
Upstream support for Python 3.2 ends February 2016 so we don’t find much value in providing security updates for a version of Python that could be insecure. To read more about the decision and to let us know if this will be problematic for you, please read the django-developers thread .
9.1. Final releases 1483
Django Documentation, Release 2.0.dev20170914110741
Bugfixes
• Fixed incorrect unique_together field name generation by inspectdb ( #25274 ).
• Corrected __len query lookup on ArrayField for empty arrays ( #25772 ).
• Restored the ability to use custom formats from formats.py with django.utils.formats.
get_format() and the date template filter ( #25812 ).
• Fixed a state bug when migrating a SeparateDatabaseAndState operation backwards ( #25896 ).
• Fixed missing varchar/text_pattern_ops index on CharField and TextField respectively when using AlterField on PostgreSQL ( #25412 ).
• Fixed a state bug when using an AlterModelManagers operation ( #25852 ).
• Fixed a regression which prevented using a language not in Django’s default language list (
( #25915 ).
• django.views.decorators.cache.never_cache() now sends more persuasive headers (added no-cache, no-store, must-revalidate to Cache-Control) to better prevent caching ( #13008 ).
This fixes a problem where a page refresh in Firefox cleared the selected entries in the admin’s filter_horizontal and filter_vertical widgets, which could result in inadvertent data loss if a user didn’t notice that and then submitted the form ( #22955 ).
• Fixed a regression in the admin which ignored line breaks in read-only fields instead of converting them to <br>
( #25465 ).
• Made loaddata skip disabling and enabling database constraints when it doesn’t load any fixtures ( #23372 ).
• Fixed a crash in QuerySet.values()/values_list() after an annotate() and order_by() when values()/values_list() includes a field not in the order_by() ( #25316 ).
Django 1.8.7 release notes
November 24, 2015
Django 1.8.7 fixes a security issue and several bugs in 1.8.6.
Additionally, Django’s vendored version of six, django.utils.six, has been upgraded to the latest release
(1.10.0).
Fixed settings leak possibility in date template filter
If an application allows users to specify an unvalidated format for dates and passes this format to the
filter, e.g. {{ last_updated|date:user_date_format }}, then a malicious user could obtain any secret in the application’s settings by specifying a settings key instead of a date format. e.g. "SECRET_KEY" instead of "j/m/
Y" .
To remedy this, the underlying function used by the date template filter, django.utils.formats.
get_format()
, now only allows accessing the date/time formatting settings.
Bugfixes
• Fixed a crash of the debug view during the autumn DST change when
is False and pytz is installed.
• Fixed a regression in 1.8.6 that caused database routers without an allow_migrate() method to crash
( #25686 ).
1484 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
• Fixed a regression in 1.8.6 by restoring the ability to use Manager objects for the queryset argument of
ModelChoiceField
( #25683 ).
• Fixed a regression in 1.8.6 that caused an application with South migrations in the migrations directory to fail ( #25618 ).
• Fixed a data loss possibility with
if to_attr is set to a ManyToManyField ( #25693 ).
• Fixed a regression in 1.8 by making gettext() once again return UTF-8 bytestrings on Python 2 if the input is a bytestring ( #25720 ).
• Fixed serialization of
and
( #24937 ).
• Fixed the exact lookup of ArrayField ( #25666 ).
• Fixed Model.refresh_from_db() updating of ForeignKey fields with on_delete=models.
SET_NULL
( #25715 ).
• Fixed a duplicate query regression in 1.8 on proxied model deletion ( #25685 ).
• Fixed set_FOO_order() crash when the ForeignKey of a model with order_with_respect_to references a model with a OneToOneField primary key ( #25786 ).
• Fixed incorrect validation for PositiveIntegerField and PositiveSmallIntegerField on
MySQL resulting in values greater than 4294967295 or 65535, respectively, passing validation and being silently truncated by the database ( #25767 ).
Django 1.8.6 release notes
November 4, 2015
Django 1.8.6 adds official support for Python 3.5 and fixes several bugs in 1.8.5.
Bugfixes
• Fixed a regression causing ModelChoiceField to ignore prefetch_related() on its queryset
( #25496 ).
• Allowed “mode=memory” in SQLite test database name if supported ( #12118 ).
• Fixed system check crash on ForeignKey to abstract model ( #25503 ).
• Fixed incorrect queries when you have multiple ManyToManyFields on different models that have the same field name, point to the same model, and have their reverse relations disabled ( #25545 ).
• Allowed filtering over a RawSQL annotation ( #25506 ).
• Made the Concat database function idempotent on SQLite ( #25517 ).
• Avoided a confusing stack trace when starting
with an invalid
setting
( #25510 ). This regression appeared in 1.8.5 as a side effect of fixing #24704 .
• Made deferred models use their proxied model’s _meta.apps for caching and retrieval ( #25563 ). This prevents any models generated in data migrations using QuerySet.defer() from leaking to test and application code.
• Fixed a typo in the name of the strictly_above PostGIS lookup ( #25592 ).
• Fixed crash with contrib.postgres.forms.SplitArrayField and IntegerField on invalid value ( #25597 ).
• Added a helpful error message when Django and South migrations exist in the same directory ( #25618 ).
9.1. Final releases 1485
Django Documentation, Release 2.0.dev20170914110741
• Fixed a regression in URLValidator that allowed URLs with consecutive dots in the domain section (like http://example..com/
) to pass ( #25620 ).
• Fixed a crash with GenericRelation and BaseModelAdmin.to_field_allowed ( #25622 ).
Django 1.8.5 release notes
October 3, 2015
Django 1.8.5 fixes several bugs in 1.8.4.
Bugfixes
• Made the development server’s autoreload more robust ( #24704 ).
• Fixed AssertionError in some delete queries with a model containing a field that is both a foreign and primary key ( #24951 ).
• Fixed AssertionError in some complex queries ( #24525 ).
• Fixed a migrations crash with GenericForeignKey ( #25040 ).
• Made translation.override() clear the overridden language when a translation isn’t initially active
( #25295 ).
• Fixed crash when using a value in ModelAdmin.list_display that clashed with a reverse field on the model ( #25299 ).
• Fixed autocompletion for options of non-argparse management commands ( #25372 ).
• Alphabetized ordering of imports in from django.db import migrations, models statement in newly created migrations ( #25384 ).
• Fixed migrations crash on MySQL when adding a text or a blob field with an unhashable default ( #25393 ).
• Changed Count queries to execute COUNT(*) instead of COUNT('*') as versions of Django before 1.8 did
( #25377 ). This may fix a performance regression on some databases.
• Fixed custom queryset chaining with values() and values_list() ( #20625 ).
• Moved the
unsaved model instance assignment data loss check
on reverse relations to Model.save()
( #25160 ).
• Readded inline foreign keys to form instances when validating model formsets ( #25431 ).
• Allowed using ORM write methods after disabling autocommit with
( #24921 ).
• Fixed the manage.py test --keepdb option on Oracle ( #25421 ).
• Fixed incorrect queries with multiple many-to-many fields on a model with the same ‘to’ model and with related_name set to ‘+’ ( #24505 , #25486 ).
• Fixed pickling a SimpleLazyObject wrapping a model ( #25389 ).
Django 1.8.4 release notes
August 18, 2015
Django 1.8.4 fixes a security issue and several bugs in 1.8.3.
1486 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
Denial-of-service possibility in logout() view by filling session store
Previously, a session could be created when anonymously accessing the
view (provided it wasn’t decorated with
as done in the admin). This could allow an attacker to easily create many new session records by sending repeated requests, potentially filling up the session store or causing other users’ session records to be evicted.
The
has been modified to no longer create empty session records, including when
is active.
Bugfixes
• Added the ability to serialize values from the newly added
( #25019 ).
• Added a system check warning if the old TEMPLATE_* settings are defined in addition to the new TEMPLATES setting.
• Fixed QuerySet.raw() so InvalidQuery is not raised when using the db_column name of a
ForeignKey field with primary_key=True ( #12768 ).
• Prevented an exception in TestCase.setUpTestData() from leaking the transaction ( #25176 ).
• Fixed has_changed() method in contrib.postgres.forms.HStoreField ( #25215 , #25233 ).
• Fixed the recording of squashed migrations when running the migrate command ( #25231 ).
• Moved the
unsaved model instance assignment data loss check
to Model.save() to allow easier usage of in-memory models ( #25160 ).
• Prevented varchar_patterns_ops and text_patterns_ops indexes for ArrayField ( #25180 ).
Django 1.8.3 release notes
July 8, 2015
Django 1.8.3 fixes several security issues and bugs in 1.8.2.
Also, django.utils.deprecation.RemovedInDjango20Warning
was renamed to
RemovedInDjango110Warning as the version roadmap was revised to 1.9, 1.10, 1.11 (LTS), 2.0 (drops
Python 2 support). For backwards compatibility, RemovedInDjango20Warning remains as an importable alias.
Denial-of-service possibility by filling session store
In previous versions of Django, the session backends created a new empty record in the session storage anytime request.session
was accessed and there was a session key provided in the request cookies that didn’t already have a session record. This could allow an attacker to easily create many new session records simply by sending repeated requests with unknown session keys, potentially filling up the session store or causing other users’ session records to be evicted.
The built-in session backends now create a session record only if the session is actually modified; empty session records are not created. Thus this potential DoS is now only possible if the site chooses to expose a session-modifying view to anonymous users.
As each built-in session backend was fixed separately (rather than a fix in the core sessions framework), maintainers of third-party session backends should check whether the same vulnerability is present in their backend and correct it if so.
9.1. Final releases 1487
Django Documentation, Release 2.0.dev20170914110741
Header injection possibility since validators accept newlines in input
the usage of $ instead of \Z in the regular expressions). If you use values with newlines in HTTP response or email headers, you can suffer from header injection attacks. Django itself isn’t vulnerable because
and the mail sending utilities in
prohibit newlines in HTTP and SMTP headers, respectively. While the validators have been fixed in Django, if you’re creating HTTP responses or email messages in other ways, it’s a good idea to ensure that those methods prohibit newlines as well. You might also want to validate that any existing data in your application doesn’t contain unexpected newlines.
are also affected, however, as of
Django 1.6 the GenericIPAddresseField, IPAddressField, SlugField, and URLField form fields which use these validators all strip the input, so the possibility of newlines entering your data only exists if you are using these validators outside of the form fields.
The undocumented, internally unused validate_integer() function is now stricter as it validates using a regular expression instead of simply casting the value using int() and checking if an exception was raised.
Denial-of-service possibility in URL validation
included a regular expression that was extremely slow to evaluate against certain invalid inputs.
This regular expression has been simplified and optimized.
Bugfixes
• Fixed BaseRangeField.prepare_value() to use each base_field’s prepare_value() method
( #24841 ).
• Fixed crash during
if a migrations module either is missing __init__.py or is a file
( #24848 ).
• Fixed QuerySet.exists() returning incorrect results after annotation with Count() ( #24835 ).
• Corrected HStoreField.has_changed() ( #24844 ).
• Reverted an optimization to the CSRF template context processor which caused a regression ( #24836 ).
• Fixed a regression which caused template context processors to overwrite variables set on a RequestContext after it’s created ( #24847 ).
• Prevented the loss of null/not null column properties during field renaming of MySQL databases
( #24817 ).
• Fixed a crash when using a reverse one-to-one relation in ModelAdmin.list_display ( #24851 ).
• Fixed quoting of SQL when renaming a field to AutoField in PostgreSQL ( #24892 ).
• Fixed lack of unique constraint when changing a field from primary_key=True to unique=True
( #24893 ).
• Fixed queryset pickling when using prefetch_related() after deleting objects ( #24831 ).
• Allowed using choices longer than 1 day with DurationField ( #24897 ).
• Fixed a crash when loading squashed migrations from two apps with a dependency between them, where the dependent app’s replaced migrations are partially applied ( #24895 ).
• Fixed recording of applied status for squashed (replacement) migrations ( #24628 ).
• Fixed queryset annotations when using Case expressions with exclude() ( #24833 ).
1488 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
• Corrected join promotion for multiple Case expressions. Annotating a query with multiple Case expressions could unexpectedly filter out results ( #24924 ).
• Fixed usage of transforms in subqueries ( #24744 ).
• Fixed SimpleTestCase.assertRaisesMessage() on Python 2.7.10 ( #24903 ).
• Provided better backwards compatibility for the verbosity argument in optparse management commands by casting it to an integer ( #24769 ).
• Fixed prefetch_related() on databases other than PostgreSQL for models using UUID primary keys
( #24912 ).
• Fixed removing unique_together constraints on MySQL ( #24972 ).
• Fixed crash when uploading images with MIME types that Pillow doesn’t detect, such as bitmap, in forms.
ImageField
( #24948 ).
• Fixed a regression when deleting a model through the admin that has a GenericRelation with a related_query_name
( #24940 ).
• Reallowed non-ASCII values for ForeignKey.related_name on Python 3 by fixing the false positive system check ( #25016 ).
• Fixed inline forms that use a parent object that has a UUIDField primary key and a child object that has an
AutoField primary key ( #24958 ).
• Fixed a regression in the unordered_list template filter on certain inputs ( #25031 ).
• Fixed a regression in URLValidator that invalidated Punycode TLDs ( #25059 ).
• Improved pyinotify runserver polling ( #23882 ).
Django 1.8.2 release notes
May 20, 2015
Django 1.8.2 fixes a security issue and several bugs in 1.8.1.
Fixed session flushing in the cached_db backend
A change to session.flush() in the cached_db session backend in Django 1.8 mistakenly sets the session key to an empty string rather than None. An empty string is treated as a valid session key and the session cookie is set accordingly. Any users with an empty string in their session cookie will use the same session store. session.flush() is called by django.contrib.auth.logout() and, more seriously, by django.
contrib.auth.login() when a user switches accounts. If a user is logged in and logs in again to a different account (without logging out) the session is flushed to avoid reuse. After the session is flushed (and its session key becomes '') the account details are set on the session and the session is saved. Any users with an empty string in their session cookie will now be logged into that account.
Bugfixes
• Fixed check for template engine alias uniqueness ( #24685 ).
• Fixed crash when reusing the same Case instance in a query ( #24752 ).
• Corrected join promotion for Case expressions. For example, annotating a query with a Case expression could unexpectedly filter out results ( #24766 ).
9.1. Final releases 1489
Django Documentation, Release 2.0.dev20170914110741
• Fixed negated Q objects in expressions. Cases like Case(When(~Q(friends__age__lte=30))) tried to generate a subquery which resulted in a crash ( #24705 ).
• Fixed incorrect GROUP BY clause generation on MySQL when the query’s model has a self-referential foreign key ( #24748 ).
• Implemented ForeignKey.get_db_prep_value() so that ForeignKeys pointing to
and inheritance on models with UUIDField primary keys work correctly ( #24698 , #24712 ).
• Fixed isnull lookup for HStoreField ( #24751 ).
• Fixed a MySQL crash when a migration removes a combined index (unique_together or index_together) containing a foreign key ( #24757 ).
• Fixed session cookie deletion when using
( #24799 ).
• On PostgreSQL, when no access is granted for the postgres database, Django now falls back to the default database when it normally requires a “no database” connection ( #24791 ).
• Fixed display of contrib.admin’s ForeignKey widget when it’s used in a row with other fields ( #24784 ).
Django 1.8.1 release notes
May 1, 2015
Django 1.8.1 fixes several bugs in 1.8 and includes some optimizations in the migrations framework.
Bugfixes
• Added support for serializing timedelta objects in migrations ( #24566 ).
• Restored proper parsing of the
command’s positional arguments (fixture names) ( #24571 ).
• Prevented TypeError in translation functions check_for_language() and get_language_bidi() when translations are deactivated ( #24569 ).
• Fixed
command when using
( #24278 ).
• Stripped microseconds from datetime values when using an older version of the MySQLdb DB API driver as it does not support fractional seconds ( #24584 ).
• Fixed a migration crash when altering
#24513 ).
• Fixed a crash with QuerySet.update() on foreign keys to one-to-one fields ( #24578 ).
• Fixed a regression in the model detail view of
when a model has a reverse foreign key relation
( #24624 ).
• Prevented arbitrary file inclusions in
( #24625 ).
• Fixed a crash with QuerySet.update() on foreign keys to instances with uuid primary keys ( #24611 ).
• Fixed database introspection with SQLite 3.8.9 (released April 8, 2015) ( #24637 ).
• Updated urlpatterns examples generated by
to remove usage of referencing views by dotted path in
which is deprecated in Django 1.8 ( #24635 ).
• Fixed queries where an expression was referenced in order_by(), but wasn’t part of the select clause. An example query is qs.annotate(foo=F('field')).values('pk').order_by('foo')) ( #24615 ).
• Fixed a database table name quoting regression ( #24605 ).
1490 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
• Prevented the loss of null/not null column properties during field alteration of MySQL databases
( #24595 ).
• Fixed JavaScript path of contrib.admin’s related field widget when using alternate static file storages
( #24655 ).
• Fixed a migration crash when adding new relations to models ( #24573 ).
• Fixed a migration crash when applying migrations with model managers on Python 3 that were generated on
Python 2 ( #24701 ).
• Restored the ability to use iterators as queryset filter arguments ( #24719 ).
• Fixed a migration crash when renaming the target model of a many-to-many relation ( #24725 ).
• Removed flushing of the test database with
, which prevented apps with data migrations from
using the option ( #24729 ).
• Fixed makemessages crash in some locales ( #23271 ).
• Fixed help text positioning of contrib.admin fields that use the ModelAdmin.filter_horizontal
and filter_vertical options ( #24676 ).
• Fixed AttributeError: function ‘GDALAllRegister’ not found error when initializing contrib.gis on Windows.
Optimizations
• Changed ModelState to deepcopy fields instead of deconstructing and reconstructing ( #24591 ). This speeds up the rendering of model states and reduces memory usage when running
(although other changes in this release may negate any performance benefits).
Django 1.8 release notes
April 1, 2015
Welcome to Django 1.8!
These release notes cover the
new features , as well as some
backwards incompatible changes
you’ll want to be aware of when upgrading from Django 1.7 or older versions. We’ve also
begun the deprecation process for some features ,
and some features have reached the end of their deprecation process and
See the
Upgrading Django to a newer version
guide if you’re updating an existing project.
Django 1.8 has been designated as Django’s second
long-term support release . It will receive security updates for at
least three years after its release. Support for the previous LTS, Django 1.4, will end 6 months from the release date of Django 1.8.
Python compatibility
Django 1.8 requires Python 2.7, 3.2, 3.3, 3.4, or 3.5. We highly recommend and only officially support the latest release of each series.
Django 1.8 is the first release to support Python 3.5.
Due to the end of upstream support for Python 3.2 in February 2016, we won’t test Django 1.8.x on Python 3.2 after the end of 2016.
9.1. Final releases 1491
Django Documentation, Release 2.0.dev20170914110741
What’s new in Django 1.8
Model._meta
API
Django now has a formalized API for
, providing an officially supported way to retrieve fields
and filter fields based on their
The Model._meta object has been part of Django since the days of pre-0.96 “Magic Removal” – it just wasn’t an official, stable API. In recognition of this, we’ve endeavored to maintain backwards-compatibility with the old API endpoint where possible. However, API endpoints that aren’t part of the new official API have been deprecated and will eventually be removed. A
guide to migrating from the old API to the new API
has been provided.
Multiple template engines
Django 1.8 defines a stable API for integrating template backends. It includes built-in support for the Django template language and for
Jinja2 . It supports rendering templates with multiple engines within the same project. Learn more
about the new features in the
and check the upgrade instructions in older versions of the documentation.
Security enhancements
Several features of the django-secure third-party library have been integrated into Django.
provides several security enhancements to the request/response cycle. The new
option allows you to check your production settings file for ways to increase the security of your site.
New PostgreSQL specific functionality
Django now has a module with extensions for PostgreSQL specific features, such as
lookup. A full breakdown of the features is available
New data types
• Django now has a
for storing universally unique identifiers. It is stored as the native uuid data type on PostgreSQL and as a fixed length character field on other backends. There is a corresponding
• Django now has a
for storing periods of time - modeled in Python by timedelta
. It is stored in the native interval data type on PostgreSQL, as a INTERVAL DAY(9) TO SECOND(6) on
Oracle, and as a bigint of microseconds on other backends. Date and time related arithmetic has also been improved on all backends. There is a corresponding
Query Expressions, Conditional Expressions, and Database Functions
allow you to create, customize, and compose complex SQL expressions. This has enabled annotate to accept expressions other than aggregates. Aggregates are now able to reference multiple fields, as well as perform arithmetic, similar to F() objects.
has also gained the ability to accept expressions.
allow you to use if
...
elif
...
else logic within queries.
A collection of
is also included with functionality such as
1492 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
TestCase data setup
has been refactored to allow for data initialization at the class level using transactions and savepoints.
Database backends which do not support transactions, like MySQL with the MyISAM storage engine, will still be able to run these tests but won’t benefit from the improvements. Tests are now run within two nested
blocks: one for the whole class and one for each test.
• The class method
adds the ability to setup test data at the class level. Using this technique can speed up the tests as compared to using setUp().
• Fixture loading within TestCase is now performed once for the whole TestCase.
Minor features django.contrib.admin
•
now has a
method to allow limiting access to the module on the admin index page.
•
now has an attribute
that supports showing a link to an inline object’s change form.
• Use the new django.contrib.admin.RelatedOnlyFieldListFilter
in
to limit the list_filter choices to foreign objects which are attached to those from the
ModelAdmin
.
• The
displays a summary of objects to be deleted on the deletion confirmation page.
• The jQuery library embedded in the admin has been upgraded to version 1.11.2.
• You can now specify
in order to display a link to the front-end site.
• You can now specify
ModelAdmin.show_full_result_count
to control whether or not the full count of objects should be displayed on a filtered admin page.
• The AdminSite.password_change() method now has an extra_context parameter.
• You can now control who may login to the admin site by overriding only
and
. The base.html template has a new block usertools which con-
tains the user-specific header.
A new context variable has_permission, which gets its value from
, indicates whether the user may access the site.
• Foreign key dropdowns now have buttons for changing or deleting related objects using a popup.
django.contrib.admindocs
• reStructuredText is now parsed in model docstrings.
django.contrib.auth
• Authorization backends can now raise
in
and
to short-circuit permission checking.
•
now has a method
that can be overridden to customize the mail to be sent.
9.1. Final releases 1493
Django Documentation, Release 2.0.dev20170914110741
• The max_length of
has been increased from 50 to 255 characters. Please run the database migration.
•
and
now supports
• The default iteration count for the PBKDF2 password hasher has been increased by 33%.
This backwards compatible change will not affect users who have subclassed django.contrib.auth.hashers.
PBKDF2PasswordHasher to change the default value.
django.contrib.gis
• A new
is now available.
• It is now allowed to include a subquery as a geographic lookup argument, for example City.
objects.filter(point__within=Country.objects.filter(continent='Africa').
values('mpoly'))
.
• The SpatiaLite backend now supports Collect and Extent aggregates when the database version is 3.0 or later.
• The PostGIS 2 CREATE EXTENSION postgis and the SpatiaLite SELECT InitSpatialMetaData initialization commands are now automatically run by
• The GDAL interface now supports retrieving properties of
• Compatibility shims for SpatialRefSys and GeometryColumns changed in Django 1.2 have been removed.
• All GDAL-related exceptions are now raised with GDALException. The former OGRException has been kept for backwards compatibility but should not be used any longer.
django.contrib.sessions
• Session cookie is now deleted after
is called.
django.contrib.sitemaps
• The new
attribute allows you to generate a sitemap based on the
setting.
django.contrib.sites
•
will now lookup the current site based on
if the
setting is not defined.
• The default
created when running migrate now respects the
setting (instead of always using pk=1
).
Cache
• The incr() method of the django.core.cache.backends.locmem.LocMemCache backend is now thread-safe.
1494 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
Cryptography
• The max_age parameter of the
django.core.signing.TimestampSigner.unsign()
method now also accepts a datetime.timedelta
object.
Database backends
• The MySQL backend no longer strips microseconds from datetime values as MySQL 5.6.4 and up supports fractional seconds depending on the declaration of the datetime field (when DATETIME includes fractional precision greater than 0). New datetime database columns created with Django 1.8 and MySQL 5.6.4 and up will support microseconds. See the
for more details.
• The MySQL backend no longer creates explicit indexes for foreign keys when using the InnoDB storage engine, as MySQL already creates them automatically.
• The Oracle backend no longer defines the connection_persists_old_columns feature as True. Instead, Oracle will now include a cache busting clause when getting the description of a table.
•
now support the context manager protocol for opening and closing connections.
• The SMTP email backend now supports keyfile and certfile authentication with the
and
settings.
• The SMTP
now supports setting the timeout parameter with the
setting.
•
and EmailMultiAlternatives now support the reply_to parameter.
File Storage
•
and
now take a max_length argument to implement storage-level maximum filename length constraints. Filenames exceeding this argument will get truncated. This prevents a database error when appending a unique suffix to a long filename that already exists on the storage. See the
about adding this argument to your custom storage classes.
Forms
• Form widgets now render attributes with a value of True or False as HTML5 boolean attributes.
• The new
method allows checking if a specific error has happened.
• If
is defined on a form, then the <label> tags for required fields will have this class present in its attributes.
• The rendering of non-field errors in unordered lists (<ul>) now includes nonfield in its list of classes to distinguish them from field-specific errors.
•
now accepts a
argument, which will override the form’s
enables customizing the suffix on a per-field basis — previously it wasn’t possible to override a form’s
while using shortcuts such as {{ form.as_p }} in templates.
•
now accepts an
argument, which will override the top list choice label when
is not required.
9.1. Final releases 1495
Django Documentation, Release 2.0.dev20170914110741
• After an
has been cleaned and validated, the UploadedFile object will have an additional image attribute containing the Pillow Image instance used to check if the file was a valid image. It will also update UploadedFile.content_type with the image’s content type as determined by Pillow.
• You can now pass a callable that returns an iterable of choices when instantiating a
Generic Views
• Generic views that use
may now specify the ordering applied to the
by setting
or overriding
• The new
SingleObjectMixin.query_pk_and_slug
attribute allows changing the behavior of
so that it’ll perform its lookup using both the primary key and the slug.
• The
method doesn’t require a form_class to be provided anymore.
If not provided form_class defaults to
• Placeholders in
now support the Python str.format() syntax. The legacy %(<foo>)s syntax is still supported but will be removed in Django 1.10.
Internationalization
•
can now be a list of strings representing module paths. This allows importing several format modules from different reusable apps. It also allows overriding those custom formats in your main
Django project.
Logging
• The
django.utils.log.AdminEmailHandler
class now has a
method to make it more subclass friendly.
Management Commands
• Database connections are now always closed after a management command called from the command line has finished doing its job.
• Commands from alternate package formats like eggs are now also discovered.
• The new
option allows specifying a file to which the serialized data is written.
• The new
and
options allow excluding specific locales from processing.
•
now has a --use-fuzzy or -f option which includes fuzzy translations into compiled files.
• The
option now ignores data for models that no longer exist.
•
now uses daemon threads for faster reloading.
•
now outputs Meta.unique_together. It is also able to introspect
for MySQL and PostgreSQL databases.
• When calling management commands with options using
, the option name can match the
command line option name (without the initial dashes) or the final option destination variable name, but in either
1496 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
case, the resulting option received by the command is now always the dest name specified in the command option definition (as long as the command uses the argparse module).
• The
command now supports MySQL’s optional SSL certificate authority setting (--ssl-ca).
• The new
allows giving the migration(s) a custom name instead of a generated one.
• The
command now prevents repeated fixture loading. If
contains duplicates or a default fixture directory path (app_name/fixtures), an exception is raised.
• The new makemigrations --exit option allows exiting with an error code if no migrations are created.
• The new
command allows listing all migrations and their dependencies in a project.
Middleware
• The
CommonMiddleware.response_redirect_class
attribute allows you to customize the redirects issued by the middleware.
• A debug message will be logged to the django.request logger when a middleware raises a
exception in
mode.
Migrations
• The
operation can now handle parameters passed to the SQL statements.
• It is now possible to have migrations (most probably
data migrations ) for applications without models.
• Migrations can now
as part of the model state.
• A
generic mechanism to handle the deprecation of model fields
was added.
• The
and
class method/attribute were added to ease in making
RunPython and RunSQL operations reversible.
• The migration operations
and
now call the
method of database routers. The router can use the newly introduced app_label and hints arguments to make a routing decision. To take advantage of this feature you need to update the router to the new allow_migrate signature, see the
for more details.
Models
• Django now logs at most 9000 queries in connections.queries, in order to prevent excessive memory usage in long-running processes in debug mode.
• There is now a model Meta option to define a
for all relational fields of a model.
• Pickling models and querysets across different versions of Django isn’t officially supported (it may work, but there’s no guarantee). An extra variable that specifies the current Django version is now added to the pickled state of models and querysets, and Django raises a RuntimeWarning when these objects are unpickled in a different version than the one in which they were pickled.
• Added
which Django uses whenever objects are loaded using the ORM. The method allows customizing model loading behavior.
• extra(select={...}) now allows you to escape a literal %s sequence using %%s.
•
can now be registered using a decorator pattern.
9.1. Final releases 1497
Django Documentation, Release 2.0.dev20170914110741
• The new
attribute allows creating bilateral transformations. These transformations are applied to both lhs and rhs when used in a lookup expression, providing opportunities for more sophisticated lookups.
• SQL special characters (, %, _) are now escaped properly when a pattern lookup (e.g.
contains , startswith , etc.) is used with an F() expression as the right-hand side. In those cases, the escaping is performed by the database, which can lead to somewhat complex queries involving nested REPLACE function calls.
• You can now refresh model instances by using
• You can now get the set of deferred fields for a model using
• Model field default’s are now used when primary key field’s are set to None.
Signals
• Exceptions from the (receiver, exception) tuples returned by
now have their traceback attached as a __traceback__ attribute.
• The environ argument, which contains the WSGI environment structure from the request, was added to the
signal.
• You can now import the
signal from django.core.signals to avoid loading django.test
in non-test situations. Django no longer does so itself.
System Check Framework
•
can now be used as a function.
Templates
•
now supports domain-only links that include characters after the top-level domain (e.g.
djangoproject.com/ and djangoproject.com/download/).
•
doesn’t treat exclamation marks at the end of a domain or its query string as part of the URL (the URL in e.g. 'djangoproject.com! is djangoproject.com)
• Added a
class that loads Django templates from a Python dictionary.
• The
tag can now store its output in a context variable with the usual syntax: {% now 'j n Y' as varname %}
.
Requests and Responses
• WSGIRequest now respects paths starting with //.
• The
HttpRequest.build_absolute_uri()
method now handles paths starting with // correctly.
• If
is True and a request raises a
SuspiciousOperation , the response will be rendered with a
detailed error page.
• The query_string argument of
is now optional, defaulting to None, so a blank QueryDict can now be instantiated with QueryDict() instead of QueryDict(None) or QueryDict('').
1498 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
• The GET and POST attributes of an
object are now
QueryDict s rather than dictionaries, and
the FILES attribute is now a MultiValueDict. This brings this class into line with the documentation and with WSGIRequest.
• The
attribute was added.
• WSGIRequestHandler now follows RFC in converting URI to IRI, using uri_to_iri().
• The
method now escapes unsafe characters from the path portion of a
Uniform Resource Identifier (URI) properly.
•
now implements a few additional methods like
so that instances can be used as stream objects.
• The new
method allows setting a header unless it has already been set.
• You can use the new
to stream files.
• The
decorator for conditional view processing now supports the If-unmodified-since header.
Tests
• The
and
methods were implemented, allowing you to create TRACE requests in your tests.
• The count argument was added to
. This allows you to assert that a template was
rendered a specific number of times.
• The new
assertion allows you to test that two JSON fragments are not equal.
• Added options to the
command to preserve the test database (
), to run the test cases in reverse order (
), and to enable SQL logging for failing tests (
• Added the
attribute to test client responses.
• Added several settings that allow customization of test tablespace parameters for Oracle:
DATAFILE_TMP , DATAFILE_MAXSIZE
and
• The
decorator can now affect the master router in
• Added test client support for file uploads with file-like objects.
• A shared cache is now used when testing with an SQLite in-memory database when using Python 3.4+ and
SQLite 3.7.13+. This allows sharing the database between threads.
Validators
•
now supports IPv6 addresses, unicode domains, and URLs containing authentication data.
Backwards incompatible changes in 1.8
Warning:
In addition to the changes outlined in this section, be sure to review the
for any features that have been removed. If you haven’t updated your code within the deprecation timeline for a given feature, its removal may appear as a backwards incompatible change.
9.1. Final releases 1499
Django Documentation, Release 2.0.dev20170914110741
Related object operations are run in a transaction
Some operations on related objects such as
or direct assignment ran multiple data modifying queries without wrapping them in transactions. To reduce the risk of data corruption, all data modifying methods that affect multiple related objects (i.e. add(), remove(), clear(), and direct assignment) now perform their data modifying queries from within a transaction, provided your database supports transactions.
This has one backwards incompatible side effect, signal handlers triggered from these methods are now executed within the method’s transaction and any exception in a signal handler will prevent the whole operation.
Assigning unsaved objects to relations raises an error
Note: To more easily allow in-memory usage of models, this change was reverted in Django 1.8.4 and replaced with a check during model.save(). For example:
>>> book = Book.objects.create(name= "Django" )
>>> book.author = Author(name= "John" )
>>> book.save()
Traceback (most recent call last):
...
ValueError : save() prohibited to prevent data loss due to unsaved related object
˓→
'author'.
A similar check on assignment to reverse one-to-one relations was removed in Django 1.8.5.
Assigning unsaved objects to a
now raises a
ValueError
.
Previously, the assignment of an unsaved object would be silently ignored. For example:
>>> book = Book.objects.create(name= "Django" )
>>> book.author = Author(name= "John" )
>>> book.author.save()
>>> book.save()
>>> Book.objects.get(name= "Django" )
>>> book.author
>>>
Now, an error will be raised to prevent data loss:
>>> book.author = Author(name= "john" )
Traceback (most recent call last):
...
ValueError : Cannot assign "<Author: John>": "Author" instance isn't saved in the
˓→ database.
If you require allowing the assignment of unsaved instances (the old behavior) and aren’t concerned about the data loss possibility (e.g. you never save the objects to the database), you can disable this check by using the ForeignKey.
allow_unsaved_instance_assignment attribute. (This attribute was removed in 1.8.4 as it’s no longer relevant.)
1500 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
Management commands that only accept positional arguments
If you have written a custom management command that only accepts positional arguments and you didn’t specify the args command variable, you might get an error like Error: unrecognized arguments: ...
, as variable parsing is now based on argparse which doesn’t implicitly accept positional arguments. You can make your command backwards compatible by simply setting the args class variable. However, if you don’t have to keep compatibility with older Django versions, it’s better to implement the new
method as described in
Writing custom django-admin commands .
Custom test management command arguments through test runner
The method to add custom arguments to the test management command through the test runner has changed. Previously, you could provide an option_list class variable on the test runner to add more arguments (à la optparse
).
Now to implement the same behavior, you have to create an add_arguments(cls, parser) class method on the test runner and call parser.add_argument to add any custom arguments, as parser is now an argparse.
ArgumentParser instance.
Model check ensures auto-generated column names are within limits specified by database
A field name that’s longer than the column name length supported by a database can create problems. For example, with MySQL you’ll get an exception trying to create the column, and with PostgreSQL the column name is truncated by the database (you may see a warning in the PostgreSQL logs).
A model check has been introduced to better alert users to this scenario before the actual creation of database tables.
If you have an existing model where this check seems to be a false positive, for example on PostgreSQL where the name was already being truncated, simply use
to specify the name that’s being used.
The check also applies to the columns generated in an implicit ManyToManyField.through model. If you run into an issue there, use
to create an explicit model and then specify
on its column(s) as needed.
Query relation lookups now check object types
Querying for model lookups now checks if the object passed is of correct type and raises a
ValueError if not.
Previously, Django didn’t care if the object was of correct type; it just used the object’s related field attribute (e.g. id) for the lookup. Now, an error is raised to prevent incorrect lookups:
>>> book = Book.objects.create(name= "Django" )
>>> book = Book.objects.filter(author=book)
Traceback (most recent call last):
...
ValueError : Cannot query "<Book: Django>": Must be "Author" instance.
select_related() now checks given fields
select_related() now validates that the given fields actually exist. Previously, nonexistent fields were silently ignored. Now, an error is raised:
9.1. Final releases 1501
Django Documentation, Release 2.0.dev20170914110741
>>> book = Book.objects.select_related( 'nonexistent_field' )
Traceback (most recent call last):
...
FieldError : Invalid field name(s) given in select_related: 'nonexistent_field'
The validation also makes sure that the given field is relational:
>>> book = Book.objects.select_related( 'name' )
Traceback (most recent call last):
...
FieldError : Non-relational field given in select_related: 'name'
Default EmailField.max_length increased to 254
The old default 75 character max_length was not capable of storing all possible RFC3696/5321-compliant email addresses. In order to store all possible valid email addresses, the max_length has been increased to 254 characters.
You will need to generate and apply database migrations for your affected models (or add max_length=75 if you wish to keep the length on your current fields). A migration for
django.contrib.auth.models.User.
is included.
Support for PostgreSQL versions older than 9.0
The end of upstream support periods was reached in July 2014 for PostgreSQL 8.4. As a consequence, Django 1.8
sets 9.0 as the minimum PostgreSQL version it officially supports.
This also includes dropping support for PostGIS 1.3 and 1.4 as these versions are not supported on versions of PostgreSQL later than 8.4.
Django also now requires the use of Psycopg2 version 2.4.5 or higher (or 2.5+ if you want to use
Support for MySQL versions older than 5.5
The end of upstream support periods was reached in January 2012 for MySQL 5.0 and December 2013 for MySQL
5.1. As a consequence, Django 1.8 sets 5.5 as the minimum MySQL version it officially supports.
Support for Oracle versions older than 11.1
The end of upstream support periods was reached in July 2010 for Oracle 9.2, January 2012 for Oracle 10.1, and July
2013 for Oracle 10.2. As a consequence, Django 1.8 sets 11.1 as the minimum Oracle version it officially supports.
Specific privileges used instead of roles for tests on Oracle
Earlier versions of Django granted the CONNECT and RESOURCE roles to the test user on Oracle. These roles have been deprecated, so Django 1.8 uses the specific underlying privileges instead. This changes the privileges required of the main user for running tests (unless the project is configured to avoid creating a test user). The exact privileges required now are detailed in
1502 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
AbstractUser.last_login
allows null values
The
field now allows null values. Previously, it defaulted to the time when the user
), run the database migration included in contrib.auth.
If you are using a custom user model that inherits from AbstractUser, you’ll need to run
and generate a migration for your app that contains that model. Also, if wish to set last_login to NULL for users who haven’t logged in, you can run this query:
from
django.db
import
models
from
django.contrib.auth
import
get_user_model
from
django.contrib.auth.models
import
AbstractBaseUser
UserModel = get_user_model()
if
issubclass (UserModel, AbstractBaseUser):
UserModel._default_manager.filter( last_login=models.F( 'date_joined' )
).update(last_login=None)
django.contrib.gis
• Support for GEOS 3.1 and GDAL 1.6 has been dropped.
• Support for SpatiaLite < 2.4 has been dropped.
• GIS-specific lookups have been refactored to use the
API.
• The default str representation of
objects has been changed from WKT to EWKT format
(including the SRID). As this representation is used in the serialization framework, that means that dumpdata output will now contain the SRID value of geometry objects.
Priority of context processors for TemplateResponse brought in line with render
The
constructor is designed to be a drop-in replacement for the
function. However, it had a slight incompatibility, in that for TemplateResponse, context data from the passed in context dictionary could be shadowed by context data returned from context processors, whereas for render it was the other way around. This was a bug, and the behavior of render is more appropriate, since it allows the globally defined context processors to be overridden locally in the view. If you were relying on the fact context data in a TemplateResponse could be overridden using a context processor, you will need to change your code.
Overriding setUpClass / tearDownClass in test cases
The decorators
and
now act at the class level when used as class decorators. As a consequence, when overriding setUpClass() or tearDownClass(), the super implementation should always be called.
Removal of django.contrib.formtools
The formtools contrib app has been moved to a separate package and the relevant documentation pages have been updated or removed.
The new package is available on GitHub and on PyPI.
9.1. Final releases 1503
Django Documentation, Release 2.0.dev20170914110741
Database connection reloading between tests
Django previously closed database connections between each test within a TestCase. This is no longer the case as
Django now wraps the whole TestCase within a transaction. If some of your tests relied on the old behavior, you should have them inherit from TransactionTestCase instead.
Cleanup of the django.template namespace
If you’ve been relying on private APIs exposed in the django.template module, you may have to import them from django.template.base instead.
Also private APIs django.template.base.compile_string()
, django.template.loader.
find_template()
, and django.template.loader.get_template_from_string() were removed.
model attribute on private model relations
In earlier versions of Django, on a model with a reverse foreign key relationship (for example), model.
_meta.get_all_related_objects() returned the relationship as a django.db.models.related.
RelatedObject with the model attribute set to the source of the relationship. Now, this method returns the relationship as django.db.models.fields.related.ManyToOneRel (private API RelatedObject has been removed), and the model attribute is set to the target of the relationship instead of the source. The source model is accessible on the related_model attribute instead.
Consider this example from the tutorial in Django 1.8:
>>> p = Poll.objects.get(pk= 1 )
>>> p._meta.get_all_related_objects()
[<ManyToOneRel: polls.choice>]
>>> p._meta.get_all_related_objects()[ 0 ].model
<class 'polls.models.Poll'>
>>> p._meta.get_all_related_objects()[ 0 ].related_model
<class 'polls.models.Choice'> and compare it to the behavior on older versions:
>>> p._meta.get_all_related_objects()
[<RelatedObject: polls:choice related to poll>]
>>> p._meta.get_all_related_objects()[ 0 ].model
<class 'polls.models.Choice'>
To access the source model, you can use a pattern like this to write code that will work with both Django 1.8 and older versions:
for
relation in opts.get_all_related_objects(): to_model = getattr (relation, 'related_model' , relation.model)
Also note that get_all_related_objects() is deprecated in 1.8. See the
for the new API.
Database backend API
The following changes to the database backend API are documented to assist those writing third-party backends in updating their code:
1504 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
• BaseDatabaseXXX classes have been moved to django.db.backends.base. Please import them from the new locations:
from
django.db.backends.base.base
import
BaseDatabaseWrapper
from
django.db.backends.base.client
import
BaseDatabaseClient
from
django.db.backends.base.creation
import
BaseDatabaseCreation
from
django.db.backends.base.features
import
BaseDatabaseFeatures
from
django.db.backends.base.introspection
import
BaseDatabaseIntrospection
from
django.db.backends.base.introspection
import
FieldInfo, TableInfo
from
django.db.backends.base.operations
import
BaseDatabaseOperations
from
django.db.backends.base.schema
import
BaseDatabaseSchemaEditor
from
django.db.backends.base.validation
import
BaseDatabaseValidation
• The data_types, data_types_suffix, and data_type_check_constraints attributes have moved from the DatabaseCreation class to DatabaseWrapper.
• The SQLCompiler.as_sql() method now takes a subquery parameter ( #24164 ).
• The BaseDatabaseOperations.date_interval_sql() method now only takes a timedelta parameter.
django.contrib.admin
• AdminSite no longer takes an app_name argument and its app_name attribute has been removed. The application name is always admin (as opposed to the instance name which you can still customize using
AdminSite(name="...")
.
• The ModelAdmin.get_object() method (private API) now takes a third argument named from_field in order to specify which field should match the provided object_id.
• The
method now takes a second argument named obj_id which is the serialized identifier used to retrieve the object before deletion.
Default autoescaping of functions in django.template.defaultfilters
In order to make built-in template filters that output HTML “safe by default” when calling them in Python code, the following functions in django.template.defaultfilters have been changed to automatically escape their input value:
• join
• linebreaksbr
• linebreaks_filter
• linenumbers
• unordered_list
• urlize
• urlizetrunc
You can revert to the old behavior by specifying autoescape=False if you are passing trusted content. This change doesn’t have any effect when using the corresponding filters in templates.
9.1. Final releases 1505
Django Documentation, Release 2.0.dev20170914110741
Miscellaneous
• connections.queries is now a read-only attribute.
• Database connections are considered equal only if they’re the same object. They aren’t hashable any more.
•
used to disable compression for some content types when the request is from Internet
Explorer, in order to work around a bug in IE6 and earlier. This behavior could affect performance on IE7 and later. It was removed.
• URLField.to_python no longer adds a trailing slash to pathless URLs.
• The
template filter now returns 0 for an undefined variable, rather than an empty string.
• ForeignKey.default_error_message['invalid'] has been changed from '%(model)s instance with pk %(pk)r does not exist.' to
'%(model)s instance with
%(field)s %(value)r does not exist.'
If you are using this message in your own code, please update the list of interpolated parameters. Internally, Django will continue to provide the pk parameter in params for backwards compatibility.
• UserCreationForm.error_messages['duplicate_username'] is no longer used.
If you wish to customize that error message,
using the 'unique' key in Meta.
error_messages['username'] or, if you have a custom form field for 'username', using the the
'unique' key in its
argument.
• The block usertools in the base.html template of
now requires the has_permission context variable to be set. If you have any custom admin views that use this template, update them to pass
as this new variable’s value or simply include
AdminSite.each_context(request)
in the context.
• Internal changes were made to the
widget to allow more customization. The undocumented url_markup_template attribute was removed in favor of template_with_initial.
• For consistency with other major vendors, the en_GB locale now has Monday as the first day of the week.
• Seconds have been removed from any locales that had them in TIME_FORMAT, DATETIME_FORMAT, or
SHORT_DATETIME_FORMAT .
• The default max size of the Oracle test tablespace has increased from 300M (or 200M, before 1.7.2) to 500M.
• reverse() and reverse_lazy() now return Unicode strings instead of byte strings.
• The CacheClass shim has been removed from all cache backends. These aliases were provided for backwards compatibility with Django 1.3. If you are still using them, please update your project to use the real class name found in the
key of the
setting.
• By default,
now always skips the check framework (unless you pass it skip_checks=False
).
• When iterating over lines,
now uses universal newlines . The following are recognized as ending a line: the Unix end-of-line convention '\n', the Windows convention '\r\n', and the old Macintosh convention
'\r'
.
• The Memcached cache backends MemcachedCache and PyLibMCCache will delete a key if set() fails.
This is necessary to ensure the cache_db session store always fetches the most current session data.
• Private APIs override_template_loaders and override_with_test_loader in django.
test.utils
were removed. Override TEMPLATES with override_settings instead.
• Warnings from the MySQL database backend are no longer converted to exceptions when
is True.
•
now has a simplified repr (e.g. <WSGIRequest:
GET '/somepath/'>
). This won’t change the behavior of the
class.
1506 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
• Class-based views that use
will raise an
exception when both the fields and form_class attributes are specified. Previously, fields was silently ignored.
• When following redirects, the test client now raises
if it detects a loop or hits a maximum redirect limit (rather than passing silently).
• Translatable strings set as the default parameter of the field are cast to concrete strings later, so the return type of Field.get_default() is different in some cases. There is no change to default values which are the result of a callable.
• GenericIPAddressField.empty_strings_allowed is now False. Database backends that interpret empty strings as null (only Oracle among the backends that Django includes) will no longer convert null values back to an empty string. This is consistent with other backends.
• When the
attribute is False, translations are now deactivated instead of forcing the
“en-us” locale. In the case your models contained non-English strings and you counted on English translations to be activated in management commands, this will not happen any longer. It might be that new database migrations are generated (once) after migrating to 1.8.
•
django.utils.translation.get_language()
now returns None instead of
when translations are temporarily deactivated.
• When a translation doesn’t exist for a specific literal, the fallback is now taken from the
language (instead of from the untranslated msgid message).
• The name field of
django.contrib.contenttypes.models.ContentType
has been removed by a migration and replaced by a property. That means it’s not possible to query or filter a ContentType by this field any longer.
Be careful if you upgrade to Django 1.8 and skip Django 1.7. If you run manage.py migrate --fake, this migration will be skipped and you’ll see a RuntimeError:
Error creating new content types.
exception because the name column won’t be dropped from the database.
Use manage.py
migrate --fake-initial to fake only the initial migration instead.
• The new
option allows faking initial migrations. In 1.7, initial migrations were always automatically faked if all tables created in an initial migration already existed.
• An app without migrations with a ForeignKey to an app with migrations may now result in a foreign key constraint error when migrating the database or running tests. In Django 1.7, this could fail silently and result in a missing constraint. To resolve the error, add migrations to the app without them.
Features deprecated in 1.8
Selected methods in django.db.models.options.Options
As part of the formalization of the Model._meta API (from the
django.db.models.options.Options
class), a number of methods have been deprecated and will be removed in Django 1.10:
• get_all_field_names()
• get_all_related_objects()
• get_all_related_objects_with_model()
• get_all_related_many_to_many_objects()
• get_all_related_m2m_objects_with_model()
• get_concrete_fields_with_model()
• get_field_by_name()
9.1. Final releases 1507
Django Documentation, Release 2.0.dev20170914110741
• get_fields_with_model()
• get_m2m_with_model()
A
has been provided to assist in converting your code from the old API to the new, official API.
Loading cycle and firstof template tags from future library
Django 1.6 introduced {% load cycle from future %} and {% load firstof from future %} syntax for forward compatibility of the
and
template tags. This syntax is now deprecated and will be removed in Django 1.10. You can simply remove the {% load ... from future %} tags.
django.conf.urls.patterns()
In the olden days of Django, it was encouraged to reference views as strings in urlpatterns: urlpatterns = patterns( '' , url( '^$' , 'myapp.views.myview' ),
) and Django would magically import myapp.views.myview internally and turn the string into a real function reference. In order to reduce repetition when referencing many views from the same module, the patterns() function takes a required initial prefix argument which is prepended to all views-as-strings in that set of urlpatterns: urlpatterns = patterns( 'myapp.views' , url( '^$' , 'myview' ), url( '^other/$' , 'otherview' ),
)
In the modern era, we have updated the tutorial to instead recommend importing your views module and referencing your view functions (or classes) directly. This has a number of advantages, all deriving from the fact that we are using normal Python in place of “Django String Magic”: the errors when you mistype a view name are less obscure, IDEs can help with autocompletion of view names, etc.
So these days, the above use of the prefix arg is much more likely to be written (and is better written) as:
from
myapp
import
views urlpatterns = patterns( '' , url( '^$' , views.myview), url( '^other/$' , views.otherview),
)
Thus patterns() serves little purpose and is a burden when teaching new users (answering the newbie’s question
“why do I need this empty string as the first argument to patterns()?”). For these reasons, we are deprecating it. Updating your code is as simple as ensuring that urlpatterns is a list of
instances. For example:
from
django.conf.urls
import
url
from
myapp
import
views urlpatterns = [ url( '^$' , views.myview), url( '^other/$' , views.otherview),
]
1508 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
Passing a string as view to url()
Related to the previous item, referencing views as strings in the url() function is deprecated. Pass the callable view as described in the previous section instead.
Template-related settings
As a consequence of the multiple template engines refactor, several settings are deprecated in favor of
• ALLOWED_INCLUDE_ROOTS
• TEMPLATE_CONTEXT_PROCESSORS
• TEMPLATE_DEBUG
• TEMPLATE_DIRS
• TEMPLATE_LOADERS
• TEMPLATE_STRING_IF_INVALID
django.core.context_processors
Built-in template context processors have been moved to django.template.context_processors.
django.test.SimpleTestCase.urls
The attribute SimpleTestCase.urls for specifying URLconf configuration in tests has been deprecated and will be removed in Django 1.10. Use
@override_settings(ROOT_URLCONF=...)
instead.
prefix argument to i18n_patterns()
Related to the previous item, the prefix argument to
django.conf.urls.i18n.i18n_patterns()
has been deprecated. Simply pass a list of
instances instead.
Using an incorrect count of unpacked values in the for template tag
Using an incorrect count of unpacked values in
tag will raise an exception rather than fail silently in Django 1.10.
Passing a dotted path to reverse() and url
Reversing URLs by Python path is an expensive operation as it causes the path being reversed to be imported. This behavior has also resulted in a security issue . Use
for reversing instead.
If you are using
, add the name argument to the url that references
contrib.sitemaps.views.sitemap()
from
django.contrib.sitemaps.views
import
sitemap url( r'^sitemap\.xml$' , sitemap, { 'sitemaps' : sitemaps}, name= 'django.contrib.sitemaps.views.sitemap' )
9.1. Final releases 1509
Django Documentation, Release 2.0.dev20170914110741
to ensure compatibility when reversing by Python path is removed in Django 1.10.
Similarly for GIS sitemaps, add name='django.contrib.gis.sitemaps.views.kml' or name='django.contrib.gis.sitemaps.views.kmz' .
If you are using a Python path for the
or
setting, use the name of the url() instead.
Aggregate methods and modules
The django.db.models.sql.aggregates
and django.contrib.gis.db.models.sql.
aggregates modules (both private API), have been deprecated as django.db.models.aggregates
and django.contrib.gis.db.models.aggregates are now also responsible for SQL generation. The old modules will be removed in Django 1.10.
If you were using the old modules, see
for instructions on rewriting custom aggregates using the new stable API.
The following methods and properties of django.db.models.sql.query.Query have also been deprecated and the backwards compatibility shims will be removed in Django 1.10:
• Query.aggregates, replaced by annotations.
• Query.aggregate_select, replaced by annotation_select.
• Query.add_aggregate(), replaced by add_annotation().
• Query.set_aggregate_mask(), replaced by set_annotation_mask().
• Query.append_aggregate_mask(), replaced by append_annotation_mask().
Extending management command arguments through Command.option_list
Management commands now use argparse instead of optparse to parse command-line arguments passed to commands. This also means that the way to add custom arguments to commands has changed: instead of extending the option_list class list, you should now override the
method and add arguments through argparse.add_argument() . See
for more details.
django.core.management.NoArgsCommand
The class NoArgsCommand is now deprecated and will be removed in Django 1.10. Use
instead, which takes no arguments by default.
Listing all migrations in a project
The --list option of the
management command is deprecated and will be removed in Django 1.10. Use
instead.
cache_choices option of ModelChoiceField and ModelMultipleChoiceField
and
took an undocumented, untested option cache_choices
. This cached querysets between multiple renderings of the same Form object. This option is subject to an accelerated deprecation and will be removed in Django 1.9.
1510 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
django.template.resolve_variable()
The function has been informally marked as “Deprecated” for some time. Replace resolve_variable(path, context) with django.template.Variable(path).resolve(context).
django.contrib.webdesign
It provided the
template tag which is now included in the built-in tags. Simply remove 'django.contrib.
webdesign' from
and {% load webdesign %} from your templates.
error_message argument to django.forms.RegexField
It provided backwards compatibility for pre-1.0 code, but its functionality is redundant.
Use Field.
error_messages['invalid'] instead.
Old unordered_list syntax
An older (pre-1.0), more restrictive and verbose input format for the
template filter has been deprecated:
[ 'States' , [[ 'Kansas' , [[ 'Lawrence' , []], [ 'Topeka' , []]]], [ 'Illinois' , []]]]
Using the new syntax, this becomes:
[ 'States' , [ 'Kansas' , [ 'Lawrence' , 'Topeka' ], 'Illinois' ]]
django.forms.Field._has_changed()
Rename this method to
by removing the leading underscore. The old name will still work until
Django 1.10.
django.utils.html.remove_tags() and removetags template filter
django.utils.html.remove_tags() as well as the template filter removetags have been deprecated as they cannot guarantee safe output. Their existence is likely to lead to their use in security-sensitive contexts where they are not actually safe.
The unused and undocumented django.utils.html.strip_entities() function has also been deprecated.
is_admin_site argument to django.contrib.auth.views.password_reset()
It’s a legacy option that should no longer be necessary.
9.1. Final releases 1511
Django Documentation, Release 2.0.dev20170914110741
SubfieldBase
django.db.models.fields.subclassing.SubfieldBase
has been deprecated and will be removed in
Django 1.10. Historically, it was used to handle fields where type conversion was needed when loading from the database, but it was not used in .values() calls or in aggregates. It has been replaced with
The new approach doesn’t call the
method on assignment as was the case with SubfieldBase. If you need that behavior, reimplement the Creator class from Django’s source code in your project.
django.utils.checksums
The django.utils.checksums module has been deprecated and will be removed in Django 1.10. The functionality it provided (validating checksum using the Luhn algorithm) was undocumented and not used in Django. The module has been moved to the django-localflavor package (version 1.1+).
InlineAdminForm.original_content_type_id
The original_content_type_id attribute on InlineAdminForm has been deprecated and will be removed in Django 1.10. Historically, it was used to construct the “view on site” URL. This URL is now accessible using the absolute_url attribute of the form.
django.views.generic.edit.FormMixin.get_form()
’s form_class argument
FormMixin subclasses that override the get_form() method should make sure to provide a default value for the form_class argument since it’s now optional.
Rendering templates loaded by get_template() with a Context
The return type of
has changed in Django 1.8: instead of a
it returns a Template instance whose exact type depends on which backend loaded it.
Both classes provide a render() method, however, the former takes a
as an argument while the latter expects a dict
. This change is enforced through a deprecation path for Django templates.
All this also applies to
Template and Context classes in template responses
Some methods of
and
accepted
and
objects as arguments.
They should now receive dict and backend-dependent template objects respectively.
This also applies to the return types if you have subclassed either template response class.
Check the
template response API documentation
for details.
current_app argument of template-related APIs
The following functions and classes will no longer accept a current_app parameter to set an URL namespace in
Django 1.10:
1512 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
• django.shortcuts.render()
• django.template.Context()
• django.template.RequestContext()
• django.template.response.TemplateResponse()
Set request.current_app instead, where request is the first argument to these functions or classes. If you’re using a plain Context, use a RequestContext instead.
dictionary and context_instance arguments of rendering functions
The following functions will no longer accept the dictionary and context_instance parameters in Django
1.10:
• django.shortcuts.render()
• django.shortcuts.render_to_response()
• django.template.loader.render_to_string()
Use the context parameter instead. When dictionary is passed as a positional argument, which is the most common idiom, no changes are needed.
If you’re passing a
in context_instance, pass a dict in the context parameter instead. If you’re passing a
, pass the request separately in the request parameter.
dirs argument of template-finding functions
The following functions will no longer accept a dirs parameter to override TEMPLATE_DIRS in Django 1.10:
•
django.template.loader.get_template()
•
django.template.loader.select_template()
•
• django.shortcuts.render_to_response()
The parameter didn’t work consistently across different template loaders and didn’t work for included templates.
django.template.loader.BaseLoader
django.template.loader.BaseLoader
was renamed to django.template.loaders.base.
Loader
.
If you’ve written a custom template loader that inherits BaseLoader, you must inherit Loader instead.
django.test.utils.TestTemplateLoader
Private API django.test.utils.TestTemplateLoader is deprecated in favor of django.template.
loaders.locmem.Loader
and will be removed in Django 1.9.
9.1. Final releases 1513
Django Documentation, Release 2.0.dev20170914110741
Support for the max_length argument on custom Storage classes
Storage subclasses should add max_length=None as a parameter to
and/or
if they override either method. Support for storages that do not accept this argument will be removed in
Django 1.10.
qn replaced by compiler
In previous Django versions, various internal ORM methods (mostly as_sql methods) accepted a qn (for “quote name”) argument, which was a reference to a function that quoted identifiers for sending to the database. In Django
1.8, that argument has been renamed to compiler and is now a full SQLCompiler instance. For backwardscompatibility, calling a SQLCompiler instance performs the same name-quoting that the qn function used to.
However, this backwards-compatibility shim is immediately deprecated: you should rename your qn arguments to compiler
, and call compiler.quote_name_unless_alias(...) where you previously called qn(...).
Default value of RedirectView.permanent
The default value of the
attribute will change from True to False in Django 1.9.
Using AuthenticationMiddleware without SessionAuthenticationMiddleware
django.contrib.auth.middleware.SessionAuthenticationMiddleware
was added in Django
1.7. In Django 1.7.2, its functionality was moved to auth.get_user() and, for backwards compatibility, enabled only if 'django.contrib.auth.middleware.SessionAuthenticationMiddleware' appears in MIDDLEWARE_CLASSES.
In or
Django not
1.10, session verification
SessionAuthenticationMiddleware will will
SessionAuthenticationMiddleware have no be is enabled enabled significance).
regardless
(at of which whether point
You can add it to your
MIDDLEWARE_CLASSES sometime before then to opt-in. Please read the
first.
django.contrib.sitemaps.FlatPageSitemap
django.contrib.sitemaps.FlatPageSitemap
has moved to django.contrib.flatpages.
sitemaps.FlatPageSitemap
. The old import location is deprecated and will be removed in Django 1.9.
Model Field.related
Private attribute django.db.models.Field.related is deprecated in favor of Field.rel. The latter is an instance of django.db.models.fields.related.ForeignObjectRel which replaces django.db.
models.related.RelatedObject
. The django.db.models.related module has been removed and the Field.related attribute will be removed in Django 1.10.
ssi template tag
The ssi template tag allows files to be included in a template by absolute path. This is of limited use in most deployment situations, and the
tag often makes more sense. This tag is now deprecated and will be removed in Django 1.10.
1514 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
= as comparison operator in if template tag
Using a single equals sign with the {% if %} template tag for equality testing was undocumented and untested. It’s now deprecated in favor of ==.
%(<foo>)s syntax in ModelFormMixin.success_url
The legacy %(<foo>)s syntax in
is deprecated and will be removed in
Django 1.10.
GeoQuerySet aggregate methods
The collect(), extent(), extent3d(), make_line(), and unionagg() aggregate methods are deprecated and should be replaced by their function-based aggregate equivalents (Collect, Extent, Extent3D,
MakeLine , and Union).
Signature of the allow_migrate router method
The signature of the
method of database routers has changed from allow_migrate(db, model) to allow_migrate(db, app_label, model_name=None, **hints).
When model_name is set, the value that was previously given through the model positional argument may now be found inside the hints dictionary under the key 'model'.
After switching to the new signature the router will also be called by the
and
operations.
Features removed in 1.8
These features have reached the end of their deprecation cycle and are removed in Django 1.8. See
for details, including how to remove usage of these features.
• django.contrib.comments is removed.
• The following transaction management APIs are removed:
– TransactionMiddleware
– the decorators and context managers autocommit
, commit_on_success
, and commit_manually
, defined in django.db.transaction
– the functions commit_unless_managed and rollback_unless_managed, also defined in django.db.transaction
– the TRANSACTIONS_MANAGED setting
• The
and
template tags auto-escape their arguments.
• The SEND_BROKEN_LINK_EMAILS setting is removed.
• django.middleware.doc.XViewMiddleware is removed.
• The Model._meta.module_name alias is removed.
• The backward compatible shims introduced to rename get_query_set and similar queryset methods are removed.
This affects the following classes:
BaseModelAdmin
,
ChangeList
,
9.1. Final releases 1515
Django Documentation, Release 2.0.dev20170914110741
BaseCommentNode
, GenericForeignKey, Manager, SingleRelatedObjectDescriptor and
ReverseSingleRelatedObjectDescriptor
.
• The backward compatible shims introduced to rename the attributes ChangeList.root_query_set and
ChangeList.query_set
are removed.
• django.views.defaults.shortcut and django.conf.urls.shortcut are removed.
• Support for the Python Imaging Library (PIL) module is removed.
• The following private APIs are removed:
– django.db.backend
– django.db.close_connection()
– django.db.backends.creation.BaseDatabaseCreation.set_autocommit()
– django.db.transaction.is_managed()
– django.db.transaction.managed()
• django.forms.widgets.RadioInput is removed.
• The module django.test.simple
DjangoTestSuiteRunner are removed.
• The module django.test._doctest is removed.
and the class django.test.simple.
• The CACHE_MIDDLEWARE_ANONYMOUS_ONLY setting is removed.
django.middleware.cache.CacheMiddleware
and
This change affects both django.middleware.cache.
UpdateCacheMiddleware despite the lack of a deprecation warning in the latter class.
• Usage of the hard-coded Hold down “Control”, or “Command” on a Mac, to select more than one. string to override or append to user-provided help_text in forms for ManyToMany model fields is not performed by
Django anymore either at the model or forms layer.
• The Model._meta.get_(add|change|delete)_permission methods are removed.
• The session key django_language is no longer read for backwards compatibility.
• Geographic Sitemaps are removed (django.contrib.gis.sitemaps.views.index and django.
contrib.gis.sitemaps.views.sitemap
).
• django.utils.html.fix_ampersands, the fix_ampersands template filter, and django.
utils.html.clean_html
are removed.
1.7 release
Django 1.7.11 release notes
November 24, 2015
Django 1.7.11 fixes a security issue and a data loss bug in 1.7.10.
Fixed settings leak possibility in date template filter
If an application allows users to specify an unvalidated format for dates and passes this format to the
filter, e.g. {{ last_updated|date:user_date_format }}, then a malicious user could obtain any secret in the application’s settings by specifying a settings key instead of a date format. e.g. "SECRET_KEY" instead of "j/m/
Y"
.
1516 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
To remedy this, the underlying function used by the date template filter, django.utils.formats.
get_format()
, now only allows accessing the date/time formatting settings.
Bugfixes
• Fixed a data loss possibility with
if to_attr is set to a ManyToManyField ( #25693 ).
Django 1.7.10 release notes
August 18, 2015
Django 1.7.10 fixes a security issue in 1.7.9.
Denial-of-service possibility in logout() view by filling session store
Previously, a session could be created when anonymously accessing the
view (provided it wasn’t decorated with
as done in the admin). This could allow an attacker to easily create many new session records by sending repeated requests, potentially filling up the session store or causing other users’ session records to be evicted.
The
has been modified to no longer create empty session records, including when
is active.
Additionally, the contrib.sessions.backends.base.SessionBase.flush() and cache_db.
SessionStore.flush() methods have been modified to avoid creating a new empty session. Maintainers of third-party session backends should check if the same vulnerability is present in their backend and correct it if so.
Django 1.7.9 release notes
July 8, 2015
Django 1.7.9 fixes several security issues and bugs in 1.7.8.
Denial-of-service possibility by filling session store
In previous versions of Django, the session backends created a new empty record in the session storage anytime request.session
was accessed and there was a session key provided in the request cookies that didn’t already have a session record. This could allow an attacker to easily create many new session records simply by sending repeated requests with unknown session keys, potentially filling up the session store or causing other users’ session records to be evicted.
The built-in session backends now create a session record only if the session is actually modified; empty session records are not created. Thus this potential DoS is now only possible if the site chooses to expose a session-modifying view to anonymous users.
As each built-in session backend was fixed separately (rather than a fix in the core sessions framework), maintainers of third-party session backends should check whether the same vulnerability is present in their backend and correct it if so.
9.1. Final releases 1517
Django Documentation, Release 2.0.dev20170914110741
Header injection possibility since validators accept newlines in input
the usage of $ instead of \Z in the regular expressions). If you use values with newlines in HTTP response or email headers, you can suffer from header injection attacks. Django itself isn’t vulnerable because
and the mail sending utilities in
prohibit newlines in HTTP and SMTP headers, respectively. While the validators have been fixed in Django, if you’re creating HTTP responses or email messages in other ways, it’s a good idea to ensure that those methods prohibit newlines as well. You might also want to validate that any existing data in your application doesn’t contain unexpected newlines.
are also affected, however, as of
Django 1.6 the GenericIPAddresseField, IPAddressField, SlugField, and URLField form fields which use these validators all strip the input, so the possibility of newlines entering your data only exists if you are using these validators outside of the form fields.
The undocumented, internally unused validate_integer() function is now stricter as it validates using a regular expression instead of simply casting the value using int() and checking if an exception was raised.
Bugfixes
• Prevented the loss of null/not null column properties during field renaming of MySQL databases
( #24817 ).
• Fixed SimpleTestCase.assertRaisesMessage() on Python 2.7.10 ( #24903 ).
Django 1.7.8 release notes
May 1, 2015
Django 1.7.8 fixes:
• Database introspection with SQLite 3.8.9 (released April 8, 2015) ( #24637 ).
• A database table name quoting regression in 1.7.2 ( #24605 ).
• The loss of null/not null column properties during field alteration of MySQL databases ( #24595 ).
Django 1.7.7 release notes
March 18, 2015
Django 1.7.7 fixes several bugs and security issues in 1.7.6.
Denial-of-service possibility with strip_tags()
Last year
was changed to work iteratively. The problem is that the size of the input it’s processing can increase on each iteration which results in an infinite loop in strip_tags(). This issue only affects versions of Python that haven’t received a bugfix in HTMLParser ; namely Python < 2.7.7 and 3.3.5. Some operating system vendors have also backported the fix for the Python bug into their packages of earlier versions.
To remedy this issue, strip_tags() will now return the original input if it detects the length of the string it’s processing increases. Remember that absolutely NO guarantee is provided about the results of strip_tags() being HTML safe. So NEVER mark safe the result of a strip_tags() call without escaping it first, for example with
1518 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
Mitigated possible XSS attack via user-supplied redirect URLs
Django relies on user input in some cases (e.g.
django.contrib.auth.views.login()
and
to redirect the user to an “on success” URL. The security checks for these redirects (namely django.
utils.http.is_safe_url() ) accepted URLs with leading control characters and so considered URLs like
\x08javascript:...
safe. This issue doesn’t affect Django currently, since we only put this URL into the
Location response header and browsers seem to ignore JavaScript there. Browsers we tested also treat URLs prefixed with control characters such as %08//example.com as relative paths so redirection to an unsafe target isn’t a problem either.
However, if a developer relies on is_safe_url() to provide safe redirect targets and puts such a URL into a link, they could suffer from an XSS attack as some browsers such as Google Chrome ignore control characters at the start of a URL in an anchor href.
Bugfixes
• Fixed renaming of classes in migrations where renaming a subclass would cause incorrect state to be recorded for objects that referenced the superclass ( #24354 ).
• Stopped writing migration files in dry run mode when merging migration conflicts. When makemigrations
--merge is called with verbosity=3 the migration file is written to stdout ( #24427 ).
Django 1.7.6 release notes
March 9, 2015
Django 1.7.6 fixes a security issue and several bugs in 1.7.5.
Mitigated an XSS attack via properties in ModelAdmin.readonly_fields
The
attribute in the Django admin allows displaying model fields and model attributes. While the former were correctly escaped, the latter were not. Thus untrusted content could be injected into the admin, presenting an exploitation vector for XSS attacks.
In this vulnerability, every model attribute used in readonly_fields that is not an actual model field (e.g. a property
) will fail to be escaped even if that attribute is not marked as safe. In this release, autoescaping is now correctly applied.
Bugfixes
• Fixed crash when coercing ManyRelatedManager to a string ( #24352 ).
• Fixed a bug that prevented migrations from adding a foreign key constraint when converting an existing field to a foreign key ( #24447 ).
Django 1.7.5 release notes
February 25, 2015
Django 1.7.5 fixes several bugs in 1.7.4.
9.1. Final releases 1519
Django Documentation, Release 2.0.dev20170914110741
Bugfixes
• Reverted a fix that prevented a migration crash when unapplying contrib.contenttypes’s or contrib.
auth ’s first migration ( #24075 ) due to severe impact on the test performance ( #24251 ) and problems in multidatabase setups ( #24298 ).
• Fixed a regression that prevented custom fields inheriting from ManyToManyField from being recognized in migrations ( #24236 ).
• Fixed crash in contrib.sites migrations when a default database isn’t used ( #24332 ).
• Added the ability to set the isolation level on PostgreSQL with psycopg2 ≥ 2.4.2 ( #24318 ). It was advertised as a new feature in Django 1.6 but it didn’t work in practice.
• Formats for the Azerbaijani locale (az) have been added.
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
( #24075 ).
• Made the migration’s RenameModel operation rename ManyToManyField tables ( #24135 ).
• Fixed a migration crash on MySQL when migrating from a OneToOneField to a ForeignKey ( #24163 ).
• Prevented the static.serve view from producing ResourceWarnings in certain circumstances (security fix regression, #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. ( #24104 ).
Django 1.7.3 release notes
January 13, 2015
Django 1.7.3 fixes several security issues and bugs in 1.7.2.
WSGI header spoofing via underscore/dash conflation
When HTTP headers are placed into the WSGI environ, they are normalized by converting to uppercase, converting all dashes to underscores, and prepending HTTP_. For instance, a header X-Auth-User would become
HTTP_X_AUTH_USER in the WSGI environ (and thus also in Django’s request.META dictionary).
Unfortunately, this means that the WSGI environ cannot distinguish between headers containing dashes and headers containing underscores: X-Auth-User and X-Auth_User both become HTTP_X_AUTH_USER. This means that if a header is used in a security-sensitive way (for instance, passing authentication information along from a front-end proxy), even if the proxy carefully strips any incoming value for X-Auth-User, an attacker may be able to provide an X-Auth_User header (with underscore) and bypass this protection.
1520 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
In order to prevent such attacks, both Nginx and Apache 2.4+ strip all headers containing underscores from incoming requests by default. Django’s built-in development server now does the same. Django’s development server is not recommended for production use, but matching the behavior of common production servers reduces the surface area for behavior changes during deployment.
Mitigated possible XSS attack via user-supplied redirect URLs
Django relies on user input in some cases (e.g.
django.contrib.auth.views.login()
and
redirect the user to an “on success” URL. The security checks for these redirects (namely django.utils.
http.is_safe_url()
) didn’t strip leading whitespace on the tested URL and as such considered URLs like
\njavascript:...
safe. If a developer relied on is_safe_url() to provide safe redirect targets and put such a URL into a link, they could suffer from a XSS attack. This bug doesn’t affect Django currently, since we only put this URL into the Location response header and browsers seem to ignore JavaScript there.
Denial-of-service attack against django.views.static.serve
In older versions of Django, the
view read the files it served one line at a time. Therefore, a big file with no newlines would result in memory usage equal to the size of that file. An attacker could exploit this and launch a denial-of-service attack by simultaneously requesting many large files. This view now reads the file in chunks to prevent large memory usage.
Note, however, that this view has always carried a warning that it is not hardened for production use and should be used only as a development aid. Now may be a good time to audit your project and serve your files in production using a real front-end web server if you are not doing so.
Database denial-of-service with ModelMultipleChoiceField
Given a form that uses ModelMultipleChoiceField and show_hidden_initial=True (not a documented API), it was possible for a user to cause an unreasonable number of SQL queries by submitting duplicate values for the field’s data. The validation logic in ModelMultipleChoiceField now deduplicates submitted values to address this issue.
Bugfixes
• The default iteration count for the PBKDF2 password hasher has been increased by 25%. This part of the normal major release process was inadvertently omitted in 1.7. This backwards compatible change will not affect users who have subclassed django.contrib.auth.hashers.PBKDF2PasswordHasher to change the default value.
• Fixed a crash in the CSRF middleware when handling non-ASCII referer header ( #23815 ).
• Fixed a crash in the django.contrib.auth.redirect_to_login view when passing a reverse_lazy() result on Python 3 ( #24097 ).
• Added correct formats for Greek (el) ( #23967 ).
• Fixed a migration crash when unapplying a migration where multiple operations interact with the same model
( #24110 ).
9.1. Final releases 1521
Django Documentation, Release 2.0.dev20170914110741
Django 1.7.2 release notes
January 2, 2015
Django 1.7.2 fixes several bugs in 1.7.1.
Additionally, Django’s vendored version of six, django.utils.six, has been upgraded to the latest release
(1.9.0).
Bugfixes
• Fixed migration’s renaming of auto-created many-to-many tables when changing
( #23630 ).
• Fixed a migration crash when adding an explicit id field to a model on SQLite ( #23702 ).
• Added a warning for duplicate models when a module is reloaded. Previously a RuntimeError was raised every time two models clashed in the app registry. ( #23621 ).
• Prevented
from loading initial data for migrated apps ( #23699 ).
• Fixed a
regression in 1.7.1 when
has the default None value ( #23717 ).
• Added GeoDjango compatibility with mysqlclient database driver.
• Fixed MySQL 5.6+ crash with GeometryFields in migrations ( #23719 ).
• Fixed a migration crash when removing a field that is referenced in AlterIndexTogether or
AlterUniqueTogether
( #23614 ).
• Updated the first day of the week in the Ukrainian locale to Monday.
• Added support for transactional spatial metadata initialization on SpatiaLite 4.1+ ( #23152 ).
• Fixed a migration crash that prevented changing a nullable field with a default to non-nullable with the same default ( #23738 ).
• Fixed a migration crash when adding GeometryFields with blank=True on PostGIS ( #23731 ).
• Allowed usage of DateTimeField() as Transform.output_field ( #23420 ).
• Fixed a migration serializing bug involving float("nan") and float("inf") ( #23770 ).
• Fixed a regression where custom form fields having a queryset attribute but no limit_choices_to could not be used in a
( #23795 ).
• Fixed a custom field type validation error with MySQL backend when db_type returned None ( #23761 ).
• Fixed a migration crash when a field is renamed that is part of an index_together ( #23859 ).
• Fixed
to respect the --no-optimize parameter ( #23799 ).
• Made
reversible ( #22248 )
• Avoided unnecessary rollbacks of migrations from other apps when migrating backwards ( #23410 ).
• Fixed a rare query error when using deeply nested subqueries ( #23605 ).
• Fixed a crash in migrations when deleting a field that is part of a index/unique_together constraint
( #23794 ).
• Fixed django.core.files.File.__repr__() when the file’s name contains Unicode characters
( #23888 ).
• Added missing context to the admin’s delete_selected view that prevented custom site header, etc. from appearing ( #23898 ).
1522 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
• Fixed a regression with dynamically generated inlines and allowed field references in the admin ( #23754 ).
• Fixed an infinite loop bug for certain cyclic migration dependencies, and made the error message for cyclic dependencies much more helpful.
• Added missing index_together handling for SQLite ( #23880 ).
• Fixed a crash when RunSQL SQL content was collected by the schema editor, typically when using sqlmigrate
( #23909 ).
• Fixed a regression in contrib.admin add/change views which caused some ModelAdmin methods to receive the incorrect obj value ( #23934 ).
• Fixed runserver crash when socket error message contained Unicode characters ( #23946 ).
• Fixed serialization of type when adding a deconstruct() method ( #23950 ).
• Prevented the django.contrib.auth.middleware.SessionAuthenticationMiddleware
from setting a "Vary:
Cookie" header on all responses ( #23939 ).
• Fixed a crash when adding blank=True to TextField() on MySQL ( #23920 ).
• Fixed index creation by the migration infrastructure, particularly when dealing with PostgreSQL specific
{text|varchar}_pattern_ops indexes ( #23954 ).
• Fixed bug in makemigrations that created broken migration files when dealing with multiple table inheritance and inheriting from more than one model ( #23956 ).
• Fixed a crash when a MultiValueField has invalid data ( #23674 ).
• Fixed a crash in the admin when using “Save as new” and also deleting a related inline ( #23857 ).
• Always converted related_name to text (unicode), since that is required on Python 3 for interpolation.
Removed conversion of related_name to text in migration deconstruction ( #23455 and #23982 ).
• Enlarged the sizes of tablespaces which are created by default for testing on Oracle (the main tablespace was increased from 200M to 300M and the temporary tablespace from 100M to 150M). This was required to accommodate growth in Django’s own test suite ( #23969 ).
• Fixed timesince filter translations in Korean ( #23989 ).
• Fixed the SQLite SchemaEditor to properly add defaults in the absence of a user specified default. For example, a CharField with blank=True didn’t set existing rows to an empty string which resulted in a crash when adding the NOT NULL constraint ( #23987 ).
• makemigrations no longer prompts for a default value when adding TextField() or CharField() without a default ( #23405 ).
• Fixed a migration crash when adding order_with_respect_to to a table with existing rows ( #23983 ).
• Restored the pre_migrate signal if all apps have migrations ( #23975 ).
• Made admin system checks run for custom AdminSites ( #23497 ).
• Ensured the app registry is fully populated when unpickling models. When an external script (like a queueing infrastructure) reloads pickled models, it could crash with an AppRegistryNotReady exception ( #24007 ).
• Added quoting to field indexes in the SQL generated by migrations to prevent a crash when the index name requires it ( ##24015 ).
• Added datetime.time support to migrations questioner ( #23998 ).
• Fixed admindocs crash on apps installed as eggs ( #23525 ).
9.1. Final releases 1523
Django Documentation, Release 2.0.dev20170914110741
• Changed migrations autodetector to generate an AlterModelOptions operation instead of DeleteModel and CreateModel operations when changing Meta.managed. This prevents data loss when changing managed from False to True and vice versa ( #24037 ).
• Enabled the sqlsequencereset command on apps with migrations ( #24054 ).
• Added tablespace SQL to apps with migrations ( #24051 ).
• Corrected contrib.sites default site creation in a multiple database setup ( #24000 ).
• Restored support for objects that aren’t str or bytes in django.utils.safestring.
mark_for_escaping() on Python 3.
• Supported strings escaped by third-party libraries with the __html__ convention in the template engine
( #23831 ).
• Prevented extraneous DROP DEFAULT SQL in migrations ( #23581 ).
• Restored the ability to use more than five levels of subqueries ( #23758 ).
• Fixed crash when ValidationError is initialized with a ValidationError that is initialized with a dictionary ( #24008 ).
• Prevented a crash on apps without migrations when running migrate --list ( #23366 ).
Django 1.7.1 release notes
October 22, 2014
Django 1.7.1 fixes several bugs in 1.7.
Bugfixes
• Allowed related many-to-many fields to be referenced in the admin ( #23604 ).
• Added a more helpful error message if you try to migrate an app without first creating the contenttypes table ( #22411 ).
• Modified migrations dependency algorithm to avoid possible infinite recursion.
• Fixed a UnicodeDecodeError when the flush error message contained Unicode characters ( #22882 ).
• Reinstated missing CHECK SQL clauses which were omitted on some backends when not using migrations
( #23416 ).
• Fixed serialization of type objects in migrations ( #22951 ).
• Allowed inline and hidden references to admin fields ( #23431 ).
• The @deconstructible decorator now fails with a ValueError if the decorated object cannot automatically be imported ( #23418 ).
• Fixed a typo in an inlineformset_factory() error message that caused a crash ( #23451 ).
• Restored the ability to use
with the 'auth.User' model ( #11775 ). As a side effect, the setting now adds a get_absolute_url() method to any model that appears in
ABSOLUTE_URL_OVERRIDES but doesn’t define get_absolute_url().
• Avoided masking some ImportError exceptions during application loading ( #22920 ).
• Empty index_together or unique_together model options no longer results in infinite migrations
( #23452 ).
1524 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
• Fixed crash in contrib.sitemaps if lastmod returned a date rather than a datetime ( #23403 ).
• Allowed migrations to work with app_labels that have the same last part (e.g. django.contrib.auth
and vendor.auth) ( #23483 ).
• Restored the ability to deepcopy F objects ( #23492 ).
• Formats for Welsh (cy) and several Chinese locales (zh_CN, zh_Hans, zh_Hant and zh_TW) have been added. Formats for Macedonian have been fixed (trailing dot removed, #23532 ).
• Added quoting of constraint names in the SQL generated by migrations to prevent crash with uppercase characters in the name ( #23065 ).
• Fixed renaming of models with a self-referential many-to-many field (ManyToManyField('self'))
( #23503 ).
• Added the
( #23539 ).
and
hooks to
• Made migrations.RunSQL no longer require percent sign escaping. This is now consistent with cursor.
execute() ( #23426 ).
• Made the
entry in the
dictionary usable ( #23421 ).
• Fixed bug in migrations that prevented foreign key constraints to unmanaged models with a custom primary key
( #23415 ).
• Added SchemaEditor for MySQL GIS backend so that spatial indexes will be created for apps with migrations ( #23538 ).
• Added SchemaEditor for Oracle GIS backend so that spatial metadata and indexes will be created for apps with migrations ( #23537 ).
• Coerced the related_name model field option to unicode during migration generation to generate migrations that work with both Python 2 and 3 ( #23455 ).
• Fixed MigrationWriter to handle builtin types without imports ( #23560 ).
• Fixed deepcopy on ErrorList ( #23594 ).
• Made the
view to browse view details check if the view specified in the URL exists in the URLconf. Previously it was possible to import arbitrary packages from the Python path. This was not considered a security issue because admindocs is only accessible to staff users ( #23601 ).
• Fixed UnicodeDecodeError crash in AdminEmailHandler with non-ASCII characters in the request
( #23593 ).
• Fixed missing get_or_create and update_or_create on related managers causing
IntegrityError
( #23611 ).
• Made
return the proper type (byte string) on Python 3 ( #23333 ).
•
can now serialize timezone-aware values ( #23365 ).
• Added a prompt to the migrations questioner when removing the null constraint from a field to prevent an
IntegrityError on existing NULL rows ( #23609 ).
• Fixed generic relations in ModelAdmin.list_filter ( #23616 ).
• Restored RFC compliance for the SMTP backend on Python 3 ( #23063 ).
• Fixed a crash while parsing cookies containing invalid content ( #23638 ).
• The system check framework now raises error models.E020 when the class method Model.check() is unreachable ( #23615 ).
9.1. Final releases 1525
Django Documentation, Release 2.0.dev20170914110741
• Made the Oracle test database creation drop the test user in the event of an unclean exit of a previous test run
( #23649 ).
• Fixed
to detect changes to
( #23629 ).
• Fixed a regression when feeding the Django test client with an empty data string ( #21740 ).
• Fixed a regression in
where static files were unexpectedly ignored ( #23583 ).
Django 1.7 release notes
September 2, 2014
Welcome to Django 1.7!
These release notes cover the
new features , as well as some
backwards incompatible changes
you’ll want to be aware of when upgrading from Django 1.6 or older versions. We’ve
begun the deprecation process for some features , and
some features have reached the end of their deprecation process and
Python compatibility
Django 1.7 requires Python 2.7, 3.2, 3.3, or 3.4. We highly recommend and only officially support the latest release of each series.
The Django 1.6 series is the last to support Python 2.6. Django 1.7 is the first release to support Python 3.4.
This change should affect only a small number of Django users, as most operating-system vendors today are shipping
Python 2.7 or newer as their default version. If you’re still using Python 2.6, however, you’ll need to stick to Django
1.6 until you can upgrade your Python version. Per
our support policy , Django 1.6 will continue to receive security
support until the release of Django 1.8.
What’s new in Django 1.7
Schema migrations
Django now has built-in support for schema migrations. It allows models to be updated, changed, and deleted by creating migration files that represent the model changes and which can be run on any development, staging or production database.
Migrations are covered in
their own documentation , but a few of the key features are:
• syncdb has been deprecated and replaced by migrate. Don’t worry - calls to syncdb will still work as before.
• A new makemigrations command provides an easy way to autodetect changes to your models and make migrations for them.
django.db.models.signals.pre_syncdb
and django.db.models.signals.post_syncdb
have been deprecated, to be replaced by
and
respectively. These new signals have slightly different arguments. Check the documentation for details.
• The allow_syncdb method on database routers is now called allow_migrate, but still performs the same function. Routers with allow_syncdb methods will still work, but that method name is deprecated and you should change it as soon as possible (nothing more than renaming is required).
• initial_data fixtures are no longer loaded for apps with migrations; if you want to load initial data for an app, we suggest you create a migration for your application and define a
or
operation in the operations section of the migration.
1526 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
• Test rollback behavior is different for apps with migrations; in particular, Django will no longer emulate rollbacks on non-transactional databases or inside TransactionTestCase
unless specifically requested .
• It is not advised to have apps without migrations depend on (have a
or
to) apps with migrations.
App-loading refactor
Historically, Django applications were tightly linked to models. A singleton known as the “app cache” dealt with both installed applications and models. The models module was used as an identifier for applications in many APIs.
As the concept of
matured, this code showed some shortcomings. It has been refactored into an
“app registry” where models modules no longer have a central role and where it’s possible to attach configuration data to applications.
Improvements thus far include:
• Applications can run code at startup, before Django does anything else, with the
method of their configuration.
• Application labels are assigned correctly to models even when they’re defined outside of models.py. You don’t have to set
explicitly any more.
• It is possible to omit models.py entirely if an application doesn’t have any models.
• Applications can be relabeled with the
attribute of application configurations, to work around label conflicts.
• The name of applications can be customized in the admin with the
of application configurations.
• The admin automatically calls
when Django starts. You can consequently remove this line from your URLconf.
• Django imports all application configurations and models as soon as it starts, through a deterministic and straightforward process. This should make it easier to diagnose import issues such as import loops.
New method on Field subclasses
To help power both schema migrations and to enable easier addition of composite keys in future releases of Django, the
API now has a new required method: deconstruct().
This method takes no arguments, and returns a tuple of four items:
• name: The field’s attribute name on its parent model, or None if it is not part of a model
• path: A dotted, Python path to the class of this field, including the class name.
• args: Positional arguments, as a list
• kwargs: Keyword arguments, as a dict
These four values allow any field to be serialized into a file, as well as allowing the field to be copied safely, both essential parts of these new features.
This change should not affect you unless you write custom Field subclasses; if you do, you may need to reimplement the deconstruct() method if your subclass changes the method signature of __init__ in any way. If your field just inherits from a built-in Django field and doesn’t override __init__, no changes are necessary.
9.1. Final releases 1527
Django Documentation, Release 2.0.dev20170914110741
If you do need to override deconstruct(), a good place to start is the built-in Django fields (django/db/ models/fields/__init__.py
) as several fields, including DecimalField and DateField, override it and show how to call the method on the superclass and simply add or remove extra arguments.
This also means that all arguments to fields must themselves be serializable; to see what we consider serializable, and to find out how to make your own classes serializable, read the
migration serialization documentation .
Calling custom QuerySet methods from the Manager
Historically, the recommended way to make reusable model queries was to create methods on a custom Manager class. The problem with this approach was that after the first method call, you’d get back a QuerySet instance and couldn’t call additional custom manager methods.
Though not documented, it was common to work around this issue by creating a custom QuerySet so that custom methods could be chained; but the solution had a number of drawbacks:
• The custom QuerySet and its custom methods were lost after the first call to values() or values_list() .
• Writing a custom Manager was still necessary to return the custom QuerySet class and all methods that were desired on the Manager had to be proxied to the QuerySet. The whole process went against the DRY principle.
The
class method can now directly
create Manager with QuerySet methods :
class FoodQuerySet
(models.QuerySet):
def pizzas
( self ):
return
self
.
filter(kind= 'pizza' )
def vegetarian
( self ):
return
self
.
filter(vegetarian=True)
class Food
(models.Model): kind = models.CharField(max_length= 50 ) vegetarian = models.BooleanField(default=False) objects = FoodQuerySet.as_manager()
Food.objects.pizzas().vegetarian()
Using a custom manager when traversing reverse relations
It is now possible to
when traversing a reverse relationship:
class Blog
(models.Model):
pass class Entry
(models.Model): blog = models.ForeignKey(Blog) objects = models.Manager() # Default Manager entries = EntryManager() # Custom Manager b = Blog.objects.get( id
=
1 ) b.entry_set(manager= 'entries' ).all()
1528 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
New system check framework
We’ve added a new
for detecting common problems (like invalid models) and providing hints for resolving those problems. The framework is extensible so you can add your own checks for your own apps and libraries.
To perform system checks, you use the
management command. This command replaces the older validate management command.
New Prefetch object for advanced prefetch_related operations.
The new
object allows customizing prefetch operations.
You can specify the QuerySet used to traverse a given relation or customize the storage location of prefetch results.
This enables things like filtering prefetched relations, calling
from a prefetched relation, or prefetching the same relation multiple times with different querysets. See
for more details.
Admin shortcuts support time zones
The “today” and “now” shortcuts next to date and time input widgets in the admin are now operating in the
match the current time zone on the server.
In addition, the widgets now display a help message when the browser and server time zone are different, to clarify how the value inserted in the field will be interpreted.
Using database cursors as context managers
Prior to Python 2.7, database cursors could be used as a context manager. The specific backend’s cursor defined the behavior of the context manager. The behavior of magic method lookups was changed with Python 2.7 and cursors were no longer usable as context managers.
Django 1.7 allows a cursor to be used as a context manager. That is, the following can be used:
with
connection.cursor() as c: c.execute(...) instead of: c = connection.cursor()
try
: c.execute(...)
finally
: c.close()
Custom lookups
It is now possible to write custom lookups and transforms for the ORM. Custom lookups work just like Django’s built-in lookups (e.g. lte, icontains) while transforms are a new concept.
The
class provides a way to add lookup operators for model fields. As an example it is possible to add day_lte operator for DateFields.
9.1. Final releases 1529
Django Documentation, Release 2.0.dev20170914110741
The
class allows transformations of database values prior to the final lookup.
For example it is possible to write a year transform that extracts year from the field’s value. Transforms allow for chaining. After the year transform has been added to DateField it is possible to filter on the transformed value, for example qs.filter(author__birthdate__year__lte=1981).
For more information about both custom lookups and transforms refer to the
documentation.
Improvements to Form error handling
Form.add_error()
Previously there were two main patterns for handling errors in forms:
• Raising a
from within certain functions (e.g.
clean_<fieldname>()
, or Form.clean() for non-field errors.)
Field.clean()
,
Form.
• Fiddling with Form._errors when targeting a specific field in Form.clean() or adding errors from outside of a “clean” method (e.g. directly from a view).
Using the former pattern was straightforward since the form can guess from the context (i.e. which method raised the exception) where the errors belong and automatically process them. This remains the canonical way of adding errors when possible. However the latter was fiddly and error-prone, since the burden of handling edge cases fell on the user.
The new
method allows adding errors to specific form fields from anywhere without having to worry about the details such as creating instances of django.forms.utils.ErrorList or dealing with Form.
cleaned_data
. This new API replaces manipulating Form._errors which now becomes a private API.
See
Cleaning and validating fields that depend on each other
for an example using Form.add_error().
Error metadata
The
constructor accepts metadata such as error code or params which are then available for interpolating into the error message (see
for more details); however, before Django 1.7 those metadata were discarded as soon as the errors were added to
and django.forms.utils.ErrorList now store the ValidationError instances so these metadata can be retrieved at any time through the new
method.
The retrieved ValidationError instances can then be identified thanks to their error code which enables things like rewriting the error’s message or writing custom logic in a view when a given error is present. It can also be used to serialize the errors in a custom format such as XML.
The new
method is a convenience method which returns error messages along with error codes serialized as JSON. as_json() uses as_data() and gives an idea of how the new system could be extended.
Error containers and backward compatibility
Heavy changes to the various error containers were necessary in order to support the features above, specifically
, django.forms.utils.ErrorList, and the internal storages of
These containers which used to store error strings now store ValidationError instances and public APIs have been adapted to make this as transparent as possible, but if you’ve been using private APIs, some of the changes are backwards incompatible; see
ValidationError constructor and internal storage
for more details.
1530 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
Minor features django.contrib.admin
• You can now implement
attributes on a custom
in order to easily change the admin site’s page title and header text. No more needing to override templates!
• Buttons in
now use the border-radius CSS property for rounded corners rather than GIF background images.
• Some admin templates now have app-<app_name> and model-<model_name> classes in their <body> tag to allow customizing the CSS per app or per model.
• The admin changelist cells now have a field-<field_name> class in the HTML to enable style customizations.
• The admin’s search fields can now be customized per-request thanks to the new
ModelAdmin.get_search_fields()
method.
• The
method may be overridden to customize the value of
• In addition to the existing admin.site.register syntax, you can use the new
decorator to register a
• You may specify
= None to disable links on the change list page grid.
• You may now specify
to control whether or not to display the “View on site” link.
• You can specify a descending ordering for a
value by prefixing the admin_order_field value with a hyphen.
• The
ModelAdmin.get_changeform_initial_data()
method may be overridden to define custom behavior for setting initial change form data.
django.contrib.auth
• Any **kwargs passed to
are passed to the underlying
call.
• The
decorator can take a list of permissions as well as a single permission.
• You can override the new
AuthenticationForm.confirm_login_allowed()
method to more easily customize the login policy.
•
django.contrib.auth.views.password_reset()
takes an optional html_email_template_name parameter used to send a multipart HTML email for password resets.
• The
AbstractBaseUser.get_session_auth_hash()
method was added and if your
inherits from
, changing a user’s password now invalidates
old sessions if the django.contrib.auth.middleware.SessionAuthenticationMiddleware
is enabled. See
Session invalidation on password change
for more details.
9.1. Final releases 1531
Django Documentation, Release 2.0.dev20170914110741
django.contrib.formtools
• Calls to WizardView.done() now include a form_dict to allow easier access to forms by their step name.
django.contrib.gis
• The default OpenLayers library version included in widgets has been updated from 2.11 to 2.13.
• Prepared geometries now also support the crosses, disjoint, overlaps, touches and within predicates, if GEOS 3.3 or later is installed.
django.contrib.messages
• The backends for
that use cookies, will now follow the
and
settings.
• The
now adds a dictionary of default levels under the name
DEFAULT_MESSAGE_LEVELS
.
•
objects now have a level_tag attribute that contains the string representation of the message level.
django.contrib.redirects
•
has two new attributes
and
instances the middleware returns.
django.contrib.sessions
• The "django.contrib.sessions.backends.cached_db" session backend now respects
. In previous versions, it always used the default cache.
django.contrib.sitemaps
• The
now makes use of
to set a Last-Modified header in the response. This makes it possible for the
to handle conditional GET requests for sitemaps which set lastmod.
django.contrib.sites
• The new
django.contrib.sites.middleware.CurrentSiteMiddleware
allows setting the current site on each request.
1532 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
django.contrib.staticfiles
• The
may be subclassed to override the permissions that collected static files and directories receive by setting the
and
parameters. See
for example usage.
• The
backend gets a sibling class called
that doesn’t use the cache system at all but instead a JSON file called staticfiles.json for storing the mapping between the original file name (e.g. css/styles.
css
) and the hashed file name (e.g. css/styles.55e7cbb9ba48.css). The staticfiles.json
file is created when running the
management command and should be a less expensive alternative for remote storages such as Amazon S3.
See the
docs for more information.
•
now accepts verbosity flag level 2, meaning it will show the relative paths of the directories it searched. See
for example output.
django.contrib.syndication
• The
syndication feed’s updated element now utilizes updateddate instead of pubdate, allowing the published element to be included in the feed (which relies on pubdate).
Cache
• Access to caches configured in
is now available via
object provides a different instance per thread. It supersedes django.core.cache.get_cache() which is now deprecated.
• If you instantiate cache backends directly, be aware that they aren’t thread-safe any more, as
now yields different instances per thread.
• Defining the
argument of the
setting as None will set the cache keys as “non-expiring” by default. Previously, it was only possible to pass timeout=None to the cache backend’s set() method.
Cross Site Request Forgery
• The
setting facilitates the use of session-based CSRF cookies.
•
now accepts an html_message parameter for sending a multipart text/plain and text/html email.
• The SMTP
now accepts a timeout parameter.
File Storage
• File locking on Windows previously depended on the PyWin32 package; if it wasn’t installed, file locking failed silently. That dependency has been removed, and file locking is now implemented natively on both Windows and Unix.
9.1. Final releases 1533
Django Documentation, Release 2.0.dev20170914110741
File Uploads
• The new
UploadedFile.content_type_extra
attribute contains extra parameters passed to the content-type header on a file upload.
• The new
FILE_UPLOAD_DIRECTORY_PERMISSIONS
setting controls the file system permissions of directories created during file upload, like
does for the files themselves.
• The
attribute is now optional. If it is omitted or given None or an empty string, a subdirectory won’t be used for storing the uploaded files.
• Uploaded files are now explicitly closed before the response is delivered to the client. Partially uploaded files are also closed as long as they are named file in the upload handler.
•
now appends an underscore plus a random 7 character alphanumeric string (e.g. "_x3a1gho"), rather than iterating through an underscore followed by a number (e.g. "_1",
"_2"
, etc.) to prevent a denial-of-service attack. This change was also made in the 1.6.6, 1.5.9, and 1.4.14
security releases.
Forms
• The <label> and <input> tags rendered by
and
when looping over the radio buttons or checkboxes now include for and id attributes, respectively. Each radio button or checkbox includes an id_for_label attribute to output the element’s ID.
• The <textarea> tags rendered by
now include a maxlength attribute if the
model field has a max_length.
•
now allows you to customize the “empty choice” label by including a tuple with an empty string or None for the key and the custom label as the value. The default blank option "----------" will be omitted in this case.
•
allows optional subfields by setting the require_all_fields argument to False.
The required attribute for each individual field will be respected, and a new incomplete validation error will be raised when any required fields are empty.
• The
method on a form no longer needs to return self.cleaned_data. If it does return a changed dictionary then that will still be used.
• After a temporary regression in Django 1.6, it’s now possible again to make
coerce method return an arbitrary value.
•
can be used to customize the wording of the months displayed in the select widget.
• The min_num and validate_min parameters were added to
to allow validating a minimum number of submitted forms.
• The metaclasses used by Form and ModelForm have been reworked to support more inheritance scenarios.
The previous limitation that prevented inheriting from both Form and ModelForm simultaneously have been removed as long as ModelForm appears first in the MRO.
• It’s now possible to remove a field from a Form when subclassing by setting the name to None.
• It’s now possible to customize the error messages for ModelForm’s unique, unique_for_date, and unique_together constraints.
In order to support unique_together or any other
NON_FIELD_ERROR
, ModelForm now looks for the NON_FIELD_ERROR key in the error_messages dictionary of the ModelForm’s inner Meta class. See
considerations regarding model’s error_messages
for more details.
1534 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
Internationalization
• The
django.middleware.locale.LocaleMiddleware.response_redirect_class
attribute allows you to customize the redirects issued by the middleware.
• The
now stores the user’s selected language with the session key _language. This should only be accessed using the
constant. Previously it was stored with the key django_language and the LANGUAGE_SESSION_KEY constant did not exist, but keys reserved for
Django should start with an underscore. For backwards compatibility django_language is still read from in 1.7. Sessions will be migrated to the new key as they are written.
• The
tag now supports a trimmed option. This option will remove newline characters from the beginning and the end of the content of the {% blocktrans %} tag, replace any whitespace at the beginning and end of a line and merge all lines into one using a space character to separate them. This is quite useful for indenting the content of a {% blocktrans %} tag without having the indentation characters end up in the corresponding entry in the PO file, which makes the translation process easier.
• When you run
from the root directory of your project, any extracted strings will now be automatically distributed to the proper app or project message file. See
Localization: how to create language files
for details.
• The
command now always adds the --previous command line flag to the msgmerge command, keeping previously translated strings in po files for fuzzy strings.
• The following settings to adjust the language cookie options were introduced:
and
• Added
for Esperanto.
Management Commands
• The new
option for django-admin disables the colorization of management command output.
• The new
and
options, and the new use_natural_foreign_keys and use_natural_primary_keys arguments for serializers.serialize() , allow the use of natural primary keys when serializing.
• It is no longer necessary to provide the cache table name or the --database option for the
command. Django takes this information from your settings file. If you have configured multiple caches or multiple databases, all cache tables are created.
• The
command received several improvements:
– On Linux systems, if pyinotify is installed, the development server will reload immediately when a file is changed. Previously, it polled the filesystem for changes every second. That caused a small delay before reloads and reduced battery life on laptops.
– In addition, the development server automatically reloads when a translation file is updated, i.e. after running
– All HTTP requests are logged to the console, including requests for static files or favicon.ico that used to be filtered out.
• Management commands can now produce syntax colored output under Windows if the ANSICON third-party tool is installed and active.
•
command with symlink option is now supported on Windows NT 6 (Windows Vista and newer).
9.1. Final releases 1535
Django Documentation, Release 2.0.dev20170914110741
• Initial SQL data now works better if the sqlparse Python library is installed.
Note that it’s deprecated in favor of the
operation of migrations, which benefits from the improved behavior.
Models
• The
method was added.
• The new
model Meta option allows you to customize (or disable) creation of the default add, change, and delete permissions.
• Explicit
for
are now discovered in abstract classes.
• It is now possible to avoid creating a backward relation for
by setting its
to '+' or ending it with '+'.
•
support the power operator (**).
• The remove() and clear() methods of the related managers created by ForeignKey and
GenericForeignKey now accept the bulk keyword argument to control whether or not to perform operations in bulk (i.e. using QuerySet.update()). Defaults to True.
• It is now possible to use None as a query value for the
lookup.
• It is now possible to pass a callable as value for the attribute
when defining a
ForeignKey or ManyToManyField.
• Calling
and
on the result of
now raises an error (before that, it would either result in a database error or incorrect data).
• You can use a single list for
(rather than a list of lists) when specifying a single set of fields.
• Custom intermediate models having more than one foreign key to any of the models participating in a manyto-many relationship are now permitted, provided you explicitly specify which foreign keys should be used by setting the new
ManyToManyField.through_fields
argument.
• Assigning a model instance to a non-relation field will now throw an error. Previously this used to work if the field accepted integers as input as it took the primary key.
• Integer fields are now validated against database backend specific min and max values based on their
data type range from being saved resulting in an integrity error.
• It is now possible to explicitly
a relation _id field by using its attribute name.
Signals
• The enter argument was added to the
signal.
• The model signals can be now be connected to using a str of the 'app_label.ModelName' form – just like related fields – to lazily reference their senders.
Templates
• The
method now returns a context manager which automatically calls
upon exiting the with statement. Additionally,
now accepts parameters that are passed to the dict constructor used to build the new context level.
1536 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
• The new
method returns a Context‘s stack as one flat dictionary.
• Context objects can now be compared for equality (internally, this uses
so the internal structure of each Context‘s stack doesn’t matter as long as their flattened version is identical).
• The
template tag now accepts an "as" parameter to capture the result in a variable.
• The
template tag will now also accept anything with a render() method (such as a Template) as an argument. String arguments will be looked up using
as always.
• It is now possible to
templates recursively.
• Template objects now have an origin attribute set when TEMPLATE_DEBUG is True. This allows template origins to be inspected and logged outside of the django.template infrastructure.
• TypeError exceptions are no longer silenced when raised during the rendering of a template.
• The following functions now accept a dirs parameter which is a list or tuple to override TEMPLATE_DIRS:
–
django.template.loader.get_template()
–
django.template.loader.select_template()
–
– django.shortcuts.render_to_response()
• The
filter now accepts timezone-related
'e'
, 'O' , 'T' and 'Z' and is able to digest
datetime instances performing the expected rendering.
• The
tag will now try to use the cache called “template_fragments” if it exists and fall back to using the default cache otherwise. It also now accepts an optional using keyword argument to control which cache it uses.
• The new
filter truncates a string to be no longer than the specified number of characters, taking HTML into account.
Requests and Responses
• The new
attribute specifies the scheme of the request (http or https normally).
• The shortcut
now supports relative URLs.
• The new
subclass of
helps easily create JSON-encoded responses.
Tests
•
has two new attributes,
and
the way tests are collected and run.
• The fetch_redirect_response argument was added to
can’t fetch externals URLs, this allows you to use assertRedirects with redirects that aren’t part of your
Django app.
• Correct handling of scheme when making comparisons in
• The secure argument was added to all the request methods of
Client . If True, the request will be made
through HTTPS.
•
now prints out the list of executed queries if the assertion fails.
9.1. Final releases 1537
Django Documentation, Release 2.0.dev20170914110741
• The WSGIRequest instance generated by the test handler is now attached to the
attribute.
• The database settings for testing have been collected into a dictionary named
Utilities
• Improved
accuracy (but it still cannot guarantee an HTML-safe result, as stated in the documentation).
Validators
•
now accepts the optional
and Boolean
arguments.
The
attribute determines if the
should be raised when the regular expression pattern matches (True) or does not match (False, by default) the provided value. The
attribute sets the flags used when compiling a regular expression string.
•
now accepts an optional schemes argument which allows customization of the accepted
URI schemes (instead of the defaults http(s) and ftp(s)).
•
now accepts addresses with IPv6 literals, like example@[2001:db8::1], as specified in RFC 5321.
Backwards incompatible changes in 1.7
Warning: In addition to the changes outlined in this section, be sure to review the
for any features that have been removed. If you haven’t updated your code within the deprecation timeline for a given feature, its removal may appear as a backwards incompatible change.
allow_syncdb
/ allow_migrate
While Django will still look at allow_syncdb methods even though they should be renamed to allow_migrate, there is a subtle difference in which models get passed to these methods.
For apps with migrations, allow_migrate will now get passed
historical models , which are special versioned mod-
els without custom attributes, methods or managers. Make sure your allow_migrate methods are only referring to fields or other items in model._meta.
initial_data
Apps with migrations will not load initial_data fixtures when they have finished migrating. Apps without migrations will continue to load these fixtures during the phase of migrate which emulates the old syncdb behavior, but any new apps will not have this support.
Instead, you are encouraged to load initial data in migrations if you need it (using the RunPython operation and your model classes); this has the added advantage that your initial data will not need updating every time you change the schema.
Additionally, like the rest of Django’s old syncdb code, initial_data has been started down the deprecation path and will be removed in Django 1.9.
1538 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
deconstruct() and serializability
Django now requires all Field classes and all of their constructor arguments to be serializable. If you modify the constructor signature in your custom Field in any way, you’ll need to implement a deconstruct() method; we’ve expanded the custom field documentation with
instructions on implementing this method .
The requirement for all field arguments to be
means that any custom class instances being passed into
Field constructors - things like custom Storage subclasses, for instance - need to have a
App-loading changes
Start-up sequence
Django 1.7 loads application configurations and models as soon as it starts. While this behavior is more straightforward and is believed to be more robust, regressions cannot be ruled out. See
for solutions to some problems you may encounter.
Standalone scripts
If you’re using Django in a plain Python script — rather than a management command — and you rely on the
environment variable, you must now explicitly initialize Django at the beginning of your script with:
>>>
import
django
>>> django.setup()
Otherwise, you will hit an AppRegistryNotReady exception.
WSGI scripts
Until Django 1.3, the recommended way to create a WSGI application was:
import
django.core.handlers.wsgi
application = django.core.handlers.wsgi.WSGIHandler()
In Django 1.4, support for WSGI was improved and the API changed to:
from
django.core.wsgi
import
get_wsgi_application application = get_wsgi_application()
If you’re still using the former style in your WSGI script, you need to upgrade to the latter, or you will hit an
AppRegistryNotReady exception.
App registry consistency
It is no longer possible to have multiple installed applications with the same label. In previous versions of Django, this didn’t always work correctly, but didn’t crash outright either.
If you have two apps with the same label, you should create an
for one of them and override its
there. You should then adjust your code wherever it references this application or its models with the old label.
9.1. Final releases 1539
Django Documentation, Release 2.0.dev20170914110741
It isn’t possible to import the same model twice through different paths any more. As of Django 1.6, this may happen only if you’re manually putting a directory and a subdirectory on
PYTHONPATH
. Refer to the section on the new project layout in the
for migration instructions.
You should make sure that:
• All models are defined in applications that are listed in
or have an explicit
• Models aren’t imported as a side-effect of loading their application. Specifically, you shouldn’t import models in the root module of an application nor in the module that define its configuration class.
Django will enforce these requirements as of version 1.9, after a deprecation period.
Subclassing AppCommand
Subclasses of
must now implement a
method instead of handle_app()
. This method receives an
instance instead of a models module.
Introspecting applications
Since
now supports application configuration classes in addition to application modules, you
should review code that accesses this setting directly and use the app registry ( django.apps.apps
The app registry has preserved some features of the old app cache. Even though the app cache was a private API, obsolete methods and arguments will be removed through a standard deprecation path, with the exception of the following changes that take effect immediately:
• get_model raises
LookupError instead of returning None when no model is found.
• The only_installed argument of get_model and get_models no longer exists, nor does the seed_cache argument of get_model.
Management commands and order of INSTALLED_APPS
When several applications provide management commands with the same name, Django loads the command from the application that comes first in
. Previous versions loaded the command from the application that
came last.
This brings discovery of management commands in line with other parts of Django that rely on the order of
, such as static files, templates, and translations.
ValidationError constructor and internal storage
The behavior of the ValidationError constructor has changed when it receives a container of errors as an argument (e.g. a list or an ErrorList):
• It converts any strings it finds to instances of ValidationError before adding them to its internal storage.
• It doesn’t store the given container but rather copies its content to its own internal storage; previously the container itself was added to the ValidationError instance and used as internal storage.
This means that if you access the ValidationError internal storages, such as error_list; error_dict; or the return value of update_error_dict() you may find instances of ValidationError where you would have previously found strings.
1540 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
Also if you directly assigned the return value of update_error_dict() to Form._errors you may inadvertently add list instances where ErrorList instances are expected. This is a problem because unlike a simple list, an
ErrorList knows how to handle instances of ValidationError.
Most use-cases that warranted using these private APIs are now covered by the newly introduced
method:
# Old pattern:
try
:
# ...
except
ValidationError as e: self
.
_errors = e.update_error_dict( self
.
_errors)
# New pattern:
try
:
# ...
except
ValidationError as e: self
.
add_error(None, e)
If you need both Django <= 1.6 and 1.7 compatibility you can’t use
since it wasn’t available before Django 1.7, but you can use the following workaround to convert any list into ErrorList:
try
:
# ...
except
ValidationError as e: self
.
_errors = e.update_error_dict( self
.
_errors)
# Additional code to ensure ``ErrorDict`` is exclusively
# composed of ``ErrorList`` instances.
for
field, error_list in self
.
_errors.items():
if not
isinstance (error_list, self
.
error_class): self
.
_errors[field] = self
.
error_class(error_list)
Behavior of LocMemCache regarding pickle errors
An inconsistency existed in previous versions of Django regarding how pickle errors are handled by different cache backends. django.core.cache.backends.locmem.LocMemCache used to fail silently when such an error occurs, which is inconsistent with other backends and leads to cache-specific errors. This has been fixed in Django
1.7, see #21200 for more details.
Cache keys are now generated from the request’s absolute URL
Previous versions of Django generated cache keys using a request’s path and query string but not the scheme or host.
If a Django application was serving multiple subdomains or domains, cache keys could collide. In Django 1.7, cache keys vary by the absolute URL of the request including scheme, host, path, and query string. For example, the URL portion of a cache key is now generated from https://www.example.com/path/to/?key=val rather than
/path/to/?key=val . The cache keys generated by Django 1.7 will be different from the keys generated by older versions of Django. After upgrading to Django 1.7, the first request to any previously cached URL will be a cache miss.
9.1. Final releases 1541
Django Documentation, Release 2.0.dev20170914110741
Passing None to Manager.db_manager()
In previous versions of Django, it was possible to use db_manager(using=None) on a model manager instance to obtain a manager instance using default routing behavior, overriding any manually specified database routing. In
Django 1.7, a value of None passed to db_manager will produce a router that retains any manually assigned database routing – the manager will not be reset. This was necessary to resolve an inconsistency in the way routing information cascaded over joins. See #13724 for more details.
pytz may be required
If your project handles datetimes before 1970 or after 2037 and Django raises a
ValueError when encountering them, you will have to install pytz . You may be affected by this problem if you use Django’s time zone-related date formats or
remove() and clear() methods of related managers
The remove() and clear() methods of the related managers created by ForeignKey, GenericForeignKey, and ManyToManyField suffered from a number of issues. Some operations ran multiple data modifying queries without wrapping them in a transaction, and some operations didn’t respect default filtering when it was present (i.e.
when the default manager on the related model implemented a custom get_queryset()).
Fixing the issues introduced some backward incompatible changes:
• The default implementation of remove() for ForeignKey related managers changed from a series of
Model.save() calls to a single QuerySet.update() call. The change means that pre_save and post_save signals aren’t sent anymore. You can use the bulk=False keyword argument to revert to the previous behavior.
• The remove() and clear() methods for GenericForeignKey related managers now perform bulk delete. The Model.delete() method isn’t called on each instance anymore. You can use the bulk=False keyword argument to revert to the previous behavior.
• The remove() and clear() methods for ManyToManyField related managers perform nested queries when filtering is involved, which may or may not be an issue depending on your database and your data itself.
See
for more details.
Admin login redirection strategy
Historically, the Django admin site passed the request from an unauthorized or unauthenticated user directly to the login view, without HTTP redirection. In Django 1.7, this behavior changed to conform to a more traditional workflow where any unauthorized request to an admin page will be redirected (by HTTP status code 302) to the login page, with the next parameter set to the referring path. The user will be redirected there after a successful login.
Note also that the admin login form has been updated to not contain the this_is_the_login_form field (now unused) and the ValidationError code has been set to the more regular invalid_login key.
select_for_update() requires a transaction
Historically, queries that use
could be executed in autocommit mode, outside of a transaction. Before Django 1.6, Django’s automatic transactions mode allowed this to be used to lock records until the next write operation. Django 1.6 introduced database-level autocommit; since then, execution in such a context voids the effect of select_for_update(). It is, therefore, assumed now to be an error and raises an exception.
1542 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
This change was made because such errors can be caused by including an app which expects global transactions (e.g.
set to True), or Django’s old autocommit behavior, in a project which runs without them; and further, such errors may manifest as data-corruption bugs. It was also made in Django 1.6.3.
This change may cause test failures if you use select_for_update() in a test class which is a subclass of
rather than
Contrib middleware removed from default MIDDLEWARE_CLASSES
The
deprecated using models from apps which are not part of the
setting. This exposed an incompatibility between the default
and MIDDLEWARE_CLASSES in the global defaults (django.conf.global_settings).
To bring these settings in sync and prevent deprecation warnings when doing things like testing reusable apps with minimal settings,
were removed from the defaults. These classes will still be included in the default settings generated by
. Most projects will not be affected by this
change but if you were not previously declaring the MIDDLEWARE_CLASSES in your project settings and relying on the global default you should ensure that the new defaults are in line with your project’s needs. You should also check for any code that accesses django.conf.global_settings.MIDDLEWARE_CLASSES directly.
Miscellaneous
• The
django.core.files.uploadhandler.FileUploadHandler.new_file()
method is now passed an additional content_type_extra parameter. If you have a custom
that implements new_file(), be sure it accepts this new parameter.
•
ModelFormSet s no longer delete instances when save(commit=False) is called. See
for instructions on how to manually delete objects from deleted forms.
• Loading empty fixtures emits a RuntimeWarning rather than raising
•
django.contrib.staticfiles.views.serve()
will now raise an
exception instead of
when
is False. This change removes the need to conditionally add the view to your root URLconf, which in turn makes it safe to reverse by name. It also removes the ability for visitors to generate spurious HTTP 500 errors by requesting static files that don’t exist or haven’t been collected yet.
• The
django.db.models.Model.__eq__()
method is now defined in a way where instances of a proxy model and its base model are considered equal when primary keys match. Previously only instances of exact same class were considered equal on primary key match.
• The
django.db.models.Model.__eq__()
method has changed such that two Model instances without primary key values won’t be considered equal (unless they are the same instance).
• The
django.db.models.Model.__hash__()
method will now raise TypeError when called on an instance without a primary key value. This is done to avoid mutable __hash__ values in containers.
•
columns in SQLite databases will now be created using the AUTOINCREMENT option, which guarantees monotonic increments. This will cause primary key numbering behavior to change on SQLite, becoming consistent with most other SQL databases. This will only apply to newly created tables. If you have a database created with an older version of Django, you will need to migrate it to take advantage of this feature.
For example, you could do the following:
1. Use
to save your data.
2. Rename the existing database file (keep it as a backup).
3. Run
to create the updated schema.
9.1. Final releases 1543
Django Documentation, Release 2.0.dev20170914110741
4. Use
to import the fixtures you exported in (1).
• django.contrib.auth.models.AbstractUser no longer defines a
method.
The old definition returned "/users/%s/" % urlquote(self.username) which was arbitrary since applications may or may not define such a url in urlpatterns.
Define a get_absolute_url() method on your own custom user object or use
if you want a URL for your user.
• The static asset-serving functionality of the
django.test.LiveServerTestCase
class has been simplified: Now it’s only able to serve content already present in
when tests are run. The ability to transparently serve all the static assets (similarly to what one gets with
at developmenttime) has been moved to a new class that lives in the staticfiles application (the one actually in charge of such feature):
django.contrib.staticfiles.testing.StaticLiveServerTestCase
other words, LiveServerTestCase itself is less powerful but at the same time has less magic.
Rationale behind this is removal of dependency of non-contrib code on contrib applications.
• The old cache URI syntax (e.g. "locmem://") is no longer supported. It still worked, even though it was not documented or officially supported. If you’re still using it, please update to the current
syntax.
• The default ordering of Form fields in case of inheritance has changed to follow normal Python MRO. Fields are now discovered by iterating through the MRO in reverse with the topmost class coming last. This only affects you if you relied on the default field ordering while having fields defined on both the current class and on a parent Form.
• The required argument of
has been removed. This widget now respects the form field’s is_required attribute like other widgets.
• Widget.is_hidden is now a read-only property, getting its value by introspecting the presence of input_type == 'hidden'
.
•
now chains in the same way as other similar calls like prefetch_related.
That is, select_related('foo', 'bar') is equivalent to select_related('foo').
select_related('bar') select_related('bar')
.
.
Previously the latter would have been equivalent to
• GeoDjango dropped support for GEOS < 3.1.
• The init_connection_state method of database backends now executes in autocommit mode (unless you set
to False). If you maintain a custom database backend, you should check that method.
• The django.db.backends.BaseDatabaseFeatures.allows_primary_key_0 attribute has been renamed to allows_auto_pk_0 to better describe it. It’s True for all database backends included with Django except MySQL which does allow primary keys with value 0. It only forbids autoincrement primary keys with value 0.
• Shadowing model fields defined in a parent model has been forbidden as this creates ambiguity in the expected model behavior. In addition, clashing fields in the model inheritance hierarchy result in a system check error. For example, if you use multi-inheritance, you need to define custom primary key fields on parent models, otherwise the default id fields will clash. See
for details.
• django.utils.translation.parse_accept_lang_header() now returns lowercase locales, instead of the case as it was provided. As locales should be treated case-insensitive this allows us to speed up locale detection.
• django.utils.translation.get_language_from_path() and django.utils.
translation.trans_real.get_supported_language_variant() now no longer have a supported argument.
• The shortcut view in django.contrib.contenttypes.views now supports protocol-relative URLs
(e.g. //example.com).
1544 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
•
now supports an optional related_query_name argument.
Setting related_query_name adds a relation from the related object back to the content type for filtering, ordering and other query operations.
• When running tests on PostgreSQL, the
will need read access to the built-in postgres database. This is in lieu of the previous behavior of connecting to the actual non-test database.
• As part of the
fields, models, and model managers
all implement a check() method that is registered with the check framework. If you have an existing method called check() on one of these objects, you will need to rename it.
• As noted above in the “Cache” section of “Minor Features”, defining the
argument of the
setting as None will set the cache keys as “non-expiring”. Previously, with the memcache backend, a
of 0 would set non-expiring keys, but this was inconsistent with the set-and-expire (i.e. no caching) behavior of set("key", "value", timeout=0)
. If you want non-expiring keys, please update your settings to use
None instead of 0 as the latter now designates set-and-expire in the settings as well.
• The sql* management commands now respect the allow_migrate() method of
If you have models synced to non-default databases, use the --database flag to get SQL for those models
(previously they would always be included in the output).
• Decoding the query string from URLs now falls back to the ISO-8859-1 encoding when the input is not valid
UTF-8.
• With the addition of the django.contrib.auth.middleware.
SessionAuthenticationMiddleware to the default project template (pre-1.7.2 only), a database must be created before accessing a page using
• The addition of the schemes argument to URLValidator will appear as a backwards-incompatible change if you were previously using a custom regular expression to validate schemes. Any scheme not listed in schemes will fail validation, even if the regular expression matches the given URL.
Features deprecated in 1.7
django.core.cache.get_cache
django.core.cache.get_cache
has been supplanted by
django.utils.dictconfig
/django.utils.importlib
django.utils.dictconfig
and django.utils.importlib were copies of respectively logging.
config and importlib provided for Python versions prior to 2.7. They have been deprecated.
django.utils.module_loading.import_by_path
The current django.utils.module_loading.import_by_path function catches AttributeError,
ImportError , and ValueError exceptions, and re-raises
ImproperlyConfigured . Such exception mask-
ing makes it needlessly hard to diagnose circular import problems, because it makes it look like the problem comes from inside Django. It has been deprecated in favor of
9.1. Final releases 1545
Django Documentation, Release 2.0.dev20170914110741
django.utils.tzinfo
django.utils.tzinfo
provided two tzinfo subclasses, LocalTimezone and FixedOffset. They’ve been deprecated in favor of more correct alternatives provided by
timezone.get_default_timezone()
and
django.utils.timezone.get_fixed_timezone() .
django.utils.unittest
django.utils.unittest
provided uniform access to the unittest2 library on all Python versions. Since unittest2 became the standard library’s unittest module in Python 2.7, and Django 1.7 drops support for older
Python versions, this module isn’t useful anymore. It has been deprecated. Use unittest instead.
django.utils.datastructures.SortedDict
As OrderedDict was added to the standard library in Python 2.7, SortedDict is no longer needed and has been deprecated.
The two additional, deprecated methods provided by SortedDict (insert() and value_for_index()) have been removed. If you relied on these methods to alter structures like form fields, you should now treat these
OrderedDict s as immutable objects and override them to change their content.
For example, you might want to override MyFormClass.base_fields (although this attribute isn’t considered a public API) to change the ordering of fields for all MyFormClass instances; or similarly, you could override self.fields
from inside MyFormClass.__init__(), to change the fields for a particular form instance. For example (from Django itself):
PasswordChangeForm.base_fields = OrderedDict(
(k, PasswordChangeForm.base_fields[k])
for
k in [ 'old_password' , 'new_password1' , 'new_password2' ]
)
Custom SQL location for models package
Previously, if models were organized in a package (myapp/models/) rather than simply myapp/models.py,
Django would look for initial SQL data in myapp/models/sql/. This bug has been fixed so that Django will search myapp/sql/ as documented. After this issue was fixed, migrations were added which deprecates initial SQL data. Thus, while this change still exists, the deprecation is irrelevant as the entire feature will be removed in Django
1.9.
Reorganization of django.contrib.sites
django.contrib.sites
provides reduced functionality when it isn’t in
refactor adds some constraints in that situation. As a consequence, two objects were moved, and the old locations are deprecated:
•
now lives in django.contrib.sites.requests.
•
now lives in django.contrib.sites.shortcuts.
1546 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
declared_fieldsets attribute on ModelAdmin
ModelAdmin.declared_fieldsets
has been deprecated. Despite being a private API, it will go through a regular deprecation path. This attribute was mostly used by methods that bypassed ModelAdmin.get_fieldsets() but this was considered a bug and has been addressed.
Reorganization of django.contrib.contenttypes
Since django.contrib.contenttypes.generic defined both admin and model related objects, an import of this module could trigger unexpected side effects. As a consequence, its contents were split into
submodules and the django.contrib.contenttypes.generic module is deprecated:
•
and
now live in
•
and
generic_inlineformset_factory()
now live in
•
and
now live in
syncdb
The syncdb command has been deprecated in favor of the new
command. migrate takes the same arguments as syncdb used to plus a few more, so it’s safe to just change the name you’re calling and nothing else.
util modules renamed to utils
The following instances of util.py in the Django codebase have been renamed to utils.py in an effort to unify all util and utils references:
• django.contrib.admin.util
• django.contrib.gis.db.backends.util
• django.db.backends.util
• django.forms.util
get_formsets method on ModelAdmin
ModelAdmin.get_formsets
has been deprecated in favor of the new
in order to better handle the case of selectively showing inlines on a ModelAdmin.
IPAddressField
The django.db.models.IPAddressField
and django.forms.IPAddressField
fields have been deprecated in favor of
django.db.models.GenericIPAddressField
and
9.1. Final releases 1547
Django Documentation, Release 2.0.dev20170914110741
BaseMemcachedCache._get_memcache_timeout
method
The BaseMemcachedCache._get_memcache_timeout() method has been renamed to get_backend_timeout() . Despite being a private API, it will go through the normal deprecation.
Natural key serialization options
The --natural and -n options for
have been deprecated. Use
instead.
Similarly, the use_natural_keys argument for serializers.serialize() has been deprecated. Use use_natural_foreign_keys instead.
Merging of POST and GET arguments into WSGIRequest.REQUEST
It was already strongly suggested that you use GET and POST instead of REQUEST, because the former are more explicit. The property REQUEST is deprecated and will be removed in Django 1.9.
django.utils.datastructures.MergeDict
class
MergeDict exists primarily to support merging POST and GET arguments into a REQUEST property on
WSGIRequest
. To merge dictionaries, use dict.update() instead. The class MergeDict is deprecated and will be removed in Django 1.9.
Language codes zh-cn, zh-tw and fy-nl
The currently used language codes for Simplified Chinese zh-cn, Traditional Chinese zh-tw and (Western) Frysian fy-nl are deprecated and should be replaced by the language codes zh-hans, zh-hant and fy respectively.
If you use these language codes, you should rename the locale directories and update your settings to reflect these changes. The deprecated language codes will be removed in Django 1.9.
django.utils.functional.memoize
function
The function memoize is deprecated and should be replaced by the functools.lru_cache decorator (available from Python 3.2 onwards).
Django ships a backport of this decorator for older Python versions and it’s available at django.utils.
lru_cache.lru_cache
. The deprecated function will be removed in Django 1.9.
Geo Sitemaps
Google has retired support for the Geo Sitemaps format. Hence Django support for Geo Sitemaps is deprecated and will be removed in Django 1.8.
1548 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
Passing callable arguments to queryset methods
Callable arguments for querysets were an undocumented feature that was unreliable. It’s been deprecated and will be removed in Django 1.9.
Callable arguments were evaluated when a queryset was constructed rather than when it was evaluated, thus this feature didn’t offer any benefit compared to evaluating arguments before passing them to queryset and created confusion that the arguments may have been evaluated at query time.
ADMIN_FOR setting
The ADMIN_FOR feature, part of the admindocs, has been removed. You can remove the setting from your configuration at your convenience.
SplitDateTimeWidget with DateTimeField
SplitDateTimeWidget support in
is deprecated, use SplitDateTimeWidget with
instead.
validate
The validate management command is deprecated in favor of the
command.
django.core.management.BaseCommand
requires_model_validation is deprecated in favor of a new requires_system_checks flag. If the latter flag is missing, then the value of the former flag is used. Defining both requires_system_checks and requires_model_validation results in an error.
The check() method has replaced the old validate() method.
ModelAdmin validators
The ModelAdmin.validator_class and default_validator_class attributes are deprecated in favor of the new checks_class 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
This method is deprecated in favor of a new check_field method.
The functionality required by check_field() is the same as that provided by validate_field(), but the output format is different. Thirdparty database backends needing this functionality should provide an implementation of check_field().
9.1. Final releases 1549
Django Documentation, Release 2.0.dev20170914110741
Loading ssi and url template tags from future library
Django 1.3 introduced {% load ssi from future %} and {% load url from future %} syntax for forward compatibility of the ssi and
template tags. This syntax is now deprecated and will be removed in
Django 1.9. You can simply remove the {% load ... from future %} tags.
django.utils.text.javascript_quote
javascript_quote() was an undocumented function present in django.utils.text. It was used internally in the javascript_catalog() view whose implementation was changed to make use of json.dumps() instead. If you were relying on this function to provide safe output from untrusted strings, you should use django.
utils.html.escapejs
or the
template filter. If all you need is to generate valid JavaScript strings, you can simply use json.dumps().
fix_ampersands utils method and template filter
The django.utils.html.fix_ampersands method and the fix_ampersands template filter are deprecated, as the escaping of ampersands is already taken care of by Django’s standard HTML escaping features. Combining this with fix_ampersands would either result in double escaping, or, if the output is assumed to be safe, a risk of introducing XSS vulnerabilities. Along with fix_ampersands, django.utils.html.clean_html
is deprecated, an undocumented function that calls fix_ampersands. As this is an accelerated deprecation, fix_ampersands and clean_html will be removed in Django 1.8.
Reorganization of database test settings
All database settings with a TEST_ prefix have been deprecated in favor of entries in a
dictionary in the database settings. The old settings will be supported until Django 1.9. For backwards compatibility with older versions of
Django, you can define both versions of the settings as long as they match.
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()
Django no longer uses this functional internally. Even though it’s a private API, it’ll go through the normal deprecation cycle.
1550 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
Private Query Lookup APIs
Private APIs django.db.models.sql.where.WhereNode.make_atom() and django.db.models.
sql.where.Constraint
are deprecated in favor of the new
Features removed in 1.7
These features have reached the end of their deprecation cycle and are removed in Django 1.7. See
for details, including how to remove usage of these features.
• django.utils.simplejson is removed.
• django.utils.itercompat.product is removed.
• INSTALLED_APPS and TEMPLATE_DIRS are no longer corrected from a plain string into a tuple.
•
no longer take a mimetype argument
•
immediately consumes its content if it’s an iterator.
• The AUTH_PROFILE_MODULE setting, and the get_profile() method on the User model are removed.
• The cleanup management command is removed.
• The daily_cleanup.py script is removed.
•
no longer has a depth keyword argument.
• The get_warnings_state()/restore_warnings_state() functions from
and the save_warnings_state()/ restore_warnings_state()
are removed.
• The check_for_test_cookie method in
is removed.
• The version of
django.contrib.auth.views.password_reset_confirm()
that supports base36 encoded user IDs (django.contrib.auth.views.password_reset_confirm_uidb36) is removed.
• The django.utils.encoding.StrAndUnicode mix-in is removed.
1.6 release
Django 1.6.11 release notes
March 18, 2015
Django 1.6.11 fixes two security issues in 1.6.10.
Denial-of-service possibility with strip_tags()
Last year
was changed to work iteratively. The problem is that the size of the input it’s processing can increase on each iteration which results in an infinite loop in strip_tags(). This issue only affects versions of Python that haven’t received a bugfix in HTMLParser ; namely Python < 2.7.7 and 3.3.5. Some operating system vendors have also backported the fix for the Python bug into their packages of earlier versions.
To remedy this issue, strip_tags() will now return the original input if it detects the length of the string it’s processing increases. Remember that absolutely NO guarantee is provided about the results of strip_tags()
9.1. Final releases 1551
Django Documentation, Release 2.0.dev20170914110741
being HTML safe. So NEVER mark safe the result of a strip_tags() call without escaping it first, for example with
Mitigated possible XSS attack via user-supplied redirect URLs
Django relies on user input in some cases (e.g.
django.contrib.auth.views.login()
and
to redirect the user to an “on success” URL. The security checks for these redirects (namely django.
utils.http.is_safe_url()
) accepted URLs with leading control characters and so considered URLs like
\x08javascript:...
safe. This issue doesn’t affect Django currently, since we only put this URL into the
Location response header and browsers seem to ignore JavaScript there. Browsers we tested also treat URLs prefixed with control characters such as %08//example.com as relative paths so redirection to an unsafe target isn’t a problem either.
However, if a developer relies on is_safe_url() to provide safe redirect targets and puts such a URL into a link, they could suffer from an XSS attack as some browsers such as Google Chrome ignore control characters at the start of a URL in an anchor href.
Django 1.6.10 release notes
January 13, 2015
Django 1.6.10 fixes several security issues in 1.6.9.
WSGI header spoofing via underscore/dash conflation
When HTTP headers are placed into the WSGI environ, they are normalized by converting to uppercase, converting all dashes to underscores, and prepending HTTP_. For instance, a header X-Auth-User would become
HTTP_X_AUTH_USER in the WSGI environ (and thus also in Django’s request.META dictionary).
Unfortunately, this means that the WSGI environ cannot distinguish between headers containing dashes and headers containing underscores: X-Auth-User and X-Auth_User both become HTTP_X_AUTH_USER. This means that if a header is used in a security-sensitive way (for instance, passing authentication information along from a front-end proxy), even if the proxy carefully strips any incoming value for X-Auth-User, an attacker may be able to provide an X-Auth_User header (with underscore) and bypass this protection.
In order to prevent such attacks, both Nginx and Apache 2.4+ strip all headers containing underscores from incoming requests by default. Django’s built-in development server now does the same. Django’s development server is not recommended for production use, but matching the behavior of common production servers reduces the surface area for behavior changes during deployment.
Mitigated possible XSS attack via user-supplied redirect URLs
Django relies on user input in some cases (e.g.
django.contrib.auth.views.login()
and
redirect the user to an “on success” URL. The security checks for these redirects (namely django.utils.
http.is_safe_url()
) didn’t strip leading whitespace on the tested URL and as such considered URLs like
\njavascript:...
safe. If a developer relied on is_safe_url() to provide safe redirect targets and put such a URL into a link, they could suffer from a XSS attack. This bug doesn’t affect Django currently, since we only put this URL into the Location response header and browsers seem to ignore JavaScript there.
1552 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
Denial-of-service attack against django.views.static.serve
In older versions of Django, the
view read the files it served one line at a time. Therefore, a big file with no newlines would result in memory usage equal to the size of that file. An attacker could exploit this and launch a denial-of-service attack by simultaneously requesting many large files. This view now reads the file in chunks to prevent large memory usage.
Note, however, that this view has always carried a warning that it is not hardened for production use and should be used only as a development aid. Now may be a good time to audit your project and serve your files in production using a real front-end web server if you are not doing so.
Database denial-of-service with ModelMultipleChoiceField
Given a form that uses ModelMultipleChoiceField and show_hidden_initial=True (not a documented API), it was possible for a user to cause an unreasonable number of SQL queries by submitting duplicate values for the field’s data. The validation logic in ModelMultipleChoiceField now deduplicates submitted values to address this issue.
Django 1.6.9 release notes
January 2, 2015
Django 1.6.9 fixes a regression in the 1.6.6 security release.
Additionally, Django’s vendored version of six, django.utils.six, has been upgraded to the latest release
(1.9.0).
Bugfixes
• Fixed a regression with dynamically generated inlines and allowed field references in the admin ( #23754 ).
Django 1.6.8 release notes
October 22, 2014
Django 1.6.8 fixes a couple regressions in the 1.6.6 security release.
Bugfixes
• Allowed related many-to-many fields to be referenced in the admin ( #23604 ).
• Allowed inline and hidden references to admin fields ( #23431 ).
Django 1.6.7 release notes
September 2, 2014
Django 1.6.7 fixes several bugs in 1.6.6, including a regression related to a security fix in that release.
9.1. Final releases 1553
Django Documentation, Release 2.0.dev20170914110741
Bugfixes
• Allowed inherited and m2m fields to be referenced in the admin ( #23329 ).
• Fixed a crash when using QuerySet.defer() with select_related() ( #23370 ).
Django 1.6.6 release notes
August 20, 2014
Django 1.6.6 fixes several security issues and bugs in 1.6.5.
reverse() could generate URLs pointing to other hosts
In certain situations, URL reversing could generate scheme-relative URLs (URLs starting with two slashes), which could unexpectedly redirect a user to a different host. An attacker could exploit this, for example, by redirecting users to a phishing site designed to ask for user’s passwords.
To remedy this, URL reversing now ensures that no URL starts with two slashes (//), replacing the second slash with its
URL encoded counterpart (%2F). This approach ensures that semantics stay the same, while making the URL relative to the domain and not to the scheme.
File upload denial-of-service
Before this release, Django’s file upload handing in its default configuration may degrade to producing a huge number of os.stat() system calls when a duplicate filename is uploaded. Since stat() may invoke IO, this may produce a huge data-dependent slowdown that slowly worsens over time. The net result is that given enough time, a user with the ability to upload files can cause poor performance in the upload handler, eventually causing it to become very slow simply by uploading 0-byte files. At this point, even a slow network connection and few HTTP requests would be all that is necessary to make a site unavailable.
We’ve remedied the issue by changing the algorithm for generating file names if a file with the uploaded name already exists.
now appends an underscore plus a random 7 character alphanumeric string (e.g. "_x3a1gho"), rather than iterating through an underscore followed by a number (e.g. "_1", "_2", etc.).
RemoteUserMiddleware session hijacking
When using the
and the RemoteUserBackend, a change to the REMOTE_USER header between requests without an intervening logout could result in the prior user’s session being co-opted by the subsequent user. The middleware now logs the user out on a failed login attempt.
Data leakage via query string manipulation in contrib.admin
In older versions of Django it was possible to reveal any field’s data by modifying the “popup” and “to_field” parameters of the query string on an admin change form page. For example, requesting a URL like /admin/auth/user/
?_popup=1&t=password and viewing the page’s HTML allowed viewing the password hash of each user. While the admin requires users to have permissions to view the change form pages in the first place, this could leak data if you rely on users having access to view only certain fields on a model.
To address the issue, an exception will now be raised if a to_field value that isn’t a related field to a model that has been registered with the admin is specified.
1554 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
Bugfixes
• Corrected email and URL validation to reject a trailing dash ( #22579 ).
• Prevented indexes on PostgreSQL virtual fields ( #22514 ).
• Prevented edge case where values of FK fields could be initialized with a wrong value when an inline model formset is created for a relationship defined to point to a field other than the PK ( #13794 ).
• Restored pre_delete signals for GenericRelation cascade deletion ( #22998 ).
• Fixed transaction handling when specifying non-default database in createcachetable and flush
( #23089 ).
• Fixed the “ORA-01843: not a valid month” errors when using Unicode with older versions of Oracle server
( #20292 ).
• Restored bug fix for sending unicode email with Python 2.6.5 and below ( #19107 ).
• Prevented UnicodeDecodeError in runserver with non-UTF-8 and non-English locale ( #23265 ).
• Fixed JavaScript errors while editing multi-geometry objects in the OpenLayers widget ( #23137 , #23293 ).
• Prevented a crash on Python 3 with query strings containing unencoded non-ASCII characters ( #22996 ).
Django 1.6.5 release notes
May 14, 2014
Django 1.6.5 fixes two security issues and several bugs in 1.6.4.
Issue: Caches may incorrectly be allowed to store and serve private data
In certain situations, Django may allow caches to store private data related to a particular session and then serve that data to requests with a different session, or no session at all. This can lead to information disclosure and can be a vector for cache poisoning.
When using Django sessions, Django will set a Vary:
Cookie header to ensure caches do not serve cached data to requests from other sessions. However, older versions of Internet Explorer (most likely only Internet Explorer
6, and Internet Explorer 7 if run on Windows XP or Windows Server 2003) are unable to handle the Vary header in combination with many content types. Therefore, Django would remove the header if the request was made by
Internet Explorer.
To remedy this, the special behavior for these older Internet Explorer versions has been removed, and the Vary header is no longer stripped from the response. In addition, modifications to the Cache-Control header for all Internet
Explorer requests with a Content-Disposition header have also been removed as they were found to have similar issues.
Issue: Malformed redirect URLs from user input not correctly validated
The validation for redirects did not correctly validate some malformed URLs, which are accepted by some browsers.
This allows a user to be redirected to an unsafe URL unexpectedly.
Django relies on user input in some cases (e.g.
django.contrib.auth.views.login()
contrib.comments
, and
i18n ) to redirect the user to an “on success” URL. The security checks for these redirects
(namely django.utils.http.is_safe_url()) did not correctly validate some malformed URLs, such as http:\\\djangoproject.com
, which are accepted by some browsers with more liberal URL parsing.
9.1. Final releases 1555
Django Documentation, Release 2.0.dev20170914110741
To remedy this, the validation in is_safe_url() has been tightened to be able to handle and correctly validate these malformed URLs.
Bugfixes
• Made the year_lookup_bounds_for_datetime_field Oracle backend method Python 3 compatible
( #22551 ).
• Fixed pgettext_lazy crash when receiving bytestring content on Python 2 ( #22565 ).
• Fixed the SQL generated when filtering by a negated Q object that contains a F object. ( #22429 ).
• Avoided overwriting data fetched by select_related() in certain cases which could cause minor performance regressions ( #22508 ).
Django 1.6.4 release notes
April 28, 2014
Django 1.6.4 fixes several bugs in 1.6.3.
Bugfixes
• Added backwards compatibility support for the
cookie format of Django 1.4
and earlier to facilitate upgrading to 1.6 from 1.4 ( #22426 ).
• Restored the ability to reverse() views created using functools.partial() ( #22486 ).
• Fixed the object_id of the LogEntry that’s created after a user password change in the admin ( #22515 ).
Django 1.6.3 release notes
April 21, 2014
Django 1.6.3 fixes several bugs in 1.6.2, including three security issues, and makes one backwards-incompatible change:
Unexpected code execution using reverse()
Django’s URL handling is based on a mapping of regex patterns (representing the URLs) to callable views, and
Django’s own processing consists of matching a requested URL against those patterns to determine the appropriate view to invoke.
Django also provides a convenience function – reverse() – which performs this process in the opposite direction.
The reverse() function takes information about a view and returns a URL which would invoke that view. Use of reverse() is encouraged for application developers, as the output of reverse() is always based on the current
URL patterns, meaning developers do not need to change other code when making changes to URLs.
One argument signature for reverse() is to pass a dotted Python path to the desired view. In this situation, Django will import the module indicated by that dotted path as part of generating the resulting URL. If such a module has import-time side effects, those side effects will occur.
Thus it is possible for an attacker to cause unexpected code execution, given the following conditions:
1556 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
1. One or more views are present which construct a URL based on user input (commonly, a “next” parameter in a querystring indicating where to redirect upon successful completion of an action).
2. One or more modules are known to an attacker to exist on the server’s Python import path, which perform code execution with side effects on importing.
To remedy this, reverse() will now only accept and import dotted paths based on the view-containing modules listed in the project’s
, so as to ensure that only modules the developer intended to be
imported in this fashion can or will be imported.
Caching of anonymous pages could reveal CSRF token
Django includes both a
and a system for
preventing cross-site request forgery (CSRF) attacks . The
CSRF-protection system is based on a random nonce sent to the client in a cookie which must be sent by the client on future requests and, in forms, a hidden value which must be submitted back with the form.
The caching framework includes an option to cache responses to anonymous (i.e., unauthenticated) clients.
When the first anonymous request to a given page is by a client which did not have a CSRF cookie, the cache framework will also cache the CSRF cookie and serve the same nonce to other anonymous clients who do not have a CSRF cookie. This can allow an attacker to obtain a valid CSRF cookie value and perform attacks which bypass the check for the cookie.
To remedy this, the caching framework will no longer cache such responses. The heuristic for this will be:
1. If the incoming request did not submit any cookies, and
2. If the response did send one or more cookies, and
3. If the Vary:
Cookie header is set on the response, then the response will not be cached.
MySQL typecasting
The MySQL database is known to “typecast” on certain queries; for example, when querying a table which contains string values, but using a query which filters based on an integer value, MySQL will first silently coerce the strings to integers and return a result based on that.
If a query is performed without first converting values to the appropriate type, this can produce unexpected results, similar to what would occur if the query itself had been manipulated.
Django’s model field classes are aware of their own types and most such classes perform explicit conversion of query arguments to the correct database-level type before querying. However, three model field classes did not correctly convert their arguments:
•
•
• IPAddressField
These three fields have been updated to convert their arguments to the correct types before querying.
Additionally, developers of custom model fields are now warned via documentation to ensure their custom field classes will perform appropriate type conversions, and users of the
and
query methods – which allow the developer to supply raw SQL or SQL fragments – will be advised to ensure they perform appropriate manual type conversions prior to executing queries.
9.1. Final releases 1557
Django Documentation, Release 2.0.dev20170914110741
select_for_update() requires a transaction
Historically, queries that use
could be executed in autocommit mode, outside of a transaction. Before Django 1.6, Django’s automatic transactions mode allowed this to be used to lock records until the next write operation. Django 1.6 introduced database-level autocommit; since then, execution in such a context voids the effect of select_for_update(). It is, therefore, assumed now to be an error and raises an exception.
This change was made because such errors can be caused by including an app which expects global transactions (e.g.
set to True), or Django’s old autocommit behavior, in a project which runs without them; and further, such errors may manifest as data-corruption bugs.
This change may cause test failures if you use select_for_update() in a test class which is a subclass of
rather than
Other bugfixes and changes
• Content retrieved from the GeoIP library is now properly decoded from its default iso-8859-1 encoding
( #21996 ).
• Fixed AttributeError when using
with ForeignObject ( #21566 ).
• Fixed crash of QuerySets that use F() + timedelta() when their query was compiled more once
( #21643 ).
• Prevented custom widget class attribute of
subclasses from being overwritten by the code in their __init__ method ( #22245 ).
• Improved
accuracy (but it still cannot guarantee an HTML-safe result, as stated in the documentation).
• Fixed a regression in the
SQL compiler for non-concrete fields ( #22250 ).
• Fixed
when running a site with a URL prefix ( #21795 ).
• Fixed a crash in the find_command management utility when the PATH environment variable wasn’t set
( #22256 ).
• Fixed
on Windows ( #22364 ).
• Avoided shadowing deadlock exceptions on MySQL ( #22291 ).
• Wrapped database exceptions in _set_autocommit ( #22321 ).
• Fixed atomicity when closing a database connection or when the database server disconnects ( #21239 and
#21202 )
• Fixed regression in prefetch_related that caused the related objects query to include an unnecessary join
( #21760 ).
Additionally, Django’s vendored version of six, django.utils.six has been upgraded to the latest release (1.6.1).
Django 1.6.2 release notes
February 6, 2014
This is Django 1.6.2, a bugfix release for Django 1.6. Django 1.6.2 fixes several bugs in 1.6.1:
• Prevented the base geometry object of a prepared geometry to be garbage collected, which could lead to crash
Django ( #21662 ).
1558 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
• Fixed a crash when executing the
command when the user object representation contained non-ASCII characters ( #21627 ).
• The
command will raise an error rather than default to using the current working directory if
is not set. Combined with the --clear option, the previous behavior could wipe anything below the current working directory ( #21581 ).
• Fixed mail encoding on Python 3.3.3+ ( #21093 ).
• Fixed an issue where when settings.DATABASES['default']['AUTOCOMMIT'] = False, the connection wasn’t in autocommit mode but Django pretended it was.
• Fixed a regression in multiple-table inheritance exclude() queries ( #21787 ).
• Added missing items to django.utils.timezone.__all__ ( #21880 ).
• Fixed a field misalignment issue with select_related() and model inheritance ( #21413 ).
• Fixed join promotion for negated AND conditions ( #21748 ).
• Oracle database introspection now works with boolean and float fields ( #19884 ).
• Fixed an issue where lazy objects weren’t actually marked as safe when passed through
and could end up being double-escaped ( #21882 ).
Additionally, Django’s vendored version of six, django.utils.six has been upgraded to the latest release (1.5.2).
Django 1.6.1 release notes
December 12, 2013
This is Django 1.6.1, a bugfix release for Django 1.6. In addition to the bug fixes listed below, translations submitted since the 1.6 release are also included.
Bug fixes
• Fixed BCryptSHA256PasswordHasher with py-bcrypt and Python 3 (#21398).
• Fixed a regression that prevented a ForeignKey with a hidden reverse manager (related_name ending with ‘+’) from being used as a lookup for prefetch_related (#21410).
• Fixed
raising AttributeError in some situations (#21432).
• Fixed
raising UnboundLocalError if
raised an error (#21439).
• Fixed a regression that prevented editable GenericRelation subclasses from working in ModelForms
(#21428).
• Added missing to_python method for ModelMultipleChoiceField which is required in Django 1.6
to properly detect changes from initial values (#21568).
• Fixed django.contrib.humanize translations where the unicode sequence for the non-breaking space was returned verbatim (#21415).
• Fixed
error when fixture file name contained any dots not related to file extensions (#21457) or when fixture path was relative but located in a subdirectory (#21551).
• Fixed display of inline instances in formsets when parent has 0 for primary key (#21472).
• Fixed a regression where custom querysets for foreign keys were overwritten if ModelAdmin had ordering set
(#21405).
9.1. Final releases 1559
Django Documentation, Release 2.0.dev20170914110741
• Removed mention of a feature in the --locale/-l option of the makemessages and compilemessages commands that never worked as promised: Support of multiple locale names separated by commas. It’s still possible to specify multiple locales in one run by using the option multiple times (#21488, #17181).
• Fixed a regression that unnecessarily triggered settings configuration when importing get_wsgi_application (#21486).
• Fixed test client logout() method when using the cookie-based session backend (#21448).
• Fixed a crash when a GeometryField uses a non-geometric widget (#21496).
• Fixed password hash upgrade when changing the iteration count (#21535).
• Fixed a bug in the debug view when the URLconf only contains one element (#21530).
• Re-added missing search result count and reset link in changelist admin view (#21510).
• The current language is no longer saved to the session by LocaleMiddleware on every response, but rather only after a logout (#21473).
• Fixed a crash when executing runserver on non-English systems and when the formatted date in its output contained non-ASCII characters (#21358).
• Fixed a crash in the debug view after an exception occurred on Python ≥ 3.3 (#21443).
• Fixed a crash in
on some platforms (Homebrew and RHEL6 reported) (#21355).
• Fixed a regression when using generic relations in ModelAdmin.list_filter (#21431).
Django 1.6 release notes
Note: Dedicated to Malcolm Tredinnick
On March 17, 2013, the Django project and the free software community lost a very dear friend and developer.
Malcolm was a long-time contributor to Django, a model community member, a brilliant mind, and a friend. His contributions to Django — and to many other open source projects — are nearly impossible to enumerate. Many on the core Django team had their first patches reviewed by him; his mentorship enriched us. His consideration, patience, and dedication will always be an inspiration to us.
This release of Django is for Malcolm.
– The Django Developers
November 6, 2013
Welcome to Django 1.6!
These release notes cover the
new features , as well as some
backwards incompatible changes
you’ll want to be aware of when upgrading from Django 1.5 or older versions. We’ve also dropped some features, which are detailed in
our deprecation plan , and we’ve
begun the deprecation process for some features .
Python compatibility
Django 1.6, like Django 1.5, requires Python 2.6.5 or above. Python 3 is also officially supported. We highly recommend the latest minor release for each supported Python series (2.6.X, 2.7.X, 3.2.X, and 3.3.X).
Django 1.6 will be the final release series to support Python 2.6; beginning with Django 1.7, the minimum supported
Python version will be 2.7.
1560 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
Python 3.4 is not supported, but support will be added in Django 1.7.
What’s new in Django 1.6
Simplified default project and app templates
The default templates used by
and
have been simplified and modernized. The
is now enabled by default in new projects; the
framework no longer is.
is now on and the database defaults to SQLite.
If the default templates don’t suit your tastes, you can use
custom project and app templates .
Improved transaction management
Django’s transaction management was overhauled. Database-level autocommit is now turned on by default. This makes transaction handling more explicit and should improve performance. The existing APIs were deprecated, and new APIs were introduced, as described in the
Persistent database connections
Django now supports reusing the same database connection for several requests. This avoids the overhead of reestablishing a connection at the beginning of each request. For backwards compatibility, this feature is disabled by default. See
for details.
Discovery of tests in any test module
Django 1.6 ships with a new test runner that allows more flexibility in the location of tests. The previous runner
(django.test.simple.DjangoTestSuiteRunner) found tests only in the models.py and tests.py
modules of a Python package in
The new runner (django.test.runner.DiscoverRunner) uses the test discovery features built into unittest2
(the version of unittest in the Python 2.7+ standard library, and bundled with Django). With test discovery, tests can be located in any module whose name matches the pattern test*.py.
In addition, the test labels provided to ./manage.py test to nominate specific tests to run must now be full
Python dotted paths (or directory paths), rather than applabel.TestCase.test_method_name pseudo-paths.
This allows running tests located anywhere in your codebase, rather than only in
details, see
This change is backwards-incompatible; see the
backwards-incompatibility notes .
Time zone aware aggregation
The support for
introduced in Django 1.4 didn’t work well with
QuerySet.dates() : aggregation was
always performed in UTC. This limitation was lifted in Django 1.6. Use
to perform time zone aware aggregation on a
Support for savepoints in SQLite
Django 1.6 adds support for savepoints in SQLite, with some
9.1. Final releases 1561
Django Documentation, Release 2.0.dev20170914110741
BinaryField model field
A new
model field allows storage of raw binary data in the database.
GeoDjango form widgets
GeoDjango now provides
for its geo-specialized fields. They are OpenLayers-based by default, but they can be customized to use any other JS framework.
check management command added for verifying compatibility
A
management command was added, enabling you to verify if your current configuration (currently oriented at settings) is compatible with the current version of Django.
Model.save() algorithm changed
The
method now tries to directly UPDATE the database if the instance has a primary key value.
Previously SELECT was performed to determine if UPDATE or INSERT were needed. The new algorithm needs only one query for updating an existing row while the old algorithm needed two. See
for more details.
In some rare cases the database doesn’t report that a matching row was found when doing an UPDATE. An example is the PostgreSQL ON UPDATE trigger which returns NULL. In such cases it is possible to set
flag to force saving to use the old algorithm.
Minor features
• Authentication backends can raise PermissionDenied to immediately fail the authentication chain.
• The HttpOnly flag can be set on the CSRF cookie with
• The
now checks for undefined order and raises ValueError if undefined order is spotted. The order is seen as undefined if the given QuerySet isn’t ordered and there are more than one ordered values to compare against.
• Added
for symmetry with
• In addition to
and
and
lookups.
• Django now wraps all PEP-249 exceptions.
• The default widgets for
and
use the new type attributes available in HTML5 (type='email', type='url', type='number'). Note that due to erratic support of the number input type with localized numbers in current browsers, Django only uses it when numeric fields are not localized.
• The number argument for
can be provided at translation time rather than at definition time.
• For custom management commands: Verification of the presence of valid settings in commands that ask for it by using the BaseCommand.can_import_settings internal option is now performed independently from handling of the locale that should be active during the execution of the command. The latter can now be influenced by the new
internal option. See
Management commands and locales
for more details.
• The
of
is now interpolated with its object’s __dict__.
1562 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
•
and
now provide an url attribute
(equivalent to the URL the response will redirect to).
• The MemcachedCache cache backend now uses the latest pickle protocol available.
• Added
which provides a success_message attribute for
based classes.
• Added the
django.db.models.ForeignKey.db_constraint
and
options.
• The jQuery library embedded in the admin has been upgraded to version 1.9.1.
• Syndication feeds ( django.contrib.syndication
) can now pass extra context through to feed templates
using a new
callback.
• The admin list columns have a column-<field_name> class in the HTML so the columns header can be styled with CSS, e.g. to set a column width.
• The
can be customized under PostgreSQL.
• The
template tag now respects TEMPLATE_STRING_IF_INVALID for variables not present in the context, just like other template constructs.
• SimpleLazyObjects will now present more helpful representations in shell debugging situations.
• Generic
is now editable with the OpenLayers widget in the admin.
• The documentation contains a
• The
command gained a --all option.
• django.forms.fields.Field.__init__ now calls super(), allowing field mixins to implement
__init__() methods that will reliably be called.
• The validate_max parameter was added to BaseFormSet and
and
ModelForm and inline versions of the same. The behavior of validation for formsets with max_num was clarified. The previously undocumented behavior that hardened formsets against memory exhaustion attacks was documented, and the undocumented limit of the higher of 1000 or max_num forms was changed so it is always 1000 more than max_num.
• Added BCryptSHA256PasswordHasher to resolve the password truncation issue with bcrypt.
• Pillow is now the preferred image manipulation library to use with Django.
PIL is pending deprecation (support to be removed in Django 1.8). To upgrade, you should first uninstall PIL, then install Pillow.
•
accepts several new Meta options.
– Fields included in the localized_fields list will be localized (by setting localize on the form field).
– The labels, help_texts and error_messages options may be used to customize the default fields, see
for details.
• The choices argument to model fields now accepts an iterable of iterables instead of requiring an iterable of lists or tuples.
• The reason phrase can be customized in HTTP responses using
• When giving the URL of the next page for
password_reset_confirm() , and
password_change() , you can now pass URL names and
they will be resolved.
• The new
option specifies the primary keys of objects to dump. This option can only be used with one model.
9.1. Final releases 1563
Django Documentation, Release 2.0.dev20170914110741
• Added QuerySet methods
and
which are convenience methods returning the first or last object matching the filters. Returns None if there are no objects matching.
•
and
now support HTTP PATCH method.
• GenericForeignKey now takes an optional for_concrete_model argument, which when set to
False allows the field to reference proxy models. The default is True to retain the old behavior.
• The
now stores the active language in session if it is not present there. This prevents loss of language settings after session flush, e.g. logout.
•
has been differentiated into a number of subclasses, and each will log to a matching named logger under the django.security logging hierarchy. Along with this change, a handler400 mechanism and default view are used whenever a SuspiciousOperation reaches the WSGI handler to return an HttpResponseBadRequest.
• The
exception now includes a message indicating the name of the attribute used for the lookup.
• The
method no longer requires at least one keyword argument.
• The
class includes a new assertion helper for testing formset errors:
• The list of related fields added to a
by
can be cleared using select_related(None)
.
• The
and
methods on
may be overridden to customize the extra and maximum number of inline forms.
• Formsets now have a
method.
•
fields can now override error messages defined in model fields by using the
argument of a Field’s constructor. To take advantage of this new feature with your custom fields,
see the updated recommendation
for raising a ValidationError.
•
now preserves filters on the list view after creating, editing or deleting an object. It’s possible to restore the previous behavior of clearing filters by setting the
attribute to False.
• Added
(which returns
by default) to allow customizing the
of the form.
• Raw queries (Manager.raw() or cursor.execute()) can now use the “pyformat” parameter style, where placeholders in the query are given as '%(name)s' and the parameters are passed as a dictionary rather than a list (except on SQLite). This has long been possible (but not officially supported) on MySQL and
PostgreSQL, and is now also available on Oracle.
• The default iteration count for the PBKDF2 password hasher has been increased by 20%. This backwards compatible change will not affect existing passwords or users who have subclassed django.contrib.auth.
hashers.PBKDF2PasswordHasher
to change the default value. Passwords
to use the new iteration count as necessary.
Backwards incompatible changes in 1.6
Warning:
In addition to the changes outlined in this section, be sure to review the
for any features that have been removed. If you haven’t updated your code within the deprecation timeline for a given feature, its removal may appear as a backwards incompatible change.
1564 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
New transaction management model
Behavior changes
Database-level autocommit is enabled by default in Django 1.6. While this doesn’t change the general spirit of
Django’s transaction management, there are a few backwards-incompatibilities.
Savepoints and assertNumQueries
The changes in transaction management may result in additional statements to create, release or rollback savepoints.
This is more likely to happen with SQLite, since it didn’t support savepoints until this release.
If tests using
fail because of a higher number of queries than expected, check that the extra queries are related to savepoints, and adjust the expected number of queries accordingly.
Autocommit option for PostgreSQL
In previous versions, database-level autocommit was only an option for PostgreSQL, and it was disabled by default.
This option is now ignored and can be removed.
New test runner
In order to maintain greater consistency with Python’s unittest module, the new test runner (django.test.
runner.DiscoverRunner
) does not automatically support some types of tests that were supported by the previous runner:
• Tests in models.py and tests/__init__.py files will no longer be found and run. Move them to a file whose name begins with test.
• Doctests will no longer be automatically discovered. To integrate doctests in your test suite, follow the recommendations in the Python documentation .
Django bundles a modified version of the doctest module from the Python standard library (in django.test.
_doctest
) and includes some additional doctest utilities. These utilities are deprecated and will be removed in
Django 1.8; doctest suites should be updated to work with the standard library’s doctest module (or converted to unittest-compatible tests).
If you wish to delay updates to your test suite, you can set your
setting to django.test.simple.
DjangoTestSuiteRunner to fully restore the old test behavior. DjangoTestSuiteRunner is deprecated but will not be removed from Django until version 1.8.
Removal of django.contrib.gis.tests.GeoDjangoTestSuiteRunner GeoDjango custom test runner
This is for developers working on the GeoDjango application itself and related to the item above about changes in the test runners:
The django.contrib.gis.tests.GeoDjangoTestSuiteRunner test runner has been removed and the standalone GeoDjango tests execution setup it implemented isn’t supported anymore. To run the GeoDjango tests simply use the new DiscoverRunner and specify the django.contrib.gis app.
9.1. Final releases 1565
Django Documentation, Release 2.0.dev20170914110741
Custom user models in tests
The introduction of the new test runner has also slightly changed the way that test models are imported.
As a result, any test that overrides AUTH_USER_MODEL to test behavior with one of Django’s test user models
( django.contrib.auth.tests.custom_user.CustomUser and django.contrib.auth.tests.
custom_user.ExtensionUser
) must now explicitly import the User model in your test module:
from
django.contrib.auth.tests.custom_user
import
CustomUser
@override_settings(AUTH_USER_MODEL= 'auth.CustomUser' )
class CustomUserFeatureTests
(TestCase):
def test_something
( self ):
# Test code here ...
This import forces the custom user model to be registered. Without this import, the test will be unable to swap in the custom user model, and you will get an error reporting:
ImproperlyConfigured: AUTH_USER_MODEL refers to model 'auth.CustomUser' that has not
˓→ been installed
Time zone-aware day, month, and week_day lookups
Django 1.6 introduces time zone support for
lookups when
is True. These lookups were previously performed in UTC regardless of the current time zone.
This requires
time zone definitions in the database
. If you’re using SQLite, you must install
pytz . If you’re using
MySQL, you must install pytz and load the time zone tables with mysql_tzinfo_to_sql .
Addition of QuerySet.datetimes()
When the
added in Django 1.4 was active,
lookups returned unexpected results, because the aggregation was performed in UTC. To fix this, Django 1.6 introduces a new API,
. This requires a few changes in your code.
QuerySet.dates() returns date objects
now returns a list of date . It used to return a list of datetime .
returns a list of datetime
.
QuerySet.dates() no longer usable on DateTimeField
raises an error if it’s used on
when time zone support is active. Use
instead.
date_hierarchy requires time zone definitions
The
feature of the admin now relies on
when it’s used on a
This requires time zone definitions in the database when
is True.
1566 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
date_list in generic views requires time zone definitions
For the same reason, accessing date_list in the context of a date-based generic view requires time zone definitions in the database when the view is based on a
and
is True.
New lookups may clash with model fields
Django 1.6 introduces hour, minute, and second lookups on
. If you had model fields called
hour
, minute, or second, the new lookups will clash with you field names. Append an explicit
lookup if this is an issue.
BooleanField no longer defaults to False
When a
doesn’t have an explicit
, the implicit default value is None. In previous version
of Django, it was False, but that didn’t represent accurately the lack of a value.
Code that relies on the default value being False may raise an exception when saving new model instances to the database, because None isn’t an acceptable value for a
You should either specify default=False in the field definition, or ensure the field is set to True or False before saving the object.
Translations and comments in templates
Extraction of translations after comments
Extraction of translatable literals from templates with the
command now correctly detects i18n constructs when they are located after a {# / #}-type comment on the same line. E.g.:
{# A comment #}
{% trans
"This literal was incorrectly ignored. Not anymore"
%}
Location of translator comments
Comments for translators in templates
specified using {# / #} need to be at the end of a line. If they are not, the comments are ignored and
will generate a warning. For example:
{# Translators: This is ignored #}
{% trans
"Translate me"
%}
{{
title
}}
{# Translators: Extracted and associated with 'Welcome' below #}
< h1 >
{% trans
"Welcome"
%}
</ h1 >
Quoting in reverse()
When reversing URLs, Django didn’t apply django.utils.http.urlquote to arguments before interpolating them in URL patterns. This bug is fixed in Django 1.6. If you worked around this bug by applying URL quoting before passing arguments to reverse(), this may result in double-quoting. If this happens, simply remove the URL quoting from your code. You will also have to replace special characters in URLs used in
with their encoded versions.
9.1. Final releases 1567
Django Documentation, Release 2.0.dev20170914110741
Storage of IP addresses in the comments app
The comments app now uses a GenericIPAddressField for storing commenters’ IP addresses, to support comments submitted from IPv6 addresses. Until now, it stored them in an IPAddressField, which is only meant to support IPv4. When saving a comment made from an IPv6 address, the address would be silently truncated on MySQL databases, and raise an exception on Oracle. You will need to change the column type in your database to benefit from this change.
For MySQL, execute this query on your project’s database:
ALTER TABLE
django_comments MODIFY ip_address VARCHAR ( 39 );
For Oracle, execute this query:
ALTER TABLE
DJANGO_COMMENTS MODIFY (ip_address VARCHAR2( 39 ));
If you do not apply this change, the behavior is unchanged: on MySQL, IPv6 addresses are silently truncated; on
Oracle, an exception is generated. No database change is needed for SQLite or PostgreSQL databases.
Percent literals in cursor.execute queries
When you are running raw SQL queries through the
method, the rule about doubling percent literals
(%) inside the query has been unified. Past behavior depended on the database backend. Now, across all backends, you only need to double literal percent characters if you are also providing replacement parameters. For example:
# No parameters, no percent doubling cursor.execute( "SELECT foo FROM bar WHERE baz = '30%'" )
# Parameters passed, non-placeholders have to be doubled cursor.execute( "SELECT foo FROM bar WHERE baz = '30%%' and id = %s" , [ self
.
id])
SQLite users need to check and update such queries.
Help text of model form fields for ManyToManyField fields
HTML rendering of model form fields corresponding to
model fields used to get the hard-coded sentence:
Hold down “Control”, or “Command” on a Mac, to select more than one.
(or its translation to the active locale) imposed as the help legend shown along them if neither
nor
help_text attributes were specified by the user (or this string was appended to any help_text that was provided).
Since this happened at the model layer, there was no way to prevent the text from appearing in cases where it wasn’t applicable such as form fields that implement user interactions that don’t involve a keyboard and/or a mouse.
Starting with Django 1.6, as an ad-hoc temporary backward-compatibility provision, the logic to add the “Hold down...” sentence has been moved to the model form field layer and modified to add the text only when the associated widget is
or selected subclasses.
The change can affect you in a backward incompatible way if you employ custom model form fields and/or widgets for ManyToManyField model fields whose UIs do rely on the automatic provision of the mentioned hard-coded sentence. These form field implementations need to adapt to the new scenario by providing their own handling of the help_text attribute.
1568 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
Applications that use Django
facilities together with Django built-in form
and
aren’t affected but need to be aware of what’s described in
Munging of help text of model form fields for ManyToManyField fields
below.
QuerySet iteration
The QuerySet iteration was changed to immediately convert all fetched rows to Model objects. In Django 1.5 and earlier the fetched rows were converted to Model objects in chunks of 100.
Existing code will work, but the amount of rows converted to objects might change in certain use cases. Such usages include partially looping over a queryset or any usage which ends up doing __bool__ or __contains__.
Notably most database backends did fetch all the rows in one go already in 1.5.
It is still possible to convert the fetched rows to Model objects lazily by using the
method.
BoundField.label_tag
now includes the form’s label_suffix
This is consistent with how methods like
and
render labels.
If you manually render label_tag in your templates:
{{
form.my_field.label_tag
}}
:
{{
form.my_field
}}
you’ll want to remove the colon (or whatever other separator you may be using) to avoid duplicating it when upgrading to Django 1.6. The following template in Django 1.6 will render identically to the above template in Django 1.5, except that the colon will appear inside the <label> element.
{{
form.my_field.label_tag
}} {{
form.my_field
}}
will render something like:
< label for
=
"id_my_field" >My Field:</ label > < input id
=
"id_my_field" type
=
"text" name
=
˓→
"my_field" />
If you want to keep the current behavior of rendering label_tag without the label_suffix, instantiate the form label_suffix=''.
You can also customize the label_suffix on a per-field basis using the new label_suffix parameter on
Admin views _changelist_filters GET parameter
To achieve preserving and restoring list view filters, admin views now pass around the _changelist_filters GET parameter. It’s important that you account for that change if you have custom admin templates or if your tests rely on the previous URLs. If you want to revert to the original behavior you can set the
attribute to
False
.
django.contrib.auth
password reset uses base 64 encoding of User PK
Past versions of Django used base 36 encoding of the User primary key in the password reset views and URLs
( django.contrib.auth.views.password_reset_confirm()
). Base 36 encoding is sufficient if the
user primary key is an integer, however, with the introduction of custom user models in Django 1.5, that assumption may no longer be true.
9.1. Final releases 1569
Django Documentation, Release 2.0.dev20170914110741
django.contrib.auth.views.password_reset_confirm()
has been modified to take a uidb64 parameter instead of uidb36. If you are reversing this view, for example in a custom password_reset_email.
html template, be sure to update your code.
A temporary shim for
django.contrib.auth.views.password_reset_confirm()
that will allow password reset links generated prior to Django 1.6 to continue to work has been added to provide backwards compatibility; this will be removed in Django 1.7. Thus, as long as your site has been running Django 1.6 for more than
, this change will have no effect. If not (for example, if you upgrade directly
from Django 1.5 to Django 1.7), then any password reset links generated before you upgrade to Django 1.7 or later won’t work after the upgrade.
In addition, if you have any custom password reset URLs, you will need to update them by replacing uidb36 with uidb64 and the dash that follows that pattern with a slash. Also add _\- to the list of characters that may match the uidb64 pattern.
For example: url( r'^reset/(?P<uidb36>[0-9A-Za-z]+)-(?P<token>.+)/$' ,
'django.contrib.auth.views.password_reset_confirm' , name= 'password_reset_confirm' ), becomes: url( r'^reset/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>.+)/$' ,
'django.contrib.auth.views.password_reset_confirm' , name= 'password_reset_confirm' ),
You may also want to add the shim to support the old style reset links. Using the example above, you would modify the existing url by replacing django.contrib.auth.views.password_reset_confirm with django.
contrib.auth.views.password_reset_confirm_uidb36
and also remove the name argument so it doesn’t conflict with the new url: url( r'^reset/(?P<uidb36>[0-9A-Za-z]+)-(?P<token>.+)/$' ,
'django.contrib.auth.views.password_reset_confirm_uidb36' ),
You can remove this URL pattern after your app has been deployed with Django 1.6
for
Default session serialization switched to JSON
Historically,
used pickle to serialize session data before storing it in the backend.
If you’re using the
and
is known by an attacker (there isn’t an inherent vulnerability in Django that would cause it to leak), the attacker could insert a string into his session which, when unpickled, executes arbitrary code on the server. The technique for doing so is simple and easily available on the internet. Although the cookie session storage signs the cookie-stored data to prevent tampering, a
leak immediately escalates to a remote code execution vulnerability.
This attack can be mitigated by serializing session data using JSON rather than pickle
. To facilitate this, Django
1.5.3 introduced a new setting,
, to customize the session serialization format. For back-
wards compatibility, this setting defaulted to using pickle in Django 1.5.3, but we’ve changed the default to JSON in 1.6. If you upgrade and switch from pickle to JSON, sessions created before the upgrade will be lost. While JSON serialization does not support all Python objects like pickle does, we highly recommend using JSON-serialized sessions. Be aware of the following when checking your code to determine if JSON serialization will work for your application:
• JSON requires string keys, so you will likely run into problems if you are using non-string keys in request.
session
.
1570 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
• Setting session expiration by passing datetime values to
will not work as datetime values are not serializable in JSON. You can use integer values instead.
See the
documentation for more details.
Object Relational Mapper changes
Django 1.6 contains many changes to the ORM. These changes fall mostly in three categories:
1. Bug fixes (e.g. proper join clauses for generic relations, query combining, join promotion, and join trimming fixes)
2. Preparation for new features. For example the ORM is now internally ready for multicolumn foreign keys.
3. General cleanup.
These changes can result in some compatibility problems. For example, some queries will now generate different table aliases. This can affect
. In addition some queries will now produce different results.
An example is
where the condition is a complex one (referencing multijoins inside
there are also cases that produce different results, but neither Django 1.5 nor 1.6 produce correct results.
Finally, there have been many changes to the ORM internal APIs.
Miscellaneous
• The django.db.models.query.EmptyQuerySet can’t be instantiated any more - it is only usable as a marker class for checking if
has been called: isinstance(qs.none(), EmptyQuerySet)
• If your CSS/JavaScript code used to access HTML input widgets by type, you should review it as type='text' widgets might be now output as type='email', type='url' or type='number' depending on their corresponding field type.
• Form field’s
that contain a placeholder should now always use a named placeholder
("Value '%(value)s' is too big" instead of "Value '%s' is too big"). See the corresponding field documentation for details about the names of the placeholders. The changes in 1.6 particularly affect
and
• Some
for
IPAddressField
,
have been suppressed because they duplicated error messages already provided by validators tied to the fields.
• Due to a change in the form validation workflow,
coerce method should always return a value present in the choices field attribute. That limitation should be lift again in Django 1.7.
• There have been changes in the way timeouts are handled in cache backends.
Explicitly passing in timeout=None no longer results in using the default timeout. It will now set a non-expiring timeout. Passing
0 into the memcache backend no longer uses the default timeout, and now will set-and-expire-immediately the value.
• The django.contrib.flatpages app used to set custom HTTP headers for debugging purposes. This functionality was not documented and made caching ineffective so it has been removed, along with its generic implementation, previously available in django.core.xheaders.
• The XViewMiddleware has been moved from django.middleware.doc to django.contrib.
admindocs.middleware
because it is an implementation detail of admindocs, proven not to be reusable in general.
9.1. Final releases 1571
Django Documentation, Release 2.0.dev20170914110741
•
will now only allow blank values if null values are also allowed. Creating a
GenericIPAddressField where blank is allowed but null is not will trigger a model validation error because blank values are always stored as null. Previously, storing a blank value in a field which did not allow null would cause a database exception at runtime.
• If a NoReverseMatch exception is raised from a method when rendering a template, it is not silenced.
For example, {{ obj.view_href }} will cause template rendering to fail if view_href() raises
NoReverseMatch
. There is no change to the
tag, it causes template rendering to fail like always when NoReverseMatch is raised.
•
now calls
which will send the
signal.
•
are now reversed by name, not their locations in django.contrib.auth.views. If you are using the views without a name, you should update your urlpatterns to use
with the name parameter. For example:
( r'^reset/done/$' , 'django.contrib.auth.views.password_reset_complete' ) becomes: url( r'^reset/done/$' , 'django.contrib.auth.views.password_reset_complete' , name=
˓→
'password_reset_complete' )
•
now has a pattern_name attribute which allows it to choose the target by reversing the URL.
• In Django 1.4 and 1.5, a blank string was unintentionally not considered to be a valid password.
This meant
would save a blank password as an unusable password like
does, and thus
always returned False for blank passwords. This has been corrected in this release: blank passwords are now valid.
• The admin
previously accepted a pop GET parameter to signify it was to be displayed in a popup. This parameter has been renamed to _popup to be consistent with the rest of the admin views. You should update your custom templates if they use the previous parameter name.
•
now accepts email addresses with localhost as the domain.
• The new
option prevents deleting the temporary .pot file generated before creating the .po file.
• The undocumented django.core.servers.basehttp.WSGIServerException has been removed.
Use socket.error provided by the standard library instead. This change was also released in Django 1.5.5.
• The signature of
django.views.generic.base.RedirectView.get_redirect_url()
has changed and now accepts positional arguments as well (*args, **kwargs). Any unnamed captured group will now be passed to get_redirect_url() which may result in a TypeError if you don’t update the signature of your custom method.
Features deprecated in 1.6
Transaction management APIs
Transaction management was completely overhauled in Django 1.6, and the current APIs are deprecated:
• django.middleware.transaction.TransactionMiddleware
• django.db.transaction.autocommit
• django.db.transaction.commit_on_success
1572 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
• django.db.transaction.commit_manually
• the TRANSACTIONS_MANAGED setting
django.contrib.comments
Django’s comment framework has been deprecated and is no longer supported. It will be available in Django 1.6 and
1.7, and removed in Django 1.8. Most users will be better served with a custom solution, or a hosted product like
Disqus .
The code formerly known as django.contrib.comments is still available in an external repository .
Support for PostgreSQL versions older than 8.4
The end of upstream support periods was reached in December 2011 for PostgreSQL 8.2 and in February 2013 for
8.3. As a consequence, Django 1.6 sets 8.4 as the minimum PostgreSQL version it officially supports.
You’re strongly encouraged to use the most recent version of PostgreSQL available, because of performance improvements and to take advantage of the native streaming replication available in PostgreSQL 9.x.
Changes to cycle and firstof
The template system generally escapes all variables to avoid XSS attacks. However, due to an accident of history, the
and
tags render their arguments as-is.
Django 1.6 starts a process to correct this inconsistency. The future template library provides alternate implementations of
and
that autoescape their inputs. If you’re using these tags, you’re encouraged to include the following line at the top of your templates to enable the new behavior:
{% load cycle from future
%
} or:
{% load firstof from future
%
}
The tags implementing the old behavior have been deprecated, and in Django 1.8, the old behavior will be replaced with the new behavior. To ensure compatibility with future versions of Django, existing templates should be modified to use the future versions.
If necessary, you can temporarily disable auto-escaping with
or
CACHE_MIDDLEWARE_ANONYMOUS_ONLY setting
CacheMiddleware and UpdateCacheMiddleware used to provide a way to cache requests only if they weren’t made by a logged-in user. This mechanism was largely ineffective because the middleware correctly takes into account the Vary:
Cookie
HTTP header, and this header is being set on a variety of occasions, such as:
• accessing the session, or
• using CSRF protection, which is turned on by default, or
• using a client-side library which sets cookies, like Google Analytics .
This makes the cache effectively work on a per-session basis regardless of the
CACHE_MIDDLEWARE_ANONYMOUS_ONLY setting.
9.1. Final releases 1573
Django Documentation, Release 2.0.dev20170914110741
SEND_BROKEN_LINK_EMAILS setting
used to provide basic reporting of broken links by email when
SEND_BROKEN_LINK_EMAILS is set to True.
Because of intractable ordering problems between
and
was split out into a new middleware:
If you’re relying on this feature, you should add
'django.middleware.common.
BrokenLinkEmailsMiddleware' to your
MIDDLEWARE_CLASSES setting and remove
SEND_BROKEN_LINK_EMAILS from your settings.
_has_changed method on widgets
If you defined your own form widgets and defined the _has_changed method on a widget, you should now define this method on the form field itself.
module_name model _meta attribute
Model._meta.module_name
was renamed to model_name. Despite being a private API, it will go through a regular deprecation path.
get_(add|change|delete)_permission model _meta methods
Model._meta.get_(add|change|delete)_permission methods were deprecated.
Even if they were not part of the public API they’ll also go through a regular deprecation path.
You can replace them with django.contrib.auth.get_permission_codename('action', Model._meta) where
'action' is 'add', 'change', or 'delete'.
get_query_set and similar methods renamed to get_queryset
Methods that return a QuerySet such as Manager.get_query_set or ModelAdmin.queryset have been renamed to get_queryset.
If you are writing a library that implements, for example, a Manager.get_query_set method, and you need to support old Django versions, you should rename the method and conditionally add an alias with the old name:
class CustomManager
(models.Manager):
def get_queryset
( self ):
pass
# ...
if
django.VERSION < ( 1 , 6 ): get_query_set = get_queryset
# For Django >= 1.6, models.Manager provides a get_query_set fallback
# that emits a warning when used.
If you are writing a library that needs to call the get_queryset method and must support old Django versions, you should write:
1574 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
get_queryset = (some_manager.get_query_set
if
hasattr (some_manager, 'get_query_set' )
else
some_manager.get_queryset)
return
get_queryset() # etc
In the general case of a custom manager that both implements its own get_queryset method and calls that method, and needs to work with older Django versions, and libraries that have not been updated yet, it is useful to define a get_queryset_compat method as below and use it internally to your manager:
class YourCustomManager
(models.Manager):
def get_queryset
( self ):
return
YourCustomQuerySet() # for example
if
django.VERSION < ( 1 , 6 ): get_query_set = get_queryset
def active
( self ): # for example
return
self
.
get_queryset_compat().filter(active=True)
def get_queryset_compat
( self ): get_queryset = ( self
.
get_query_set
if
hasattr ( self , 'get_query_set' )
else
self
.
get_queryset)
return
get_queryset()
This helps to minimize the changes that are needed, but also works correctly in the case of subclasses (such as
RelatedManagers from Django 1.5) which might override either get_query_set or get_queryset.
shortcut view and URLconf
The shortcut view was moved from django.views.defaults to django.contrib.contenttypes.
views shortly after the 1.0 release, but the old location was never deprecated. This oversight was corrected in Django
1.6 and you should now use the new location.
The URLconf django.conf.urls.shortcut was also deprecated. If you’re including it in an URLconf, simply replace:
( r'^prefix/' , include( 'django.conf.urls.shortcut' )), with:
( r'^prefix/(?P<content_type_id>\d+)/(?P<object_id>.*)/$' , 'django.contrib.
˓→ contenttypes.views.shortcut' ),
ModelForm without fields or exclude
Previously, if you wanted a
to use all fields on the model, you could simply omit the Meta.fields
attribute, and all fields would be used.
This can lead to security problems where fields are added to the model and, unintentionally, automatically become editable by end users. In some cases, particular with boolean fields, it is possible for this problem to be completely invisible. This is a form of Mass assignment vulnerability .
For this reason, this behavior is deprecated, and using the Meta.exclude option is strongly discouraged. Instead, all fields that are intended for inclusion in the form should be listed explicitly in the fields attribute.
9.1. Final releases 1575
Django Documentation, Release 2.0.dev20170914110741
If this security concern really does not apply in your case, there is a shortcut to explicitly indicate that all fields should be used - use the special value "__all__" for the fields attribute:
class MyModelForm
(ModelForm):
class Meta
: fields = "__all__" model = MyModel
If you have custom ModelForms that only need to be used in the admin, there is another option. The admin has its own methods for defining fields (fieldsets etc.), and so adding a list of fields to the ModelForm is redundant. Instead, simply omit the Meta inner class of the ModelForm, or omit the Meta.model attribute. Since the ModelAdmin subclass knows which model it is for, it can add the necessary attributes to derive a functioning
ModelForm
. This behavior also works for earlier Django versions.
UpdateView and CreateView without explicit fields
The generic views
and
, and anything else derived from
nerable to the security problem described in the section above, because they can automatically create a ModelForm that uses all fields for a model.
For this reason, if you use these views for editing models, you must also supply the fields attribute (new in Django
1.6), which is a list of model fields and works in the same way as the
Meta.fields
attribute. Alternatively, you can set the form_class attribute to a ModelForm that explicitly defines the fields to be used.
Defining an UpdateView or CreateView subclass to be used with a model but without an explicit list of fields is deprecated.
Munging of help text of model form fields for ManyToManyField fields
All special handling of the help_text attribute of ManyToManyField model fields performed by standard model or model form fields as described in
Help text of model form fields for ManyToManyField fields
above is deprecated and will be removed in Django 1.8.
Help text of these fields will need to be handled either by applications, custom form fields or widgets, just like happens with the rest of the model field types.
1.5 release
Django 1.5.12 release notes
January 2, 2015
Django 1.5.12 fixes a regression in the 1.5.9 security release.
Bugfixes
• Fixed a regression with dynamically generated inlines and allowed field references in the admin ( #23754 ).
Django 1.5.11 release notes
October 22, 2014
Django 1.5.11 fixes a couple regressions in the 1.5.9 security release.
1576 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
Bugfixes
• Allowed related many-to-many fields to be referenced in the admin ( #23604 ).
• Allowed inline and hidden references to admin fields ( #23431 ).
Django 1.5.10 release notes
September 2, 2014
Django 1.5.10 fixes a regression in the 1.5.9 security release.
Bugfixes
• Allowed inherited and m2m fields to be referenced in the admin ( #22486 )
Django 1.5.9 release notes
August 20, 2014
Django 1.5.9 fixes several security issues in 1.5.8.
reverse() could generate URLs pointing to other hosts
In certain situations, URL reversing could generate scheme-relative URLs (URLs starting with two slashes), which could unexpectedly redirect a user to a different host. An attacker could exploit this, for example, by redirecting users to a phishing site designed to ask for user’s passwords.
To remedy this, URL reversing now ensures that no URL starts with two slashes (//), replacing the second slash with its
URL encoded counterpart (%2F). This approach ensures that semantics stay the same, while making the URL relative to the domain and not to the scheme.
File upload denial-of-service
Before this release, Django’s file upload handing in its default configuration may degrade to producing a huge number of os.stat() system calls when a duplicate filename is uploaded. Since stat() may invoke IO, this may produce a huge data-dependent slowdown that slowly worsens over time. The net result is that given enough time, a user with the ability to upload files can cause poor performance in the upload handler, eventually causing it to become very slow simply by uploading 0-byte files. At this point, even a slow network connection and few HTTP requests would be all that is necessary to make a site unavailable.
We’ve remedied the issue by changing the algorithm for generating file names if a file with the uploaded name already exists.
now appends an underscore plus a random 7 character alphanumeric string (e.g. "_x3a1gho"), rather than iterating through an underscore followed by a number (e.g. "_1", "_2", etc.).
RemoteUserMiddleware session hijacking
When using the
and the RemoteUserBackend, a change to the REMOTE_USER header between requests without an intervening logout could result in the prior user’s session being co-opted by the subsequent user. The middleware now logs the user out on a failed login attempt.
9.1. Final releases 1577
Django Documentation, Release 2.0.dev20170914110741
Data leakage via query string manipulation in contrib.admin
In older versions of Django it was possible to reveal any field’s data by modifying the “popup” and “to_field” parameters of the query string on an admin change form page. For example, requesting a URL like /admin/auth/user/
?pop=1&t=password and viewing the page’s HTML allowed viewing the password hash of each user. While the admin requires users to have permissions to view the change form pages in the first place, this could leak data if you rely on users having access to view only certain fields on a model.
To address the issue, an exception will now be raised if a to_field value that isn’t a related field to a model that has been registered with the admin is specified.
Django 1.5.8 release notes
May 14, 2014
Django 1.5.8 fixes two security issues in 1.5.8.
Caches may incorrectly be allowed to store and serve private data
In certain situations, Django may allow caches to store private data related to a particular session and then serve that data to requests with a different session, or no session at all. This can lead to information disclosure and can be a vector for cache poisoning.
When using Django sessions, Django will set a Vary:
Cookie header to ensure caches do not serve cached data to requests from other sessions. However, older versions of Internet Explorer (most likely only Internet Explorer
6, and Internet Explorer 7 if run on Windows XP or Windows Server 2003) are unable to handle the Vary header in combination with many content types. Therefore, Django would remove the header if the request was made by
Internet Explorer.
To remedy this, the special behavior for these older Internet Explorer versions has been removed, and the Vary header is no longer stripped from the response. In addition, modifications to the Cache-Control header for all Internet
Explorer requests with a Content-Disposition header have also been removed as they were found to have similar issues.
Malformed redirect URLs from user input not correctly validated
The validation for redirects did not correctly validate some malformed URLs, which are accepted by some browsers.
This allows a user to be redirected to an unsafe URL unexpectedly.
Django relies on user input in some cases (e.g.
django.contrib.auth.views.login()
contrib.comments
, and
i18n ) to redirect the user to an “on success” URL. The security checks for these redirects
(namely django.utils.http.is_safe_url()) did not correctly validate some malformed URLs, such as http:\\\djangoproject.com
, which are accepted by some browsers with more liberal URL parsing.
To remedy this, the validation in is_safe_url() has been tightened to be able to handle and correctly validate these malformed URLs.
Django 1.5.7 release notes
April 28, 2014
Django 1.5.7 fixes a regression in the 1.5.6 security release.
1578 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
Bugfixes
• Restored the ability to reverse() views created using functools.partial() ( #22486 ).
Django 1.5.6 release notes
April 21, 2014
Django 1.5.6 fixes several bugs in 1.5.5, including three security issues.
Unexpected code execution using reverse()
Django’s URL handling is based on a mapping of regex patterns (representing the URLs) to callable views, and
Django’s own processing consists of matching a requested URL against those patterns to determine the appropriate view to invoke.
Django also provides a convenience function – reverse() – which performs this process in the opposite direction.
The reverse() function takes information about a view and returns a URL which would invoke that view. Use of reverse() is encouraged for application developers, as the output of reverse() is always based on the current
URL patterns, meaning developers do not need to change other code when making changes to URLs.
One argument signature for reverse() is to pass a dotted Python path to the desired view. In this situation, Django will import the module indicated by that dotted path as part of generating the resulting URL. If such a module has import-time side effects, those side effects will occur.
Thus it is possible for an attacker to cause unexpected code execution, given the following conditions:
1. One or more views are present which construct a URL based on user input (commonly, a “next” parameter in a querystring indicating where to redirect upon successful completion of an action).
2. One or more modules are known to an attacker to exist on the server’s Python import path, which perform code execution with side effects on importing.
To remedy this, reverse() will now only accept and import dotted paths based on the view-containing modules listed in the project’s
URL pattern configuration , so as to ensure that only modules the developer intended to be
imported in this fashion can or will be imported.
Caching of anonymous pages could reveal CSRF token
Django includes both a
and a system for
preventing cross-site request forgery (CSRF) attacks . The
CSRF-protection system is based on a random nonce sent to the client in a cookie which must be sent by the client on future requests and, in forms, a hidden value which must be submitted back with the form.
The caching framework includes an option to cache responses to anonymous (i.e., unauthenticated) clients.
When the first anonymous request to a given page is by a client which did not have a CSRF cookie, the cache framework will also cache the CSRF cookie and serve the same nonce to other anonymous clients who do not have a CSRF cookie. This can allow an attacker to obtain a valid CSRF cookie value and perform attacks which bypass the check for the cookie.
To remedy this, the caching framework will no longer cache such responses. The heuristic for this will be:
1. If the incoming request did not submit any cookies, and
2. If the response did send one or more cookies, and
3. If the Vary:
Cookie header is set on the response, then the response will not be cached.
9.1. Final releases 1579
Django Documentation, Release 2.0.dev20170914110741
MySQL typecasting
The MySQL database is known to “typecast” on certain queries; for example, when querying a table which contains string values, but using a query which filters based on an integer value, MySQL will first silently coerce the strings to integers and return a result based on that.
If a query is performed without first converting values to the appropriate type, this can produce unexpected results, similar to what would occur if the query itself had been manipulated.
Django’s model field classes are aware of their own types and most such classes perform explicit conversion of query arguments to the correct database-level type before querying. However, three model field classes did not correctly convert their arguments:
•
•
• IPAddressField
These three fields have been updated to convert their arguments to the correct types before querying.
Additionally, developers of custom model fields are now warned via documentation to ensure their custom field classes will perform appropriate type conversions, and users of the
and
query methods – which allow the developer to supply raw SQL or SQL fragments – will be advised to ensure they perform appropriate manual type conversions prior to executing queries.
Bugfixes
• Fixed
raising UnboundLocalError if
raised an error (#21439).
Additionally, Django’s vendored version of six, django.utils.six, has been upgraded to the latest release
(1.6.1).
Django 1.5.5 release notes
October 23, 2013
Django 1.5.5 fixes a couple security-related bugs and several other bugs in the 1.5 series.
Readdressed denial-of-service via password hashers
Django 1.5.4 imposes a 4096-byte limit on passwords in order to mitigate a denial-of-service attack through submission of bogus but extremely large passwords. In Django 1.5.5, we’ve reverted this change and instead improved the speed of our PBKDF2 algorithm by not rehashing the key on every iteration.
Properly rotate CSRF token on login
This behavior introduced as a security hardening measure in Django 1.5.2 did not work properly and is now fixed.
Bugfixes
• Fixed a data corruption bug with datetime_safe.datetime.combine (#21256).
• Fixed a Python 3 incompatibility in django.utils.text.unescape_entities() (#21185).
1580 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
• Fixed a couple data corruption issues with QuerySet edge cases under Oracle and MySQL (#21203, #21126).
• Fixed crashes when using combinations of annotate(), select_related(), and only() (#16436).
Backwards incompatible changes
• The undocumented django.core.servers.basehttp.WSGIServerException has been removed.
Use socket.error provided by the standard library instead.
Django 1.5.4 release notes
September 14, 2013
This is Django 1.5.4, the fourth release in the Django 1.5 series. It addresses two security issues and one bug.
Denial-of-service via password hashers
In previous versions of Django, no limit was imposed on the plaintext length of a password. This allowed a denial-ofservice attack through submission of bogus but extremely large passwords, tying up server resources performing the
(expensive, and increasingly expensive with the length of the password) calculation of the corresponding hash.
As of 1.5.4, Django’s authentication framework imposes a 4096-byte limit on passwords, and will fail authentication with any submitted password of greater length.
Corrected usage of sensitive_post_parameters() in django.contrib.auth’s admin
The decoration of the add_view and user_change_password user admin views with
did not include
(required since the views are methods) resulting in the decorator not being properly applied.
This usage has been fixed and
will now throw an exception if it’s improperly used.
Bugfixes
• Fixed a bug that prevented a QuerySet that uses
from being pickled and unpickled more than once (the second pickling attempt raised an exception) (#21102).
Django 1.5.3 release notes
September 10, 2013
This is Django 1.5.3, the third release in the Django 1.5 series. It addresses one security issue and also contains an opt-in feature to enhance the security of
Directory traversal vulnerability in ssi template tag
In previous versions of Django it was possible to bypass the ALLOWED_INCLUDE_ROOTS setting used for security with the ssi template tag by specifying a relative path that starts with one of the allowed roots. For example, if
ALLOWED_INCLUDE_ROOTS = ("/var/www",) the following would be possible:
9.1. Final releases 1581
Django Documentation, Release 2.0.dev20170914110741
{% ssi
"/var/www/../../etc/passwd"
%}
In practice this is not a very common problem, as it would require the template author to put the ssi file in a usercontrolled variable, but it’s possible in principle.
Mitigating a remote-code execution vulnerability in django.contrib.sessions
currently uses pickle to serialize session data before storing it in the backend. If you’re using the
and
is known by an attacker (there isn’t an inherent vulnerability in Django that would cause it to leak), the attacker could insert a string into his session which, when unpickled, executes arbitrary code on the server. The technique for doing so is simple and easily available on the internet. Although the cookie session storage signs the cookie-stored data to prevent tampering, a
leak immediately escalates to a remote code execution vulnerability.
This attack can be mitigated by serializing session data using JSON rather than pickle
. To facilitate this, Django
1.5.3 introduces a new setting,
, to customize the session serialization format. For back-
wards compatibility, this setting defaults to using pickle
. While JSON serialization does not support all Python objects like pickle does, we highly recommend switching to JSON-serialized values. Also, as JSON requires string keys, you will likely run into problems if you are using non-string keys in request.session. See the
documentation for more details.
Django 1.5.2 release notes
August 13, 2013
This is Django 1.5.2, a bugfix and security release for Django 1.5.
Mitigated possible XSS attack via user-supplied redirect URLs
Django relies on user input in some cases (e.g.
django.contrib.auth.views.login()
contrib.comments
, and
i18n ) to redirect the user to an “on success” URL. The security checks for these redirects
(namely django.utils.http.is_safe_url()) didn’t check if the scheme is http(s) and as such allowed javascript:...
URLs to be entered. If a developer relied on is_safe_url() to provide safe redirect targets and put such a URL into a link, they could suffer from a XSS attack. This bug doesn’t affect Django currently, since we only put this URL into the Location response header and browsers seem to ignore JavaScript there.
XSS vulnerability in django.contrib.admin
If a
is used in Django 1.5, it displays the current value of the field and a link to the target on the admin change page. The display routine of this widget was flawed and allowed for XSS.
Bugfixes
• Fixed a crash with
(#19607) as well as some pickle regressions with prefetch_related
(#20157 and #20257).
• Fixed a regression in
in the Google Map output on Python 3 (#20773).
• Made DjangoTestSuiteRunner.setup_databases properly handle aliases for the default database
(#19940) and prevented teardown_databases from attempting to tear down aliases (#20681).
1582 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
• Fixed the django.core.cache.backends.memcached.MemcachedCache
get_many() method on Python 3 (#20722).
backend’s
• Fixed
translation syntax errors. Affected languages: Mexican Spanish, Mongolian, Romanian, Turkish (#20695).
• Added support for wheel packages (#19252).
• The CSRF token now rotates when a user logs in.
• Some Python 3 compatibility fixes including #20212 and #20025.
• Fixed some rare cases where
exceptions recursed infinitely (#20278).
•
no longer crashes with UnicodeDecodeError (#20354).
• Fixed geojson detection with SpatiaLite.
•
once again works with binary content (#20237).
• Fixed
if it has a unicode name parameter (#20207).
• Ensured that the WSGI request’s path is correctly based on the SCRIPT_NAME environment variable or the
setting, regardless of whether or not either has a trailing slash (#20169).
• Fixed an obscure bug with the
decorator. If you hit an AttributeError:
'Settings' object has no attribute '_original_allowed_hosts' exception, it’s probably fixed (#20636).
Django 1.5.1 release notes
March 28, 2013
This is Django 1.5.1, a bugfix release for Django 1.5. It’s completely backwards compatible with Django 1.5, but includes a handful of fixes.
The biggest fix is for a memory leak introduced in Django 1.5. Under certain circumstances, repeated iteration over querysets could leak memory - sometimes quite a bit of it. If you’d like more information, the details are in our ticket tracker (and in a related issue in Python itself).
If you’ve noticed memory problems under Django 1.5, upgrading to 1.5.1 should fix those issues.
Django 1.5.1 also includes a couple smaller fixes:
• Module-level warnings emitted during tests are no longer silently hidden ( #18985 ).
• Prevented filtering on password hashes in the user admin ( #20078 ).
Django 1.5 release notes
February 26, 2013
Welcome to Django 1.5!
These release notes cover the
new features , as well as some
backwards incompatible changes
you’ll want to be aware of when upgrading from Django 1.4 or older versions. We’ve also dropped some features, which are detailed in
our deprecation plan , and we’ve
begun the deprecation process for some features .
9.1. Final releases 1583
Django Documentation, Release 2.0.dev20170914110741
Overview
The biggest new feature in Django 1.5 is the
configurable User model . Before Django 1.5, applications that wanted
to use Django’s auth framework ( django.contrib.auth
) were forced to use Django’s definition of a “user”. In
Django 1.5, you can now swap out the User model for one that you write yourself. This could be a simple extension to the existing User model – for example, you could add a Twitter or Facebook ID field – or you could completely replace the User with one totally customized for your site.
Django 1.5 is also the first release with
Python 3 support ! We’re labeling this support “experimental” because we
don’t yet consider it production-ready, but everything’s in place for you to start porting your apps to Python 3. Our next release, Django 1.6, will support Python 3 without reservations.
Other notable new features in Django 1.5 include:
•
Support for saving a subset of model’s fields
-
now accepts an update_fields argument, letting you specify which fields are written back to the database when you call save(). This can help in high-concurrency operations, and can improve performance.
• Better
support for streaming responses
via the new
response class.
•
now supports PostGIS 2.0.
• ... and more;
Wherever possible we try to introduce new features in a backwards-compatible manner per
However, as with previous releases, Django 1.5 ships with some minor
backwards incompatible changes ; people
upgrading from previous versions of Django should read that list carefully.
One deprecated feature worth noting is the shift to “new-style”
tag. Prior to Django 1.3, syntax like {% url myview %} was interpreted incorrectly (Django considered "myview" to be a literal name of a view, not a template variable named myview). Django 1.3 and above introduced the {% load url from future %} syntax to bring in the corrected behavior where myview was seen as a variable.
The upshot of this is that if you are not using {% load url from future %} in your templates, you’ll need to change tags like {% url myview %} to {% url "myview" %}. If you were using {% load url from future %} you can simply remove that line under Django 1.5
Python compatibility
Django 1.5 requires Python 2.6.5 or above, though we highly recommend Python 2.7.3 or above. Support for Python
2.5 and below has been dropped.
This change should affect only a small number of Django users, as most operating-system vendors today are shipping
Python 2.6 or newer as their default version. If you’re still using Python 2.5, however, you’ll need to stick to Django
1.4 until you can upgrade your Python version. Per
our support policy , Django 1.4 will continue to receive security
support until the release of Django 1.6.
Django 1.5 does not run on a Jython final release, because Jython’s latest release doesn’t currently support Python
2.6. However, Jython currently does offer an alpha release featuring 2.7 support, and Django 1.5 supports that alpha release.
Python 3 support
Django 1.5 introduces support for Python 3 - specifically, Python 3.2 and above. This comes in the form of a single codebase; you don’t need to install a different version of Django on Python 3. This means that you can write applications targeted for just Python 2, just Python 3, or single applications that support both platforms.
1584 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
However, we’re labeling this support “experimental” for now: although it’s received extensive testing via our automated test suite, it’s received very little real-world testing. We’ve done our best to eliminate bugs, but we can’t be sure we covered all possible uses of Django.
Some features of Django aren’t available because they depend on third-party software that hasn’t been ported to Python
3 yet, including:
• the MySQL database backend (depends on MySQLdb)
•
(depends on PIL)
•
(depends on Selenium WebDriver)
Further, Django’s more than a web framework; it’s an ecosystem of pluggable components. At this point, very few third-party applications have been ported to Python 3, so it’s unlikely that a real-world application will have all its dependencies satisfied under Python 3.
Thus, we’re recommending that Django 1.5 not be used in production under Python 3. Instead, use this opportunity to begin porting applications to Python 3. If you’re an author of a pluggable component, we encourage you to start porting now.
We plan to offer first-class, production-ready support for Python 3 in our next release, Django 1.6.
What’s new in Django 1.5
Configurable User model
In Django 1.5, you can now use your own model as the store for user-related data. If your project needs a username with more than 30 characters, or if you want to store user’s names in a format other than first name/last name, or you want to put custom profile information onto your User object, you can now do so.
If you have a third-party reusable application that references the User model, you may need to make some changes to the way you reference User instances. You should also document any specific features of the User model that your application relies upon.
See the
documentation on custom user models
for more details.
Support for saving a subset of model’s fields
The method
has a new keyword argument update_fields. By using this argument it is possible to save only a select list of model’s fields. This can be useful for performance reasons or when trying to avoid overwriting concurrent changes.
Deferred instances (those loaded by .only() or .defer()) will automatically save just the loaded fields. If any field is set manually after load, that field will also get updated on save.
See the
documentation for more details.
Caching of related model instances
When traversing relations, the ORM will avoid re-fetching objects that were previously loaded. For example, with the tutorial’s models:
>>> first_poll = Poll.objects.all()[ 0 ]
>>> first_choice = first_poll.choice_set.all()[ 0 ]
>>> first_choice.poll is first_poll
True
9.1. Final releases 1585
Django Documentation, Release 2.0.dev20170914110741
In Django 1.5, the third line no longer triggers a new SQL query to fetch first_choice.poll; it was set by the second line.
For one-to-one relationships, both sides can be cached. For many-to-one relationships, only the single side of the relationship can be cached. This is particularly helpful in combination with prefetch_related.
Explicit support for streaming responses
Before Django 1.5, it was possible to create a streaming response by passing an iterator to
was unreliable: any middleware that accessed the
attribute would consume the iterator prematurely.
You can now explicitly generate a streaming response with the new
class. This class exposes a
attribute which is an iterator.
Since
does not have a content attribute, middleware that needs access to the response content must test for streaming responses and behave accordingly.
{% verbatim %} template tag
To make it easier to deal with JavaScript templates which collide with Django’s syntax, you can now use the
block tag to avoid parsing the tag’s content.
Retrieval of ContentType instances associated with proxy models
The methods
ContentTypeManager.get_for_model()
and
have a new keyword argument – respectively for_concrete_model and for_concrete_models
. By passing False using this argument it is now possible to retrieve the
associated with proxy models.
New view variable in class-based views context
In all
(or any class-based view inheriting from ContextMixin), the context dictionary contains a view variable that points to the View instance.
GeoDjango
•
and
GEOS objects now support the
and
methods (so-called linear referencing).
• The wkb and hex properties of
objects preserve the Z dimension.
• Support for PostGIS 2.0 has been added and support for GDAL < 1.5 has been dropped.
New tutorials
Additions to the docs include a revamped
and a new
tutorial on testing . A new section, “Advanced Tutori-
als”, offers
as well as a step-by-step guide for new contributors in
Writing your first patch for Django
1586 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
Minor features
Django 1.5 also includes several smaller improvements worth noting:
• The template engine now interprets True, False and None as the corresponding Python objects.
•
provides a helper for converting aware datetimes between time zones. See
• The generic views support OPTIONS requests.
• Management commands do not raise SystemExit any more when called by code from
Any exception raised by the command (mostly
Moreover, when you output errors or messages in your custom commands, you should now use self.
stdout.write('message') and self.stderr.write('error') (see the note on
• The dumpdata management command outputs one row at a time, preventing out-of-memory errors when dumping large datasets.
• In the localflavor for Canada, “pq” was added to the acceptable codes for Quebec. It’s an old abbreviation.
• The
decorator is now able to connect to more than one signal by supplying a list of signals.
• In the admin, you can now filter users by groups which they are members of.
•
now has a batch_size argument. By default the batch_size is unlimited except for SQLite where single batch is limited so that 999 parameters per query isn’t exceeded.
• The
and
settings now also accept view function names and
documentation.
• Django now provides a mod_wsgi
• The
and
can now take fast-path in some cases. The fast-path allows for less queries and less objects fetched into memory. See
for details.
• An instance of ResolverMatch is stored on the request as resolver_match.
• By default, all logging messages reaching the django logger when
is True are sent to the console
(unless you redefine the logger in your
setting).
• When using
, it is now possible to look up permissions by using {% if 'someapp.
someperm' in perms %} in templates.
• It’s not required any more to have 404.html and 500.html templates in the root templates directory. Django will output some basic error messages for both situations when those templates are not found. Of course, it’s still recommended as good practice to provide those templates in order to present pretty error pages to the user.
•
provides a new signal that is emitted whenever a user fails to login successfully.
See
• The new
option ignore data for fields that no longer exist.
•
and
new assertions allow you to test equality for XML content at a semantic level, without caring for syntax differences (spaces, attribute order, etc.).
• RemoteUserMiddleware now forces logout when the REMOTE_USER header disappears during the same browser session.
• The
can store session data in a non-default cache.
9.1. Final releases 1587
Django Documentation, Release 2.0.dev20170914110741
• Multi-column indexes can now be created on models. Read the
documentation for more information.
• During Django’s logging configuration verbose Deprecation warnings are enabled and warnings are captured into the logging system. Logged warnings are routed through the console logging handler, which by default requires
to be True for output to be generated. The result is that DeprecationWarnings should be printed to the console in development environments the way they have been in Python versions < 2.7.
• The API for
django.contrib.admin.ModelAdmin.message_user()
method has been modified to accept additional arguments adding capabilities similar to
. This is useful for generating error messages from admin actions.
• The admin’s list filters can now be customized per-request thanks to the new
method.
Backwards incompatible changes in 1.5
Warning: In addition to the changes outlined in this section, be sure to review the
for any features that have been removed. If you haven’t updated your code within the deprecation timeline for a given feature, its removal may appear as a backwards incompatible change.
ALLOWED_HOSTS required in production
The new
setting validates the request’s Host header and protects against host-poisoning attacks.
This setting is now required whenever
is False, or else
django.http.HttpRequest.get_host()
will raise
for the new setting.
Managers on abstract models
Abstract models are able to define a custom manager, and that manager
exception will now be raised. Previously, the call would have been permitted, but would have failed as soon as any database operation was attempted (usually with a “table does not exist” error from the database).
If you have functionality on a manager that you have been invoking using the abstract class, you should migrate that logic to a Python staticmethod or classmethod on the abstract class.
Context in year archive class-based views
For consistency with the other date-based generic views,
now passes year in the context as a datetime.date
rather than a string. If you are using {{ year }} in your templates, you must replace it with
{{ year|date:"Y" }}
.
next_year and previous_year were also added in the context.
They are calculated according to allow_empty and allow_future.
Context in year and month archive class-based views
and
were documented to provide a date_list sorted in ascending order in the context, like their function-based predecessors, but it actually was in descending order. In 1.5, the doc-
1588 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
umented order was restored. You may want to add (or remove) the reversed keyword when you’re iterating on date_list in a template:
{% for date in date_list reversed
%
}
still provides a date_list in descending order.
Context in TemplateView
For consistency with the design of the other generic views,
no longer passes a params dictionary into the context, instead passing the variables from the URLconf directly into the context.
Non-form data in HTTP requests
will no longer include data posted via HTTP requests with non form-specific content-types in the header. In prior versions, data posted with content-types other than multipart/form-data or application/ x-www-form-urlencoded would still end up represented in the
attribute. Developers wishing to access the raw POST data for these cases, should use the
attribute instead.
request_finished signal
Django used to send the
signal as soon as the view function returned a response. This interacted badly with
that delay content generation.
This signal is now sent after the content is fully consumed by the WSGI gateway. This might be backwards incompatible if you rely on the signal being fired before sending the response content to the client. If you do, you should consider using
instead.
Note: Some WSGI servers and middleware do not always call close on the response object after handling a request, most notably uWSGI prior to 1.2.6 and Sentry’s error reporting middleware up to 2.0.7. In those cases the request_finished signal isn’t sent at all. This can result in idle connections to database and memcache servers.
OPTIONS, PUT and DELETE requests in the test client
Unlike GET and POST, these HTTP methods aren’t implemented by web browsers. Rather, they’re used in APIs, which transfer data in various formats such as JSON or XML. Since such requests may contain arbitrary data, Django doesn’t attempt to decode their body.
However, the test client used to build a query string for OPTIONS and DELETE requests like for GET, and a request body for PUT requests like for POST. This encoding was arbitrary and inconsistent with Django’s behavior when it receives the requests, so it was removed in Django 1.5.
If you were using the data parameter in an OPTIONS or a DELETE request, you must convert it to a query string and append it to the path parameter.
If you were using the data parameter in a PUT request without a content_type, you must encode your data before passing it to the test client and set the content_type argument.
9.1. Final releases 1589
Django Documentation, Release 2.0.dev20170914110741
System version of simplejson no longer used
As explained below , Django 1.5 deprecates django.utils.simplejson in favor of Python 2.6’s built-in
json module.
In theory, this change is harmless.
Unfortunately, because of incompatibilities between versions of simplejson , it may trigger errors in some circumstances.
JSON-related features in Django 1.4 always used django.utils.simplejson. This module was actually:
• A system version of simplejson, if one was available (ie. import simplejson works), if it was more recent than Django’s built-in copy or it had the C speedups, or
• The json module from the standard library, if it was available (ie. Python 2.6 or greater), or
• A built-in copy of version 2.0.7 of simplejson.
In Django 1.5, those features use Python’s json module, which is based on version 2.0.9 of simplejson.
There are no known incompatibilities between Django’s copy of version 2.0.7 and Python’s copy of version 2.0.9.
However, there are some incompatibilities between other versions of simplejson:
• While the simplejson API is documented as always returning unicode strings, the optional C implementation can return a byte string. This was fixed in Python 2.7.
• simplejson.JSONEncoder gained a namedtuple_as_object keyword argument in version 2.2.
More information on these incompatibilities is available in ticket #18023 .
The net result is that, if you have installed simplejson and your code uses Django’s serialization internals directly – for instance django.core.serializers.json.DjangoJSONEncoder, the switch from simplejson to json could break your code. (In general, changes to internals aren’t documented; we’re making an exception here.)
At this point, the maintainers of Django believe that using json from the standard library offers the strongest guarantee of backwards-compatibility. They recommend to use it from now on.
String types of hasher method parameters
If you have written a
custom password hasher , your encode(), verify() or safe_summary() methods should
accept Unicode parameters (password, salt or encoded). If any of the hashing methods need byte strings, you can use the
utility to encode the strings.
Validation of previous_page_number and next_page_number
When using
object pagination , the previous_page_number() and next_page_number() methods of the
object did not check if the returned number was inside the existing page range. It does check it now and raises an
exception when the number is either too low or too high.
Behavior of autocommit database option on PostgreSQL changed
PostgreSQL’s autocommit option didn’t work as advertised previously. It did work for single transaction block, but after the first block was left the autocommit behavior was never restored. This bug is now fixed in 1.5. While this is only a bug fix, it is worth checking your applications behavior if you are using PostgreSQL together with the autocommit option.
1590 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
Session not saved on 500 responses
Django’s session middleware will skip saving the session data if the response’s status code is 500.
Email checks on failed admin login
Prior to Django 1.5, if you attempted to log into the admin interface and mistakenly used your email address instead of your username, the admin interface would provide a warning advising that your email address was not your username.
In Django 1.5, the introduction of
has required the removal of this warning. This doesn’t change the login behavior of the admin site; it only affects the warning message that is displayed under one particular mode of login failure.
Changes in tests execution
Some changes have been introduced in the execution of tests that might be backward-incompatible for some testing setups:
Database flushing in django.test.TransactionTestCase
Previously, the test database was truncated before each test run in a
In order to be able to run unit tests in any order and to make sure they are always isolated from each other,
will now reset the database after each test run instead.
No more implicit DB sequences reset
tests used to reset primary key sequences automatically together with the database flushing actions described above.
This has been changed so no sequences are implicitly reset. This can cause
tests that depend on hard-coded primary key values to break.
The new
attribute can be used to force the old behavior for
that might need it.
Ordering of tests
In order to make sure all TestCase code starts with a clean database, tests are now executed in the following order:
• First, all unittests (including unittest.TestCase
,
and
) are run with no particular ordering guaranteed nor enforced among them.
• Then any other tests (e.g. doctests) that may alter the database without restoring it to its original state are run.
This should not cause any problems unless you have existing doctests which assume a
executed earlier left some database state behind or unit tests that rely on some form of state being preserved after the execution of other tests. Such tests are already very fragile, and must now be changed to be able to run independently.
9.1. Final releases 1591
Django Documentation, Release 2.0.dev20170914110741
cleaned_data dictionary kept for invalid forms
The
dictionary is now always present after form validation. When the form doesn’t validate, it contains only the fields that passed validation. You should test the success of the validation with the
method and not with the presence or absence of the
attribute on the form.
Behavior of syncdb with multiple databases
syncdb now queries the database routers to determine if content types (when
is enabled) and permissions (when
is enabled) should be created in the target database. Previously, it created them in the default database, even when another database was specified with the --database option.
If you use syncdb on multiple databases, you should ensure that your routers allow synchronizing content types and permissions to only one of them. See the docs on the
behavior of contrib apps with multiple databases
for more information.
XML deserializer will not parse documents with a DTD
In order to prevent exposure to denial-of-service attacks related to external entity references and entity expansion, the
XML model deserializer now refuses to parse XML documents containing a DTD (DOCTYPE definition). Since the
XML serializer does not output a DTD, this will not impact typical usage, only cases where custom-created XML documents are passed to Django’s model deserializer.
Formsets default max_num
A (default) value of None for the max_num argument to a formset factory no longer defaults to allowing any number of forms in the formset. Instead, in order to prevent memory-exhaustion attacks, it now defaults to a limit of 1000 forms. This limit can be raised by explicitly setting a higher value for max_num.
Miscellaneous
•
django.forms.ModelMultipleChoiceField
now returns an empty QuerySet as the empty value instead of an empty list.
•
properly raises a
TypeError instead of
ValueError for non-integer inputs.
• The slugify template filter is now available as a standard python function at
. Similarly, remove_tags is available at django.utils.html.remove_tags().
• Uploaded files are no longer created as executable by default. If you need them to be executable change
to your needs. The new default value is 0o666 (octal) and the current umask value is first masked out.
• The
supported bitwise operators by & and |. These operators are now available using .
bitand() and .bitor() instead. The removal of & and | was done to be consistent with
and QuerySet combining where the operators are used as boolean AND and OR operators.
• In a filter() call, when
contained lookups spanning multi-valued relations, they didn’t always reuse the same relations as other lookups along the same chain. This was changed, and now F() expressions will always use the same relations as other lookups within the same filter() call.
• The
template tag is no longer enclosed in a div. If you need HTML validation against pre-
HTML5 Strict DTDs, you should add a div around it in your pages.
1592 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
• The template tags library adminmedia, which only contained the deprecated template tag {% admin_media_prefix %}
, was removed. Attempting to load it with {% load adminmedia %} will fail. If your templates still contain that line you must remove it.
• Because of an implementation oversight, it was possible to use
without enabling
. This isn’t allowed any longer. If you’re using django.contrib.redirects, make
sure
contains django.contrib.sites.
•
now escapes its contents argument.
To avoid the HTML escaping, use
django.utils.safestring.mark_safe()
on the argument before passing it.
• Accessing reverse one-to-one relations fetched via
now raises
instead of returning None.
Features deprecated in 1.5
django.contrib.localflavor
The localflavor contrib app has been split into separate packages. django.contrib.localflavor itself will be removed in Django 1.6, after an accelerated deprecation.
The new packages are available on GitHub. The core team cannot efficiently maintain these packages in the long term
— it spans just a dozen countries at this time; similar to translations, maintenance will be handed over to interested members of the community.
django.contrib.markup
The markup contrib module has been deprecated and will follow an accelerated deprecation schedule. Direct use of
Python markup libraries or 3rd party tag libraries is preferred to Django maintaining this functionality in the framework.
AUTH_PROFILE_MODULE
With the introduction of
, there is no longer any need for a built-in mechanism to store user profile
data.
You can still define user profiles models that have a one-to-one relation with the User model - in fact, for many applications needing to associate data with a User account, this will be an appropriate design pattern to follow. However, the AUTH_PROFILE_MODULE setting, and the django.contrib.auth.models.User.get_profile() method for accessing the user profile model, should not be used any longer.
Streaming behavior of HttpResponse
Django 1.5 deprecates the ability to stream a response by passing an iterator to
behavior, switch to
Explicit support for streaming responses
above.
In Django 1.7 and above, the iterator will be consumed immediately by
9.1. Final releases 1593
Django Documentation, Release 2.0.dev20170914110741
django.utils.simplejson
Since Django 1.5 drops support for Python 2.5, we can now rely on the json module being available in Python’s standard library, so we’ve removed our own copy of simplejson. You should now import json instead of django.
utils.simplejson
.
Unfortunately, this change might have unwanted side-effects, because of incompatibilities between versions of simplejson
– see the
backwards-incompatible changes
section. If you rely on features added to simplejson after it became Python’s json
, you should import simplejson explicitly.
django.utils.encoding.StrAndUnicode
The django.utils.encoding.StrAndUnicode mix-in has been deprecated. Define a __str__ method and apply the
decorator instead.
django.utils.itercompat.product
The django.utils.itercompat.product function has been deprecated. Use the built-in itertools.
product() instead.
cleanup management command
The cleanup management command has been deprecated and replaced by
daily_cleanup.py
script
The undocumented daily_cleanup.py script has been deprecated. Use the
management command instead.
depth keyword argument in select_related
The depth keyword argument in
has been deprecated. You should use field names instead.
1.4 release
Django 1.4.22 release notes
August 18, 2015
Django 1.4.22 fixes a security issue in 1.4.21.
It also fixes support with pip 7+ by disabling wheel support. Older versions of 1.4 would silently build a broken wheel when installed with those versions of pip.
1594 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
Denial-of-service possibility in logout() view by filling session store
Previously, a session could be created when anonymously accessing the
view (provided it wasn’t decorated with
as done in the admin). This could allow an attacker to easily create many new session records by sending repeated requests, potentially filling up the session store or causing other users’ session records to be evicted.
The
has been modified to no longer create empty session records, including when
is active.
Additionally, the contrib.sessions.backends.base.SessionBase.flush() and cache_db.
SessionStore.flush() methods have been modified to avoid creating a new empty session. Maintainers of third-party session backends should check if the same vulnerability is present in their backend and correct it if so.
Django 1.4.21 release notes
July 8, 2015
Django 1.4.21 fixes several security issues in 1.4.20.
Denial-of-service possibility by filling session store
In previous versions of Django, the session backends created a new empty record in the session storage anytime request.session
was accessed and there was a session key provided in the request cookies that didn’t already have a session record. This could allow an attacker to easily create many new session records simply by sending repeated requests with unknown session keys, potentially filling up the session store or causing other users’ session records to be evicted.
The built-in session backends now create a session record only if the session is actually modified; empty session records are not created. Thus this potential DoS is now only possible if the site chooses to expose a session-modifying view to anonymous users.
As each built-in session backend was fixed separately (rather than a fix in the core sessions framework), maintainers of third-party session backends should check whether the same vulnerability is present in their backend and correct it if so.
Header injection possibility since validators accept newlines in input
Some of Django’s built-in validators (
, most seriously) didn’t prohibit newline characters (due to
the usage of $ instead of \Z in the regular expressions). If you use values with newlines in HTTP response or email headers, you can suffer from header injection attacks. Django itself isn’t vulnerable because
and the mail sending utilities in
prohibit newlines in HTTP and SMTP headers, respectively. While the validators have been fixed in Django, if you’re creating HTTP responses or email messages in other ways, it’s a good idea to ensure that those methods prohibit newlines as well. You might also want to validate that any existing data in your application doesn’t contain unexpected newlines.
and their usage in the corresponding form fields GenericIPAddresseField, IPAddressField, SlugField, and URLField are also affected.
The undocumented, internally unused validate_integer() function is now stricter as it validates using a regular expression instead of simply casting the value using int() and checking if an exception was raised.
9.1. Final releases 1595
Django Documentation, Release 2.0.dev20170914110741
Django 1.4.20 release notes
March 18, 2015
Django 1.4.20 fixes one security issue in 1.4.19.
Mitigated possible XSS attack via user-supplied redirect URLs
Django relies on user input in some cases (e.g.
django.contrib.auth.views.login()
and
to redirect the user to an “on success” URL. The security checks for these redirects (namely django.
utils.http.is_safe_url() ) accepted URLs with leading control characters and so considered URLs like
\x08javascript:...
safe. This issue doesn’t affect Django currently, since we only put this URL into the
Location response header and browsers seem to ignore JavaScript there. Browsers we tested also treat URLs prefixed with control characters such as %08//example.com as relative paths so redirection to an unsafe target isn’t a problem either.
However, if a developer relies on is_safe_url() to provide safe redirect targets and puts such a URL into a link, they could suffer from an XSS attack as some browsers such as Google Chrome ignore control characters at the start of a URL in an anchor href.
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 ).
Django 1.4.18 release notes
January 13, 2015
Django 1.4.18 fixes several security issues in 1.4.17 as well as a regression on Python 2.5 in the 1.4.17 release.
WSGI header spoofing via underscore/dash conflation
When HTTP headers are placed into the WSGI environ, they are normalized by converting to uppercase, converting all dashes to underscores, and prepending HTTP_. For instance, a header X-Auth-User would become
HTTP_X_AUTH_USER in the WSGI environ (and thus also in Django’s request.META dictionary).
Unfortunately, this means that the WSGI environ cannot distinguish between headers containing dashes and headers containing underscores: X-Auth-User and X-Auth_User both become HTTP_X_AUTH_USER. This means that if a header is used in a security-sensitive way (for instance, passing authentication information along from a front-end proxy), even if the proxy carefully strips any incoming value for X-Auth-User, an attacker may be able to provide an X-Auth_User header (with underscore) and bypass this protection.
In order to prevent such attacks, both Nginx and Apache 2.4+ strip all headers containing underscores from incoming requests by default. Django’s built-in development server now does the same. Django’s development server is not
1596 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
recommended for production use, but matching the behavior of common production servers reduces the surface area for behavior changes during deployment.
Mitigated possible XSS attack via user-supplied redirect URLs
Django relies on user input in some cases (e.g.
django.contrib.auth.views.login()
and
redirect the user to an “on success” URL. The security checks for these redirects (namely django.utils.
http.is_safe_url()
) didn’t strip leading whitespace on the tested URL and as such considered URLs like
\njavascript:...
safe. If a developer relied on is_safe_url() to provide safe redirect targets and put such a URL into a link, they could suffer from a XSS attack. This bug doesn’t affect Django currently, since we only put this URL into the Location response header and browsers seem to ignore JavaScript there.
Denial-of-service attack against django.views.static.serve
In older versions of Django, the
view read the files it served one line at a time. Therefore, a big file with no newlines would result in memory usage equal to the size of that file. An attacker could exploit this and launch a denial-of-service attack by simultaneously requesting many large files. This view now reads the file in chunks to prevent large memory usage.
Note, however, that this view has always carried a warning that it is not hardened for production use and should be used only as a development aid. Now may be a good time to audit your project and serve your files in production using a real front-end web server if you are not doing so.
Bugfixes
• To maintain compatibility with Python 2.5, Django’s vendored version of six, django.utils.six, has been downgraded to 1.8.0 which is the last version to support Python 2.5.
Django 1.4.17 release notes
January 2, 2015
Django 1.4.17 fixes a regression in the 1.4.14 security release.
Additionally, Django’s vendored version of six, django.utils.six, has been upgraded to the latest release
(1.9.0).
Bugfixes
• Fixed a regression with dynamically generated inlines and allowed field references in the admin ( #23754 ).
Django 1.4.16 release notes
October 22, 2014
Django 1.4.16 fixes a couple regressions in the 1.4.14 security release and a bug preventing the use of some GEOS versions with GeoDjango.
9.1. Final releases 1597
Django Documentation, Release 2.0.dev20170914110741
Bugfixes
• Allowed related many-to-many fields to be referenced in the admin ( #23604 ).
• Allowed inline and hidden references to admin fields ( #23431 ).
• Fixed parsing of the GEOS version string ( #20036 ).
Django 1.4.15 release notes
September 2, 2014
Django 1.4.15 fixes a regression in the 1.4.14 security release.
Bugfixes
• Allowed inherited and m2m fields to be referenced in the admin ( #22486 )
Django 1.4.14 release notes
August 20, 2014
Django 1.4.14 fixes several security issues in 1.4.13.
reverse() could generate URLs pointing to other hosts
In certain situations, URL reversing could generate scheme-relative URLs (URLs starting with two slashes), which could unexpectedly redirect a user to a different host. An attacker could exploit this, for example, by redirecting users to a phishing site designed to ask for user’s passwords.
To remedy this, URL reversing now ensures that no URL starts with two slashes (//), replacing the second slash with its
URL encoded counterpart (%2F). This approach ensures that semantics stay the same, while making the URL relative to the domain and not to the scheme.
File upload denial-of-service
Before this release, Django’s file upload handing in its default configuration may degrade to producing a huge number of os.stat() system calls when a duplicate filename is uploaded. Since stat() may invoke IO, this may produce a huge data-dependent slowdown that slowly worsens over time. The net result is that given enough time, a user with the ability to upload files can cause poor performance in the upload handler, eventually causing it to become very slow simply by uploading 0-byte files. At this point, even a slow network connection and few HTTP requests would be all that is necessary to make a site unavailable.
We’ve remedied the issue by changing the algorithm for generating file names if a file with the uploaded name already exists.
now appends an underscore plus a random 7 character alphanumeric string (e.g. "_x3a1gho"), rather than iterating through an underscore followed by a number (e.g. "_1", "_2", etc.).
1598 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
RemoteUserMiddleware session hijacking
When using the
and the RemoteUserBackend, a change to the REMOTE_USER header between requests without an intervening logout could result in the prior user’s session being co-opted by the subsequent user. The middleware now logs the user out on a failed login attempt.
Data leakage via query string manipulation in contrib.admin
In older versions of Django it was possible to reveal any field’s data by modifying the “popup” and “to_field” parameters of the query string on an admin change form page. For example, requesting a URL like /admin/auth/user/
?pop=1&t=password and viewing the page’s HTML allowed viewing the password hash of each user. While the admin requires users to have permissions to view the change form pages in the first place, this could leak data if you rely on users having access to view only certain fields on a model.
To address the issue, an exception will now be raised if a to_field value that isn’t a related field to a model that has been registered with the admin is specified.
Django 1.4.13 release notes
May 14, 2014
Django 1.4.13 fixes two security issues in 1.4.12.
Caches may incorrectly be allowed to store and serve private data
In certain situations, Django may allow caches to store private data related to a particular session and then serve that data to requests with a different session, or no session at all. This can lead to information disclosure and can be a vector for cache poisoning.
When using Django sessions, Django will set a Vary:
Cookie header to ensure caches do not serve cached data to requests from other sessions. However, older versions of Internet Explorer (most likely only Internet Explorer
6, and Internet Explorer 7 if run on Windows XP or Windows Server 2003) are unable to handle the Vary header in combination with many content types. Therefore, Django would remove the header if the request was made by
Internet Explorer.
To remedy this, the special behavior for these older Internet Explorer versions has been removed, and the Vary header is no longer stripped from the response. In addition, modifications to the Cache-Control header for all Internet
Explorer requests with a Content-Disposition header have also been removed as they were found to have similar issues.
Malformed redirect URLs from user input not correctly validated
The validation for redirects did not correctly validate some malformed URLs, which are accepted by some browsers.
This allows a user to be redirected to an unsafe URL unexpectedly.
Django relies on user input in some cases (e.g.
django.contrib.auth.views.login()
contrib.comments
, and
i18n ) to redirect the user to an “on success” URL. The security checks for these redirects
(namely django.utils.http.is_safe_url()) did not correctly validate some malformed URLs, such as http:\\\djangoproject.com
, which are accepted by some browsers with more liberal URL parsing.
To remedy this, the validation in is_safe_url() has been tightened to be able to handle and correctly validate these malformed URLs.
9.1. Final releases 1599
Django Documentation, Release 2.0.dev20170914110741
Django 1.4.12 release notes
April 28, 2014
Django 1.4.12 fixes a regression in the 1.4.11 security release.
Bugfixes
• Restored the ability to reverse() views created using functools.partial()
( #22486 ).
Django 1.4.11 release notes
April 21, 2014
Django 1.4.11 fixes three security issues in 1.4.10. Additionally, Django’s vendored version of six, django.utils.
six
, has been upgraded to the latest release (1.6.1).
Unexpected code execution using reverse()
Django’s URL handling is based on a mapping of regex patterns (representing the URLs) to callable views, and
Django’s own processing consists of matching a requested URL against those patterns to determine the appropriate view to invoke.
Django also provides a convenience function – reverse() – which performs this process in the opposite direction.
The reverse() function takes information about a view and returns a URL which would invoke that view. Use of reverse() is encouraged for application developers, as the output of reverse() is always based on the current
URL patterns, meaning developers do not need to change other code when making changes to URLs.
One argument signature for reverse() is to pass a dotted Python path to the desired view. In this situation, Django will import the module indicated by that dotted path as part of generating the resulting URL. If such a module has import-time side effects, those side effects will occur.
Thus it is possible for an attacker to cause unexpected code execution, given the following conditions:
1. One or more views are present which construct a URL based on user input (commonly, a “next” parameter in a querystring indicating where to redirect upon successful completion of an action).
2. One or more modules are known to an attacker to exist on the server’s Python import path, which perform code execution with side effects on importing.
To remedy this, reverse() will now only accept and import dotted paths based on the view-containing modules listed in the project’s
, so as to ensure that only modules the developer intended to be
imported in this fashion can or will be imported.
Caching of anonymous pages could reveal CSRF token
Django includes both a
and a system for
preventing cross-site request forgery (CSRF) attacks . The
CSRF-protection system is based on a random nonce sent to the client in a cookie which must be sent by the client on future requests and, in forms, a hidden value which must be submitted back with the form.
The caching framework includes an option to cache responses to anonymous (i.e., unauthenticated) clients.
When the first anonymous request to a given page is by a client which did not have a CSRF cookie, the cache framework will also cache the CSRF cookie and serve the same nonce to other anonymous clients who do not have a CSRF
1600 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
cookie. This can allow an attacker to obtain a valid CSRF cookie value and perform attacks which bypass the check for the cookie.
To remedy this, the caching framework will no longer cache such responses. The heuristic for this will be:
1. If the incoming request did not submit any cookies, and
2. If the response did send one or more cookies, and
3. If the Vary:
Cookie header is set on the response, then the response will not be cached.
MySQL typecasting
The MySQL database is known to “typecast” on certain queries; for example, when querying a table which contains string values, but using a query which filters based on an integer value, MySQL will first silently coerce the strings to integers and return a result based on that.
If a query is performed without first converting values to the appropriate type, this can produce unexpected results, similar to what would occur if the query itself had been manipulated.
Django’s model field classes are aware of their own types and most such classes perform explicit conversion of query arguments to the correct database-level type before querying. However, three model field classes did not correctly convert their arguments:
•
•
• IPAddressField
These three fields have been updated to convert their arguments to the correct types before querying.
Additionally, developers of custom model fields are now warned via documentation to ensure their custom field classes will perform appropriate type conversions, and users of the
and
query methods – which allow the developer to supply raw SQL or SQL fragments – will be advised to ensure they perform appropriate manual type conversions prior to executing queries.
Django 1.4.10 release notes
November 6, 2013
Django 1.4.10 fixes a Python-compatibility bug in the 1.4 series.
Python compatibility
Django 1.4.9 inadvertently introduced issues with Python 2.5 compatibility. Django 1.4.10 restores Python 2.5 compatibility. This was issue #21362 in Django’s Trac.
Django 1.4.9 release notes
October 23, 2013
Django 1.4.9 fixes a security-related bug in the 1.4 series and one other data corruption bug.
9.1. Final releases 1601
Django Documentation, Release 2.0.dev20170914110741
Readdressed denial-of-service via password hashers
Django 1.4.8 imposes a 4096-byte limit on passwords in order to mitigate a denial-of-service attack through submission of bogus but extremely large passwords. In Django 1.4.9, we’ve reverted this change and instead improved the speed of our PBKDF2 algorithm by not rehashing the key on every iteration.
Bugfixes
• Fixed a data corruption bug with datetime_safe.datetime.combine (#21256).
Django 1.4.8 release notes
September 14, 2013
Django 1.4.8 fixes two security issues present in previous Django releases in the 1.4 series.
Denial-of-service via password hashers
In previous versions of Django, no limit was imposed on the plaintext length of a password. This allowed a denial-ofservice attack through submission of bogus but extremely large passwords, tying up server resources performing the
(expensive, and increasingly expensive with the length of the password) calculation of the corresponding hash.
As of 1.4.8, Django’s authentication framework imposes a 4096-byte limit on passwords and will fail authentication with any submitted password of greater length.
Corrected usage of sensitive_post_parameters() in django.contrib.auth’s admin
The decoration of the add_view and user_change_password user admin views with
did not include
(required since the views are methods) resulting in the decorator not being properly applied.
This usage has been fixed and
will now throw an exception if it’s improperly used.
Django 1.4.7 release notes
September 10, 2013
Django 1.4.7 fixes one security issue present in previous Django releases in the 1.4 series.
Directory traversal vulnerability in ssi template tag
In previous versions of Django it was possible to bypass the ALLOWED_INCLUDE_ROOTS setting used for security with the ssi template tag by specifying a relative path that starts with one of the allowed roots. For example, if
ALLOWED_INCLUDE_ROOTS = ("/var/www",) the following would be possible:
{% ssi
"/var/www/../../etc/passwd"
%}
In practice this is not a very common problem, as it would require the template author to put the ssi file in a usercontrolled variable, but it’s possible in principle.
1602 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
Django 1.4.6 release notes
August 13, 2013
Django 1.4.6 fixes one security issue present in previous Django releases in the 1.4 series, as well as one other bug.
This is the sixth bugfix/security release in the Django 1.4 series.
Mitigated possible XSS attack via user-supplied redirect URLs
Django relies on user input in some cases (e.g.
django.contrib.auth.views.login()
contrib.comments
, and
i18n ) to redirect the user to an “on success” URL. The security checks for these redirects
(namely django.utils.http.is_safe_url()) didn’t check if the scheme is http(s) and as such allowed javascript:...
URLs to be entered. If a developer relied on is_safe_url() to provide safe redirect targets and put such a URL into a link, they could suffer from a XSS attack. This bug doesn’t affect Django currently, since we only put this URL into the Location response header and browsers seem to ignore JavaScript there.
Bugfixes
• Fixed an obscure bug with the
decorator. If you hit an AttributeError:
'Settings' object has no attribute '_original_allowed_hosts' exception, it’s probably fixed (#20636).
Django 1.4.5 release notes
February 20, 2013
Django 1.4.5 corrects a packaging problem with yesterday’s
The release contained stray .pyc files that caused “bad magic number” errors when running with some versions of
Python. This releases corrects this, and also fixes a bad documentation link in the project template settings.py
file generated by manage.py startproject.
Django 1.4.4 release notes
February 19, 2013
Django 1.4.4 fixes four security issues present in previous Django releases in the 1.4 series, as well as several other bugs and numerous documentation improvements.
This is the fourth bugfix/security release in the Django 1.4 series.
Host header poisoning
Some parts of Django – independent of end-user-written applications – make use of full URLs, including domain name, which are generated from the HTTP Host header. Django’s documentation has for some time contained notes advising users on how to configure Web servers to ensure that only valid Host headers can reach the Django application. However, it has been reported to us that even with the recommended Web server configurations there are still techniques available for tricking many common Web servers into supplying the application with an incorrect and possibly malicious Host header.
For this reason, Django 1.4.4 adds a new setting, ALLOWED_HOSTS, containing an explicit list of valid host/domain names for this site.
A request with a Host header not matching an entry in this list will raise
9.1. Final releases 1603
Django Documentation, Release 2.0.dev20170914110741
SuspiciousOperation if request.get_host() is called. For full details see the documentation for the
setting.
The default value for this setting in Django 1.4.4 is ['*'] (matching any host), for backwards-compatibility, but we strongly encourage all sites to set a more restrictive value.
This host validation is disabled when DEBUG is True or when running tests.
XML deserialization
The XML parser in the Python standard library is vulnerable to a number of attacks via external entities and entity expansion. Django uses this parser for deserializing XML-formatted database fixtures. This deserializer is not intended for use with untrusted data, but in order to err on the side of safety in Django 1.4.4 the XML deserializer refuses to parse an XML document with a DTD (DOCTYPE definition), which closes off these attack avenues.
These issues in the Python standard library are CVE-2013-1664 and CVE-2013-1665. More information available from the Python security team .
Django’s XML serializer does not create documents with a DTD, so this should not cause any issues with the typical round-trip from dumpdata to loaddata, but if you feed your own XML documents to the loaddata management command, you will need to ensure they do not contain a DTD.
Formset memory exhaustion
Previous versions of Django did not validate or limit the form-count data provided by the client in a formset’s management form, making it possible to exhaust a server’s available memory by forcing it to create very large numbers of forms.
In Django 1.4.4, all formsets have a strictly-enforced maximum number of forms (1000 by default, though it can be set higher via the max_num formset factory argument).
Admin history view information leakage
In previous versions of Django, an admin user without change permission on a model could still view the unicode representation of instances via their admin history log. Django 1.4.4 now limits the admin history log view for an object to users with change permission for that model.
Other bugfixes and changes
• Prevented transaction state from leaking from one request to the next (#19707).
• Changed an SQL command syntax to be MySQL 4 compatible (#19702).
• Added backwards-compatibility with old unsalted MD5 passwords (#18144).
• Numerous documentation improvements and fixes.
Django 1.4.3 release notes
December 10, 2012
Django 1.4.3 addresses two security issues present in previous Django releases in the 1.4 series.
1604 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
Please be aware that this security release is slightly different from previous ones. Both issues addressed here have been dealt with in prior security updates to Django. In one case, we have received ongoing reports of problems, and in the other we’ve chosen to take further steps to tighten up Django’s code in response to independent discovery of potential problems from multiple sources.
Host header poisoning
Several earlier Django security releases focused on the issue of poisoning the HTTP Host header, causing Django to generate URLs pointing to arbitrary, potentially-malicious domains.
In response to further input received and reports of continuing issues following the previous release, we’re taking additional steps to tighten Host header validation. Rather than attempt to accommodate all features HTTP supports here, Django’s Host header validation attempts to support a smaller, but far more common, subset:
• Hostnames must consist of characters [A-Za-z0-9] plus hyphen (‘-‘) or dot (‘.’).
• IP addresses – both IPv4 and IPv6 – are permitted.
• Port, if specified, is numeric.
Any deviation from this will now be rejected, raising the exception
Redirect poisoning
Also following up on a previous issue: in July of this year, we made changes to Django’s HTTP redirect classes, performing additional validation of the scheme of the URL to redirect to (since, both within Django’s own supplied applications and many third-party applications, accepting a user-supplied redirect target is a common pattern).
Since then, two independent audits of the code turned up further potential problems. So, similar to the Host-header issue, we are taking steps to provide tighter validation in response to reported problems (primarily with third-party applications, but to a certain extent also within Django itself). This comes in two parts:
1. A new utility function, django.utils.http.is_safe_url, is added; this function takes a URL and a hostname, and checks that the URL is either relative, or if absolute matches the supplied hostname. This function is intended for use whenever user-supplied redirect targets are accepted, to ensure that such redirects cannot lead to arbitrary third-party sites.
2. All of Django’s own built-in views – primarily in the authentication system – which allow user-supplied redirect targets now use is_safe_url to validate the supplied URL.
Django 1.4.2 release notes
October 17, 2012
This is the second security release in the Django 1.4 series.
Host header poisoning
Some parts of Django – independent of end-user-written applications – make use of full URLs, including domain name, which are generated from the HTTP Host header. Some attacks against this are beyond Django’s ability to control, and require the web server to be properly configured; Django’s documentation has for some time contained notes advising users on such configuration.
9.1. Final releases 1605
Django Documentation, Release 2.0.dev20170914110741
Django’s own built-in parsing of the Host header is, however, still vulnerable, as was reported to us recently. The Host header parsing in Django 1.3.3 and Django 1.4.1 – specifically, django.http.HttpRequest.get_host() – was incorrectly handling username/password information in the header. Thus, for example, the following Host header would be accepted by Django when running on “validsite.com”:
Host: validsite.com:random@evilsite.com
Using this, an attacker can cause parts of Django – particularly the password-reset mechanism – to generate and display arbitrary URLs to users.
To remedy this, the parsing in HttpRequest.get_host() is being modified; Host headers which contain potentially dangerous content (such as username/password pairs) now raise the exception
Details of this issue were initially posted online as a security advisory .
Backwards incompatible changes
• The newly introduced
constructor arguments have been adapted to match those of all other model fields. The first two keyword arguments are now verbose_name and name.
Other bugfixes and changes
• Subclass HTMLParser only for appropriate Python versions (#18239).
• Added batch_size argument to qs.bulk_create() (#17788).
• Fixed a small regression in the admin filters where wrongly formatted dates passed as url parameters caused an unhandled ValidationError (#18530).
• Fixed an endless loop bug when accessing permissions in templates (#18979)
• Fixed some Python 2.5 compatibility issues
• Fixed an issue with quoted filenames in Content-Disposition header (#19006)
• Made the context option in trans and blocktrans tags accept literals wrapped in single quotes (#18881).
• Numerous documentation improvements and fixes.
Django 1.4.1 release notes
July 30, 2012
This is the first security release in the Django 1.4 series, fixing several security issues in Django 1.4. Django 1.4.1 is a recommended upgrade for all users of Django 1.4.
For a full list of issues addressed in this release, see the security advisory .
Django 1.4 release notes
March 23, 2012
Welcome to Django 1.4!
These release notes cover the
new features , as well as some
backwards incompatible changes
you’ll want to be aware of when upgrading from Django 1.3 or older versions. We’ve also dropped some features, which are detailed in
our deprecation plan , and we’ve
begun the deprecation process for some features .
1606 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
Overview
The biggest new feature in Django 1.4 is
when handling date/times. When enabled, this Django will store date/times in UTC, use timezone-aware objects internally, and translate them to users’ local timezones for display.
If you’re upgrading an existing project to Django 1.4, switching to the timezone aware mode may take some care: the new mode disallows some rather sloppy behavior that used to be accepted. We encourage anyone who’s upgrading to check out the
and the
for useful pointers.
Other notable new features in Django 1.4 include:
• A number of ORM improvements, including
SELECT FOR UPDATE support , the ability to
large datasets for improved performance, and
, a method to batch-load related objects in
areas where
doesn’t work.
• Some nice security additions, including
(featuring PBKDF2 and bcrypt support), new
tools for cryptographic signing , several
CSRF improvements , and simple clickjacking protection .
• An
updated default project layout and manage.py
that removes the “magic” from prior versions. And for those who don’t like the new layout, you can use
custom project and app templates
instead!
•
Support for in-browser testing frameworks
(like Selenium ).
• ... and a whole lot more;
Wherever possible we try to introduce new features in a backwards-compatible manner per
policy. However, as with previous releases, Django 1.4 ships with some minor
backwards incompatible changes ;
people upgrading from previous versions of Django should read that list carefully.
Python compatibility
Django 1.4 has dropped support for Python 2.4. Python 2.5 is now the minimum required Python version. Django is tested and supported on Python 2.5, 2.6 and 2.7.
This change should affect only a small number of Django users, as most operating-system vendors today are shipping
Python 2.5 or newer as their default version. If you’re still using Python 2.4, however, you’ll need to stick to Django
1.3 until you can upgrade. Per
our support policy , Django 1.3 will continue to receive security support until the release
of Django 1.5.
Django does not support Python 3.x at this time. At some point before the release of Django 1.4, we plan to publish a document outlining our full timeline for deprecating Python 2.x and moving to Python 3.x.
What’s new in Django 1.4
Support for time zones
In previous versions, Django used “naive” date/times (that is, date/times without an associated time zone), leaving it up to each developer to interpret what a given date/time “really means”. This can cause all sorts of subtle timezone-related bugs.
In Django 1.4, you can now switch Django into a more correct, time-zone aware mode. In this mode, Django stores date and time information in UTC in the database, uses time-zone-aware datetime objects internally and translates them to the end user’s time zone in templates and forms. Reasons for using this feature include:
• Customizing date and time display for users around the world.
9.1. Final releases 1607
Django Documentation, Release 2.0.dev20170914110741
• Storing datetimes in UTC for database portability and interoperability. (This argument doesn’t apply to PostgreSQL, because it already stores timestamps with time zone information in Django 1.3.)
• Avoiding data corruption problems around DST transitions.
Time zone support is enabled by default in new projects created with
startproject . If you want to use this feature
in an existing project, read the
. If you encounter problems, there’s a helpful
Support for in-browser testing frameworks
Django 1.4 supports integration with in-browser testing frameworks like Selenium . The new
base class lets you test the interactions between your site’s front and back ends more comprehensively. See the
for more details and concrete examples.
Updated default project layout and manage.py
Django 1.4 ships with an updated default project layout and manage.py file for the
management command. These fix some issues with the previous manage.py handling of Python import paths that caused double imports, trouble moving from development to deployment, and other difficult-to-debug path issues.
The previous manage.py called functions that are now deprecated, and thus projects upgrading to Django 1.4 should update their manage.py. (The old-style manage.py will continue to work as before until Django 1.6. In 1.5 it will raise DeprecationWarning).
The new recommended manage.py file should look like this:
#!/usr/bin/env python
import
os
,
sys
if
__name__
==
"__main__" : os.environ.setdefault( "DJANGO_SETTINGS_MODULE" , "{{ project_name }}.settings" )
from
django.core.management
import
execute_from_command_line execute_from_command_line(sys.argv)
{{ project_name }} should be replaced with the Python package name of the actual project.
If settings, URLconfs and apps within the project are imported or referenced using the project name prefix (e.g.
myproject.settings
, ROOT_URLCONF = "myproject.urls", etc.), the new manage.py will need to be moved one directory up, so it is outside the project package rather than adjacent to settings.py and urls.py.
For instance, with the following layout: manage.py mysite/
__init__ .
py settings.py urls.py myapp/
__init__ .
py models.py
You could import mysite.settings, mysite.urls, and mysite.myapp, but not settings, urls, or myapp as top-level modules.
1608 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
Anything imported as a top-level module can be placed adjacent to the new manage.py. For instance, to decouple
“myapp” from the project module and import it as just myapp, place it outside the mysite/ directory: manage.py myapp/
__init__ .
py models.py mysite/
__init__ .
py settings.py urls.py
If the same code is imported inconsistently (some places with the project prefix, some places without it), the imports will need to be cleaned up when switching to the new manage.py.
Custom project and app templates
The
and
management commands now have a --template option for specifying a path or URL to a custom app or project template.
For example, Django will use the /path/to/my_project_template directory when you run the following command: django-admin.py startproject --template=/path/to/my_project_template myproject
You can also now provide a destination directory as the second argument to both
and
django-admin.py startapp myapp /path/to/new/app django-admin.py startproject myproject /path/to/new/project
For more information, see the
and
documentation.
Improved WSGI support
The
management command now adds a wsgi.py module to the initial project layout, containing a simple WSGI application that can be used for
deploying with WSGI app servers .
The
now supports using an externally-defined WSGI callable, which makes it possible to run runserver with the same WSGI configuration that is used for deployment.
The new
setting lets you configure which WSGI callable
uses.
(The runfcgi management command also internally wraps the WSGI callable configured via
SELECT FOR UPDATE support
Django 1.4 includes a
method, which generates a SELECT ... FOR
UPDATE
SQL query. This will lock rows until the end of the transaction, meaning other transactions cannot modify or delete rows matched by a FOR UPDATE query.
For more details, see the documentation for
9.1. Final releases 1609
Django Documentation, Release 2.0.dev20170914110741
Model.objects.bulk_create
in the ORM
This method lets you create multiple objects more efficiently. It can result in significant performance increases if you have many objects.
Django makes use of this internally, meaning some operations (such as database setup for test suites) have seen a performance benefit as a result.
See the
docs for more information.
QuerySet.prefetch_related
Similar to
but with a different strategy and broader scope,
has been added to
. This method returns a new QuerySet that will prefetch each of the specified related
lookups in a single batch as soon as the query begins to be evaluated. Unlike select_related, it does the joins in Python, not in the database, and supports many-to-many relationships, GenericForeignKey and more. This allows you to fix a very common performance problem in which your code ends up doing O(n) database queries (or worse) if objects on your primary QuerySet each have many related objects that you also need to fetch.
Improved password hashing
Django’s auth system (django.contrib.auth) stores passwords using a one-way algorithm. Django 1.3 uses the SHA1 algorithm, but increasing processor speeds and theoretical attacks have revealed that SHA1 isn’t as secure as we’d like. Thus, Django 1.4 introduces a new password storage system: by default Django now uses the PBKDF2 algorithm (as recommended by NIST ). You can also easily choose a different algorithm (including the popular bcrypt algorithm). For more details, see
HTML5 doctype
We’ve switched the admin and other bundled templates to use the HTML5 doctype. While Django will be careful to maintain compatibility with older browsers, this change means that you can use any HTML5 features you need in admin pages without having to lose HTML validity or override the provided templates to change the doctype.
List filters in admin interface
Prior to Django 1.4, the
app let you specify change list filters by specifying a field lookup, but it didn’t allow you to create custom filters. This has been rectified with a simple API (previously used internally and known as
“FilterSpec”). For more details, see the documentation for
Multiple sort in admin interface
The admin change list now supports sorting on multiple columns. It respects all elements of the
attribute, and sorting on multiple columns by clicking on headers is designed to mimic the behavior of desktop GUIs. We also added a
method for specifying the ordering dynamically (i.e., depending on the request).
New ModelAdmin methods
We added a
method to
to ease customization of how related objects are saved in the admin.
1610 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
Two other new
methods,
and
enable dynamic customization of fields and links displayed on the admin change list.
Admin inlines respect user permissions
Admin inlines now only allow those actions for which the user has permission. For ManyToMany relationships with an auto-created intermediate model (which does not have its own permissions), the change permission for the related model determines if the user has the permission to add, change or delete relationships.
Tools for cryptographic signing
Django 1.4 adds both a low-level API for signing values and a high-level API for setting and reading signed cookies, one of the most common uses of signing in Web applications.
See the
docs for more information.
Cookie-based session backend
Django 1.4 introduces a cookie-based session backend that uses the tools for
to store the session data in the client’s browser.
Warning: Session data is signed and validated by the server, but it’s not encrypted. This means a user can view any data stored in the session but cannot change it. Please read the documentation for further clarification before using this backend.
See the
docs for more information.
New form wizard
The previous FormWizard from django.contrib.formtools has been replaced with a new implementation based on the class-based views introduced in Django 1.3. It features a pluggable storage API and doesn’t require the wizard to pass around hidden fields for every previous step.
Django 1.4 ships with a session-based storage backend and a cookie-based storage backend. The latter uses the tools for
also introduced in Django 1.4 to store the wizard’s state in the user’s cookies.
reverse_lazy
A lazily evaluated version of reverse() was added to allow using URL reversals before the project’s URLconf gets loaded.
Translating URL patterns
Django can now look for a language prefix in the URLpattern when using the new
helper function. It’s also now possible to define translatable URL patterns using
Internationalization: in URL patterns
for more information about the language prefix and how to internationalize URL patterns.
9.1. Final releases 1611
Django Documentation, Release 2.0.dev20170914110741
Contextual translation support for {% trans %} and {% blocktrans %}
The
support introduced in Django 1.3 via the pgettext function has been extended to the
and
template tags using the new context keyword.
Customizable SingleObjectMixin URLConf kwargs
Two new attributes,
and
to enable the customization of URLconf keyword arguments used for single object generic views.
Assignment template tags
A new assignment_tag helper function was added to template.Library to ease the creation of template tags that store data in a specified context variable.
*args and **kwargs support for template tag helper functions
The
and newly introduced assignment_tag template helper functions may now accept any number of positional or keyword arguments. For example:
@register.simple_tag
def my_tag
(a, b, *args, **kwargs): warning = kwargs[ 'warning' ] profile = kwargs[ 'profile' ]
...
return ...
Then, in the template, any number of arguments may be passed to the template tag. For example:
{% my_tag
123 "abcd" book.title warning
=
message
| lower
profile
=
user.profile
%}
No wrapping of exceptions in TEMPLATE_DEBUG mode
In previous versions of Django, whenever the TEMPLATE_DEBUG setting was True, any exception raised during template rendering (even exceptions unrelated to template syntax) were wrapped in TemplateSyntaxError and re-raised. This was done in order to provide detailed template source location information in the debug 500 page.
In Django 1.4, exceptions are no longer wrapped. Instead, the original exception is annotated with the source information. This means that catching exceptions from template rendering is now consistent regardless of the value of
TEMPLATE_DEBUG
, and there’s no need to catch and unwrap TemplateSyntaxError in order to catch other errors.
truncatechars template filter
This new filter truncates a string to be no longer than the specified number of characters. Truncated strings end with a translatable ellipsis sequence (”...”). See the documentation for
for more details.
1612 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
static template tag
The
contrib app has a new static template tag to refer to files saved with the
storage backend. It uses the storage backend’s url method and therefore supports advanced features such as
serving files from a cloud service .
CachedStaticFilesStorage storage backend
The
contrib app now has a
backend that caches the files it saves
(when running the
management command) by appending the MD5 hash of the file’s content to the filename. For example, the file css/styles.css would also be saved as css/styles.55e7cbb9ba48.css
See the
docs for more information.
Simple clickjacking protection
We’ve added a middleware to provide easy protection against clickjacking using the X-Frame-Options header.
It’s not enabled by default for backwards compatibility reasons, but you’ll almost certainly want to
to help plug that security hole for browsers that support the header.
CSRF improvements
We’ve made various improvements to our CSRF features, including the
decorator, which can help with AJAX-heavy sites; protection for PUT and DELETE requests; and the
and
settings, which can improve the security and usefulness of CSRF protection. See the
for more information.
Error report filtering
We added two function decorators,
and
sensitive_post_parameters() , to
allow designating the local variables and POST parameters that may contain sensitive information and should be filtered out of error reports.
All POST parameters are now systematically filtered out of error reports for certain views (login, password_reset_confirm
, password_change and add_view in
well as user_change_password in the admin app) to prevent the leaking of sensitive information such as user passwords.
You can override or customize the default filtering by writing a
custom filter . For more information see the docs on
Extended IPv6 support
Django 1.4 can now better handle IPv6 addresses with the new
model field,
form field and the validators
and
9.1. Final releases 1613
Django Documentation, Release 2.0.dev20170914110741
HTML comparisons in tests
The base classes in
now have some helpers to compare HTML without tripping over irrelevant differences in whitespace, argument quoting/ordering and closing of self-closing tags. You can either compare HTML directly with the new
and
assertions, or use the html=True flag with
and
to test whether the client’s response contains a given HTML fragment. See the
for more.
Two new date format strings
Two new
formats were added for use in template filters, template tags and
• e – the name of the timezone of the given datetime object
• o – the ISO 8601 year number
Please make sure to update your
if they contain either e or o in a format string. For example a
Spanish localization format previously only escaped the d format character:
DATE_FORMAT = r'j \de F \de Y'
But now it needs to also escape e and o:
DATE_FORMAT = r'j \d\e F \d\e Y'
For more information, see the
documentation.
Minor features
Django 1.4 also includes several smaller improvements worth noting:
• A more usable stacktrace in the technical 500 page. Frames in the stack trace that reference Django’s framework code are dimmed out, while frames in application code are slightly emphasized. This change makes it easier to scan a stacktrace for issues in application code.
•
in PostgreSQL.
• Customizable names for
• In the documentation, a helpful
page.
• The django.contrib.auth.models.check_password function has been moved to the
module. Importing it from the old location will still work, but you should update your imports.
• The
management command now has a --clear option to delete all files at the destination before copying or linking the static files.
• It’s now possible to load fixtures containing forward references when using MySQL with the InnoDB database engine.
• A new 403 response handler has been added as 'django.views.defaults.permission_denied'.
You can set your own handler by setting the value of
mentation about
for more information.
• The
command uses a new and more accurate lexer, JsLex , for extracting translatable strings from JavaScript files.
1614 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
• The
template tag now takes an optional as argument to be able to retrieve a translation string without displaying it but setting a template context variable instead.
• The
template tag now supports {% elif %} clauses.
• If your Django app is behind a proxy, you might find the new
setting useful.
It solves the problem of your proxy “eating” the fact that a request came in via HTTPS. But only use this setting if you know what you’re doing.
• A new, plain-text, version of the HTTP 500 status code internal error page served when
is True is now
is used for this.)
Like its HTML counterpart, it contains a collection of different pieces of information about the state of the application.
This should make it easier to read when debugging interaction with client-side JavaScript.
• Added the
option.
• Changed the locmem cache backend to use pickle.HIGHEST_PROTOCOL for better compatibility with the other cache backends.
• Added support in the ORM for generating SELECT queries containing DISTINCT ON.
The distinct() QuerySet method now accepts an optional list of model field names. If specified, then the
DISTINCT statement is limited to these fields. This is only supported in PostgreSQL.
For more details, see the documentation for
• The admin login page will add a password reset link if you include a URL with the name ‘admin_password_reset’ in your urls.py, so plugging in the built-in password reset mechanism and making it available is now much easier. For details, see
Adding a password reset feature .
• The MySQL database backend can now make use of the savepoint feature implemented by MySQL version
5.0.3 or newer with the InnoDB storage engine.
• It’s now possible to pass initial values to the model forms that are part of both model formsets and inline model formsets as returned from factory functions modelformset_factory and inlineformset_factory respectively just like with regular formsets. However, initial values only apply to extra forms, i.e. those which are not bound to an existing model instance.
• The sitemaps framework can now handle HTTPS links using the new
class attribute.
• A new
subclass of unittest.TestCase
that’s lighter than
and company. It can be useful in tests that don’t need to hit a database. See
Hierarchy of Django unit testing classes .
Backwards incompatible changes in 1.4
SECRET_KEY setting is required
Running Django with an empty or known
disables many of Django’s security protections and can lead to remote-code-execution vulnerabilities. No Django site should ever be run without a
In Django 1.4, starting Django with an empty
will raise a DeprecationWarning. In Django 1.5, it will raise an exception and Django will refuse to start. This is slightly accelerated from the usual deprecation path due to the severity of the consequences of running Django with no
9.1. Final releases 1615
Django Documentation, Release 2.0.dev20170914110741
django.contrib.admin
The included administration app django.contrib.admin has for a long time shipped with a default set of static files such as JavaScript, images and stylesheets. Django 1.3 added a new contrib app django.contrib.
staticfiles to handle such files in a generic way and defined conventions for static files included in apps.
Starting in Django 1.4, the admin’s static files also follow this convention, to make the files easier to deploy. In previous versions of Django, it was also common to define an ADMIN_MEDIA_PREFIX setting to point to the URL where the admin’s static files live on a Web server. This setting has now been deprecated and replaced by the more general setting
. Django will now expect to find the admin static files under the URL <STATIC_URL>/admin/.
If you’ve previously used a URL path for ADMIN_MEDIA_PREFIX (e.g.
/media/
) simply make sure
and
are configured and your Web server serves those files correctly. The development server continues to serve the admin files just like before. Read the
for more details.
If your ADMIN_MEDIA_PREFIX is set to an specific domain (e.g. http://media.example.com/admin/), make sure to also set your
setting to the correct URL – for example, http://media.example.
com/
.
Warning: If you’re implicitly relying on the path of the admin static files within Django’s source code, you’ll need to update that path. The files were moved from django/contrib/admin/media/ to django/contrib/ admin/static/admin/ .
Supported browsers for the admin
Django hasn’t had a clear policy on which browsers are supported by the admin app. Our new policy formalizes existing practices: YUI’s A-grade browsers should provide a fully-functional admin experience, with the notable exception of Internet Explorer 6, which is no longer supported.
Released over 10 years ago, IE6 imposes many limitations on modern Web development. The practical implications of this policy are that contributors are free to improve the admin without consideration for these limitations.
Obviously, this new policy has no impact on sites you develop using Django. It only applies to the Django admin.
Feel free to develop apps compatible with any range of browsers.
Removed admin icons
As part of an effort to improve the performance and usability of the admin’s change-list sorting interface and
and
“filter” widgets, some icon files were removed and grouped into two sprite files.
Specifically: selector-add.gif
, selector-addall.gif
, selector-remove.gif
, selector-removeall.gif
, selector_stacked-add.gif
and selector_stacked-remove.
gif were combined into selector-icons.gif; and arrow-up.gif and arrow-down.gif were combined into sorting-icons.gif.
If you used those icons to customize the admin, then you’ll need to replace them with your own icons or get the files from a previous release.
CSS class names in admin forms
To avoid conflicts with other common CSS class names (e.g. “button”), we added a prefix (“field-”) to all CSS class names automatically generated from the form field names in the main admin forms, stacked inline forms and tabular
1616 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
inline cells. You’ll need to take that prefix into account in your custom style sheets or JavaScript files if you previously used plain field names as selectors for custom styles or JavaScript transformations.
Compatibility with old signed data
Django 1.3 changed the cryptographic signing mechanisms used in a number of places in Django. While Django 1.3
kept fallbacks that would accept hashes produced by the previous methods, these fallbacks are removed in Django 1.4.
So, if you upgrade to Django 1.4 directly from 1.2 or earlier, you may lose/invalidate certain pieces of data that have been cryptographically signed using an old method. To avoid this, use Django 1.3 first for a period of time to allow the signed data to expire naturally. The affected parts are detailed below, with 1) the consequences of ignoring this advice and 2) the amount of time you need to run Django 1.3 for the data to expire or become irrelevant.
• contrib.sessions data integrity check
– Consequences: The user will be logged out, and session data will be lost.
– Time period: Defined by
• contrib.auth password reset hash
– Consequences: Password reset links from before the upgrade will not work.
– Time period: Defined by
Form-related hashes: these have a are much shorter lifetime and are relevant only for the short window where a user might fill in a form generated by the pre-upgrade Django instance and try to submit it to the upgraded Django instance:
• contrib.comments form security hash
– Consequences: The user will see the validation error “Security hash failed.”
– Time period: The amount of time you expect users to take filling out comment forms.
• FormWizard security hash
– Consequences: The user will see an error about the form having expired and will be sent back to the first page of the wizard, losing the data entered so far.
– Time period: The amount of time you expect users to take filling out the affected forms.
• CSRF check
– Note: This is actually a Django 1.1 fallback, not Django 1.2, and it applies only if you’re upgrading from
1.1.
– Consequences: The user will see a 403 error with any CSRF-protected POST form.
– Time period: The amount of time you expect user to take filling out such forms.
• contrib.auth user password hash-upgrade sequence
– Consequences: Each user’s password will be updated to a stronger password hash when it’s written to the database in 1.4. This means that if you upgrade to 1.4 and then need to downgrade to 1.3, version 1.3
won’t be able to read the updated passwords.
– Remedy: Set
to use your original password hashing when you initially upgrade to
1.4. After you confirm your app works well with Django 1.4 and you won’t have to roll back to 1.3, enable the new password hashes.
9.1. Final releases 1617
Django Documentation, Release 2.0.dev20170914110741
django.contrib.flatpages
Starting in 1.4, the
only adds a trailing slash and redirects if the resulting
URL refers to an existing flatpage. For example, requesting /notaflatpageoravalidurl in a previous version would redirect to /notaflatpageoravalidurl/, which would subsequently raise a 404. Requesting / notaflatpageoravalidurl now will immediately raise a 404.
Also, redirects returned by flatpages are now permanent (with 301 status code), to match the behavior of
Serialization of datetime and time
As a consequence of time-zone support, and according to the ECMA-262 specification, we made changes to the JSON serializer:
• It includes the time zone for aware datetime objects. It raises an exception for aware time objects.
• It includes milliseconds for datetime and time objects. There is still some precision loss, because Python stores microseconds (6 digits) and JSON only supports milliseconds (3 digits). However, it’s better than discarding microseconds entirely.
We changed the XML serializer to use the ISO8601 format for datetimes. The letter T is used to separate the date part from the time part, instead of a space. Time zone information is included in the [+-]HH:MM format.
Though the serializers now use these new formats when creating fixtures, they can still load fixtures that use the old format.
supports_timezone changed to False for SQLite
The database feature supports_timezone used to be True for SQLite. Indeed, if you saved an aware datetime object, SQLite stored a string that included an UTC offset. However, this offset was ignored when loading the value back from the database, which could corrupt the data.
In the context of time-zone support, this flag was changed to False, and datetimes are now stored without time-zone information in SQLite. When
is False, if you attempt to save an aware datetime object, Django raises an exception.
MySQLdb
-specific exceptions
The MySQL backend historically has raised MySQLdb.OperationalError when a query triggered an exception.
We’ve fixed this bug, and we now raise
instead. If you were testing for MySQLdb.
OperationalError
, you’ll need to update your except clauses.
Database connection’s thread-locality
DatabaseWrapper objects (i.e. the connection objects referenced by django.db.connection and django.
db.connections["some_alias"] ) used to be thread-local. They are now global objects in order to be potentially shared between multiple threads. While the individual connection objects are now global, the django.
db.connections
dictionary referencing those objects is still thread-local. Therefore if you just use the ORM or DatabaseWrapper.cursor() then the behavior is still the same as before. Note, however, that django.
db.connection
does not directly reference the default DatabaseWrapper object anymore and is now a proxy to access that object’s attributes. If you need to access the actual DatabaseWrapper object, use django.db.
connections[DEFAULT_DB_ALIAS] instead.
1618 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
As part of this change, all underlying SQLite connections are now enabled for potential thread-sharing (by passing the check_same_thread=False attribute to pysqlite). DatabaseWrapper however preserves the previous behavior by disabling thread-sharing by default, so this does not affect any existing code that purely relies on the
ORM or on DatabaseWrapper.cursor().
Finally, while it’s now possible to pass connections between threads, Django doesn’t make any effort to synchronize access to the underlying backend. Concurrency behavior is defined by the underlying backend implementation. Check their documentation for details.
COMMENTS_BANNED_USERS_GROUP setting
Django’s comments has historically supported excluding the comments of a special user group, but we’ve never documented the feature properly and didn’t enforce the exclusion in other parts of the app such as the template tags. To fix this problem, we removed the code from the feed class.
If you rely on the feature and want to restore the old behavior, use a custom comment model manager to exclude the user group, like this:
from
django.conf
import
settings
from
django.contrib.comments.managers
import
CommentManager
class BanningCommentManager
(CommentManager):
def get_query_set
( self ): qs = super ().get_query_set()
if
getattr (settings, 'COMMENTS_BANNED_USERS_GROUP' , None): where = [ 'user_id NOT IN (SELECT user_id FROM auth_user_groups WHERE
˓→ group_id = %s)' ] params = [settings.COMMENTS_BANNED_USERS_GROUP] qs = qs.extra(where=where, params=params)
return
qs
Save this model manager in your custom comment app (e.g., in my_comments_app/managers.py) and add it your custom comment app model:
from
django.db
import
models
from
django.contrib.comments.models
import
Comment
from
my_comments_app.managers
import
BanningCommentManager
class CommentWithTitle
(Comment): title = models.CharField(max_length= 300 ) objects = BanningCommentManager()
IGNORABLE_404_STARTS and IGNORABLE_404_ENDS settings
Until Django 1.3, it was possible to exclude some URLs from Django’s
by adding prefixes to
IGNORABLE_404_STARTS and suffixes to IGNORABLE_404_ENDS.
In Django 1.4, these two settings are superseded by
, which is a list of compiled regular
expressions. Django won’t send an email for 404 errors on URLs that match any of them.
Furthermore, the previous settings had some rather arbitrary default values:
9.1. Final releases 1619
Django Documentation, Release 2.0.dev20170914110741
IGNORABLE_404_STARTS = ( '/cgi-bin/' , '/_vti_bin' , '/_vti_inf' )
IGNORABLE_404_ENDS = ( 'mail.pl' , 'mailform.pl' , 'mail.cgi' , 'mailform.cgi' ,
'favicon.ico' , '.php' )
It’s not Django’s role to decide if your website has a legacy /cgi-bin/ section or a favicon.
ico
.
As a consequence, the default values of
IGNORABLE_404_ENDS are all now empty.
If you have customized IGNORABLE_404_STARTS or IGNORABLE_404_ENDS, or if you want to keep the old default value, you should add the following lines in your settings file:
import
re
IGNORABLE_404_URLS = (
# for each <prefix> in IGNORABLE_404_STARTS re.compile( r'^<prefix>' ),
# for each <suffix> in IGNORABLE_404_ENDS re.compile( r'<suffix>$' ),
)
Don’t forget to escape characters that have a special meaning in a regular expression, such as periods.
CSRF protection extended to PUT and DELETE
Previously, Django’s
provided protection only against POST requests. Since use of PUT and
DELETE methods in AJAX applications is becoming more common, we now protect all methods not defined as safe by RFC 2616 – i.e., we exempt GET, HEAD, OPTIONS and TRACE, and we enforce protection on everything else.
If you’re using PUT or DELETE methods in AJAX applications, please see the
instructions about using AJAX and
Password reset view now accepts subject_template_name
The password_reset view in django.contrib.auth now accepts a subject_template_name parameter, which is passed to the password save form as a keyword argument. If you are using this view with a custom password reset form, then you will need to ensure your form’s save() method accepts this keyword argument.
django.core.template_loaders
This was an alias to django.template.loader since 2005, and we’ve removed it without emitting a warning due to the length of the deprecation. If your code still referenced this, please use django.template.loader
instead.
django.db.models.fields.URLField.verify_exists
This functionality has been removed due to intractable performance and security issues. Any existing usage of verify_exists should be removed.
1620 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
django.core.files.storage.Storage.open
The open method of the base Storage class used to take an obscure parameter mixin that allowed you to dynamically change the base classes of the returned file object. This has been removed. In the rare case you relied on the mixin parameter, you can easily achieve the same by overriding the open method, like this:
from
django.core.files
import
File
from
django.core.files.storage
import
FileSystemStorage
class Spam
(File):
"""
Spam, spam, spam, spam and spam.
"""
def ham
( self ):
return
'eggs'
class SpamStorage
(FileSystemStorage):
"""
A custom file storage backend.
"""
def open
( self , name, mode= 'rb' ):
return
Spam( open ( self
.
path(name), mode))
YAML deserializer now uses yaml.safe_load
yaml.load
is able to construct any Python object, which may trigger arbitrary code execution if you process a
YAML document that comes from an untrusted source. This feature isn’t necessary for Django’s YAML deserializer, whose primary use is to load fixtures consisting of simple objects. Even though fixtures are trusted data, the YAML deserializer now uses yaml.safe_load for additional security.
Session cookies now have the httponly flag by default
Session cookies now include the httponly attribute by default to help reduce the impact of potential XSS attacks.
As a consequence of this change, session cookie data, including sessionid, is no longer accessible from JavaScript in many browsers. For strict backwards compatibility, use SESSION_COOKIE_HTTPONLY = False in your settings file.
The urlize filter no longer escapes every URL
When a URL contains a %xx sequence, where xx are two hexadecimal digits,
now assumes that the URL is already escaped and doesn’t apply URL escaping again. This is wrong for URLs whose unquoted form contains a
%xx sequence, but such URLs are very unlikely to happen in the wild, because they would confuse browsers too.
assertTemplateUsed and assertTemplateNotUsed as context manager
It’s now possible to check whether a template was used within a block of code with
and
. And they can be used as a context manager:
with
self
.
assertTemplateUsed( 'index.html' ): render_to_string( 'index.html' )
9.1. Final releases 1621
Django Documentation, Release 2.0.dev20170914110741
with
self
.
assertTemplateNotUsed( 'base.html' ): render_to_string( 'index.html' )
See the
for more.
Database connections after running the test suite
The default test runner no longer restores the database connections after tests’ execution. This prevents the production database from being exposed to potential threads that would still be running and attempting to create new connections.
If your code relied on connections to the production database being created after tests’ execution, then you can restore the previous behavior by subclassing DjangoTestRunner and overriding its teardown_databases() method.
Output of manage.py help
now groups available commands by application. If you depended on the output of this command
– if you parsed it, for example – then you’ll need to update your code. To get a list of all available management commands in a script, use
instead.
extends template tag
Previously, the
tag used a buggy method of parsing arguments, which could lead to it erroneously considering an argument as a string literal when it wasn’t. It now uses parser.compile_filter, like other tags.
The internals of the tag aren’t part of the official stable API, but in the interests of full disclosure, the ExtendsNode.
__init__ definition has changed, which may break any custom tags that use this class.
Loading some incomplete fixtures no longer works
Prior to 1.4, a default value was inserted for fixture objects that were missing a specific date or datetime value when auto_now or auto_now_add was set for the field. This was something that should not have worked, and in 1.4 loading such incomplete fixtures will fail. Because fixtures are a raw import, they should explicitly specify all field values, regardless of field options on the model.
Development Server Multithreading
The development server is now is multithreaded by default. Use the
option to disable the use of threading in the development server: django-admin.py runserver --nothreading
Attributes disabled in markdown when safe mode set
Prior to Django 1.4, attributes were included in any markdown output regardless of safe mode setting of the filter.
With version > 2.1 of the Python-Markdown library, an enable_attributes option was added. When the safe argument is passed to the markdown filter, both the safe_mode=True and enable_attributes=False options are set.
If using a version of the Python-Markdown library less than 2.1, a warning is issued that the output is insecure.
1622 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
FormMixin get_initial returns an instance-specific dictionary
In Django 1.3, the get_initial method of the
django.views.generic.edit.FormMixin
class was returning the class initial dictionary. This has been fixed to return a copy of this dictionary, so form instances can modify their initial data without messing with the class variable.
Features deprecated in 1.4
Old styles of calling cache_page decorator
Some legacy ways of calling
have been deprecated. Please see the documentation for the correct way to use this decorator.
Support for PostgreSQL versions older than 8.2
Django 1.3 dropped support for PostgreSQL versions older than 8.0, and we suggested using a more recent version because of performance improvements and, more importantly, the end of upstream support periods for 8.0 and 8.1 was near (November 2010).
Django 1.4 takes that policy further and sets 8.2 as the minimum PostgreSQL version it officially supports.
Request exceptions are now always logged
When we added
in Django in 1.3, the admin error email support was moved into the
, attached to the 'django.request' logger. In order to maintain the
established behavior of error emails, the 'django.request' logger was called only when
was False.
To increase the flexibility of error logging for requests, the 'django.request' logger is now called regardless of the value of
DEBUG , and the default settings file for new projects now includes a separate filter attached to
to prevent admin error emails in DEBUG mode:
'filters' : {
'require_debug_false' : {
'()' : 'django.utils.log.RequireDebugFalse'
}
},
'handlers' : {
'mail_admins' : {
'level' : 'ERROR' ,
'filters' : [ 'require_debug_false' ],
'class' : 'django.utils.log.AdminEmailHandler'
}
},
If your project was created prior to this change, your
setting will not include this new filter. In order to maintain backwards-compatibility, Django will detect that your 'mail_admins' handler configuration includes no
'filters' section and will automatically add this filter for you and issue a pending-deprecation warning. This will become a deprecation warning in Django 1.5, and in Django 1.6 the backwards-compatibility shim will be removed entirely.
The existence of any 'filters' key under the 'mail_admins' handler will disable this backward-compatibility shim and deprecation warning.
9.1. Final releases 1623
Django Documentation, Release 2.0.dev20170914110741
django.conf.urls.defaults
Until Django 1.3, the functions
include() , patterns() and url()
plus
were located in a django.conf.urls.defaults module.
In Django 1.4, they live in
django.contrib.databrowse
Databrowse has not seen active development for some time, and this does not show any sign of changing. There had been a suggestion for a GSOC project to integrate the functionality of databrowse into the admin, but no progress was made. While Databrowse has been deprecated, an enhancement of django.contrib.admin providing a similar feature set is still possible.
The code that powers Databrowse is licensed under the same terms as Django itself, so it’s available to be adopted by an individual or group as a third-party project.
django.core.management.setup_environ
This function temporarily modified sys.path in order to make the parent “project” directory importable under the old flat
layout. This function is now deprecated, as its path workarounds are no longer needed with the new manage.py and default project layout.
This function was never documented or part of the public API, but it was widely recommended for use in setting up a
“Django environment” for a user script. These uses should be replaced by setting the DJANGO_SETTINGS_MODULE environment variable or using
django.conf.settings.configure()
django.core.management.execute_manager
This function was previously used by manage.py to execute a management command. It is identical to django.
core.management.execute_from_command_line
, except that it first calls setup_environ, which is now deprecated. As such, execute_manager is also deprecated; execute_from_command_line can be used instead. Neither of these functions is documented as part of the public API, but a deprecation path is needed due to use in existing manage.py files.
is_safe and needs_autoescape attributes of template filters
Two flags, is_safe and needs_autoescape, define how each template filter interacts with Django’s autoescaping behavior. They used to be attributes of the filter function:
@register.filter
def noop
(value):
return
value noop.is_safe = True
However, this technique caused some problems in combination with decorators, especially
the flags are keyword arguments of
@register.filter(is_safe=True)
def noop
(value):
return
value
1624 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
See
for more information.
Wildcard expansion of application names in INSTALLED_APPS
Until Django 1.3,
accepted wildcards in application names, like django.contrib.*. The expansion was performed by a filesystem-based implementation of from <package> import *. Unfortunately, this can’t be done reliably.
This behavior was never documented. Since it is unpythonic and not obviously useful, it was removed in Django 1.4.
If you relied on it, you must edit your settings file to list all your applications explicitly.
HttpRequest.raw_post_data
renamed to HttpRequest.body
This attribute was confusingly named HttpRequest.raw_post_data, but it actually provided the body of the
HTTP request. It’s been renamed to HttpRequest.body, and HttpRequest.raw_post_data has been deprecated.
django.contrib.sitemaps
bug fix with potential performance implications
In previous versions, Paginator objects used in sitemap classes were cached, which could result in stale site maps.
We’ve removed the caching, so each request to a site map now creates a new Paginator object and calls the
method of the
subclass. Depending on what your items() method is doing, this may have a negative performance impact. To mitigate the performance impact, consider using the
within your Sitemap subclass.
Versions of Python-Markdown earlier than 2.1
Versions of Python-Markdown earlier than 2.1 do not support the option to disable attributes. As a security issue, earlier versions of this library will not be supported by the markup contrib app in 1.5 under an accelerated deprecation timeline.
1.3 release
Django 1.3.7 release notes
February 20, 2013
Django 1.3.7 corrects a packaging problem with yesterday’s
The release contained stray .pyc files that caused “bad magic number” errors when running with some versions of
Python. This releases corrects this, and also fixes a bad documentation link in the project template settings.py
file generated by manage.py startproject.
Django 1.3.6 release notes
February 19, 2013
Django 1.3.6 fixes four security issues present in previous Django releases in the 1.3 series.
This is the sixth bugfix/security release in the Django 1.3 series.
9.1. Final releases 1625
Django Documentation, Release 2.0.dev20170914110741
Host header poisoning
Some parts of Django – independent of end-user-written applications – make use of full URLs, including domain name, which are generated from the HTTP Host header. Django’s documentation has for some time contained notes advising users on how to configure Web servers to ensure that only valid Host headers can reach the Django application. However, it has been reported to us that even with the recommended Web server configurations there are still techniques available for tricking many common Web servers into supplying the application with an incorrect and possibly malicious Host header.
For this reason, Django 1.3.6 adds a new setting, ALLOWED_HOSTS, which should contain an explicit list of valid host/domain names for this site. A request with a Host header not matching an entry in this list will raise
SuspiciousOperation if request.get_host() is called. For full details see the documentation for the
setting.
The default value for this setting in Django 1.3.6 is ['*'] (matching any host), for backwards-compatibility, but we strongly encourage all sites to set a more restrictive value.
This host validation is disabled when DEBUG is True or when running tests.
XML deserialization
The XML parser in the Python standard library is vulnerable to a number of attacks via external entities and entity expansion. Django uses this parser for deserializing XML-formatted database fixtures. The fixture deserializer is not intended for use with untrusted data, but in order to err on the side of safety in Django 1.3.6 the XML deserializer refuses to parse an XML document with a DTD (DOCTYPE definition), which closes off these attack avenues.
These issues in the Python standard library are CVE-2013-1664 and CVE-2013-1665. More information available from the Python security team .
Django’s XML serializer does not create documents with a DTD, so this should not cause any issues with the typical round-trip from dumpdata to loaddata, but if you feed your own XML documents to the loaddata management command, you will need to ensure they do not contain a DTD.
Formset memory exhaustion
Previous versions of Django did not validate or limit the form-count data provided by the client in a formset’s management form, making it possible to exhaust a server’s available memory by forcing it to create very large numbers of forms.
In Django 1.3.6, all formsets have a strictly-enforced maximum number of forms (1000 by default, though it can be set higher via the max_num formset factory argument).
Admin history view information leakage
In previous versions of Django, an admin user without change permission on a model could still view the unicode representation of instances via their admin history log. Django 1.3.6 now limits the admin history log view for an object to users with change permission for that model.
Django 1.3.5 release notes
December 10, 2012
Django 1.3.5 addresses two security issues present in previous Django releases in the 1.3 series.
1626 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
Please be aware that this security release is slightly different from previous ones. Both issues addressed here have been dealt with in prior security updates to Django. In one case, we have received ongoing reports of problems, and in the other we’ve chosen to take further steps to tighten up Django’s code in response to independent discovery of potential problems from multiple sources.
Host header poisoning
Several earlier Django security releases focused on the issue of poisoning the HTTP Host header, causing Django to generate URLs pointing to arbitrary, potentially-malicious domains.
In response to further input received and reports of continuing issues following the previous release, we’re taking additional steps to tighten Host header validation. Rather than attempt to accommodate all features HTTP supports here, Django’s Host header validation attempts to support a smaller, but far more common, subset:
• Hostnames must consist of characters [A-Za-z0-9] plus hyphen (‘-‘) or dot (‘.’).
• IP addresses – both IPv4 and IPv6 – are permitted.
• Port, if specified, is numeric.
Any deviation from this will now be rejected, raising the exception
Redirect poisoning
Also following up on a previous issue: in July of this year, we made changes to Django’s HTTP redirect classes, performing additional validation of the scheme of the URL to redirect to (since, both within Django’s own supplied applications and many third-party applications, accepting a user-supplied redirect target is a common pattern).
Since then, two independent audits of the code turned up further potential problems. So, similar to the Host-header issue, we are taking steps to provide tighter validation in response to reported problems (primarily with third-party applications, but to a certain extent also within Django itself). This comes in two parts:
1. A new utility function, django.utils.http.is_safe_url, is added; this function takes a URL and a hostname, and checks that the URL is either relative, or if absolute matches the supplied hostname. This function is intended for use whenever user-supplied redirect targets are accepted, to ensure that such redirects cannot lead to arbitrary third-party sites.
2. All of Django’s own built-in views – primarily in the authentication system – which allow user-supplied redirect targets now use is_safe_url to validate the supplied URL.
Django 1.3.4 release notes
October 17, 2012
This is the fourth release in the Django 1.3 series.
Host header poisoning
Some parts of Django – independent of end-user-written applications – make use of full URLs, including domain name, which are generated from the HTTP Host header. Some attacks against this are beyond Django’s ability to control, and require the web server to be properly configured; Django’s documentation has for some time contained notes advising users on such configuration.
9.1. Final releases 1627
Django Documentation, Release 2.0.dev20170914110741
Django’s own built-in parsing of the Host header is, however, still vulnerable, as was reported to us recently. The Host header parsing in Django 1.3.3 and Django 1.4.1 – specifically, django.http.HttpRequest.get_host() – was incorrectly handling username/password information in the header. Thus, for example, the following Host header would be accepted by Django when running on “validsite.com”:
Host: validsite.com:random@evilsite.com
Using this, an attacker can cause parts of Django – particularly the password-reset mechanism – to generate and display arbitrary URLs to users.
To remedy this, the parsing in HttpRequest.get_host() is being modified; Host headers which contain potentially dangerous content (such as username/password pairs) now raise the exception
Details of this issue were initially posted online as a security advisory .
Django 1.3.3 release notes
August 1, 2012
Following Monday’s security release of
, we began receiving reports that one of the fixes applied was
breaking Python 2.4 compatibility for Django 1.3. Since Python 2.4 is a supported Python version for that release series, this release fixes compatibility with Python 2.4.
Django 1.3.2 release notes
July 30, 2012
This is the second security release in the Django 1.3 series, fixing several security issues in Django 1.3. Django 1.3.2
is a recommended upgrade for all users of Django 1.3.
For a full list of issues addressed in this release, see the security advisory .
Django 1.3.1 release notes
September 9, 2011
Welcome to Django 1.3.1!
This is the first security release in the Django 1.3 series, fixing several security issues in Django 1.3. Django 1.3.1 is a recommended upgrade for all users of Django 1.3.
For a full list of issues addressed in this release, see the security advisory .
Django 1.3 release notes
March 23, 2011
Welcome to Django 1.3!
Nearly a year in the making, Django 1.3 includes quite a few
and plenty of bug fixes and improvements to existing features. These release notes cover the new features in 1.3, as well as some
backwards-incompatible changes
you’ll want to be aware of when upgrading from Django 1.2 or older versions.
1628 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
Overview
Django 1.3’s focus has mostly been on resolving smaller, long-standing feature requests, but that hasn’t prevented a few fairly significant new features from landing, including:
• A framework for writing
• Built-in support for
using Python’s logging facilities
• Contrib support for
easy handling of static files .
• Django’s testing framework now supports (and ships with a copy of)
Wherever possible, of course, new features are introduced in a backwards-compatible manner per
policy. As a result of this policy, Django 1.3
begins the deprecation process for some features .
Python compatibility
The release of Django 1.2 was notable for having the first shift in Django’s Python compatibility policy; prior to
Django 1.2, Django supported any 2.x version of Python from 2.3 up. As of Django 1.2, the minimum requirement was raised to Python 2.4.
Django 1.3 continues to support Python 2.4, but will be the final Django release series to do so; beginning with Django
1.4, the minimum supported Python version will be 2.5. A document outlining our full timeline for deprecating Python
2.x and moving to Python 3.x will be published shortly after the release of Django 1.3.
What’s new in Django 1.3
Class-based views
Django 1.3 adds a framework that allows you to use a class as a view. This means you can compose a view out of a collection of methods that can be subclassed and overridden to provide common views of data without having to write too much code.
Analogs of all the old function-based generic views have been provided, along with a completely generic view base class that can be used as the basis for reusable applications that can be easily extended.
See
the documentation on class-based generic views
for more details. There is also a document to help you convert your function-based generic views to class-based views .
Logging
Django 1.3 adds framework-level support for Python’s logging module. This means you can now easily configure and control logging as part of your Django project. A number of logging handlers and logging calls have been added to Django’s own code as well – most notably, the error emails sent on a HTTP 500 server error are now handled as a logging activity. See
the documentation on Django’s logging interface
for more details.
Extended static files handling
Django 1.3 ships with a new contrib app – django.contrib.staticfiles – to help developers handle the static media files (images, CSS, JavaScript, etc.) that are needed to render a complete web page.
In previous versions of Django, it was common to place static assets in
along with user-uploaded files, and serve them both at
. Part of the purpose of introducing the staticfiles app is to make it easier
9.1. Final releases 1629
Django Documentation, Release 2.0.dev20170914110741
to keep static files separate from user-uploaded files. Static assets should now go in static/ subdirectories of your apps or in other static assets directories listed in
See the
reference documentation of the app
for more details or learn how to
unittest2 support
Python 2.7 introduced some major changes to the unittest library, adding some extremely useful features. To ensure that every Django project can benefit from these new features, Django ships with a copy of unittest2 , a copy of the Python 2.7 unittest library, backported for Python 2.4 compatibility.
To access this library, Django provides the django.utils.unittest module alias. If you are using Python 2.7, or you have installed unittest2 locally, Django will map the alias to the installed version of the unittest library.
Otherwise, Django will use its own bundled version of unittest2.
To take advantage of this alias, simply use:
from
django.utils
import
unittest wherever you would have historically used:
import
unittest
If you want to continue to use the base unittest library, you can – you just won’t get any of the nice new unittest2 features.
Transaction context managers
Users of Python 2.5 and above may now use transaction management functions as context managers. For example:
with
transaction.autocommit():
# ...
Configurable delete-cascade
and
now accept an
argument to customize behavior when the referenced object is deleted. Previously, deletes were always cascaded; available alternatives now include set null, set default, set to any value, protect, or do nothing.
For more information, see the
documentation.
Contextual markers and comments for translatable strings
For translation strings with ambiguous meaning, you can now use the pgettext function to specify the context of the string.
And if you just want to add some information for translators, you can also add special translator comments in the source.
For more information, see
and
1630 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
Improvements to built-in template tags
A number of improvements have been made to Django’s built-in template tags:
• The
tag now accepts a with option, allowing you to specify context variables to the included template
• The
tag now accepts an only option, allowing you to exclude the current context from the included context
• The
tag now allows you to define multiple context variables in a single
block.
• The
tag now accepts a from argument, allowing you to load a single tag or filter from a library.
TemplateResponse
It can sometimes be beneficial to allow decorators or middleware to modify a response after it has been constructed by the view. For example, you may want to change the template that is used, or put additional data into the context.
However, you can’t (easily) modify the content of a basic
after it has been constructed. To overcome this limitation, Django 1.3 adds a new
class. Unlike basic
objects,
objects retain the details of the template and context that was provided by the view to compute the response. The final output of the response is not computed until it is needed, later in the response process.
For more details, see the
on the
class.
Caching changes
Django 1.3 sees the introduction of several improvements to the Django’s caching infrastructure.
Firstly, Django now supports multiple named caches. In the same way that Django 1.2 introduced support for multiple database connections, Django 1.3 allows you to use the new
setting to define multiple named cache connections.
Secondly,
versioning , site-wide prefixing
and
have been added to the cache API.
Thirdly,
has been updated to take the request query string into account on GET requests.
Finally, support for pylibmc has been added to the memcached cache backend.
For more details, see the
documentation on caching in Django .
Permissions for inactive users
If you provide a custom auth backend with supports_inactive_user set to True, an inactive User instance will check the backend for permissions. This is useful for further centralizing the permission handling. See the
for more details.
GeoDjango
The GeoDjango test suite is now included when
with runtests.py when using
9.1. Final releases 1631
Django Documentation, Release 2.0.dev20170914110741
MEDIA_URL and STATIC_URL must end in a slash
Previously, the
setting only required a trailing slash if it contained a suffix beyond the domain name.
A trailing slash is now required for
and the new
setting as long as it is not blank. This ensures there is a consistent way to combine paths in templates.
Project settings which provide either of both settings without a trailing slash will now raise a
PendingDeprecationWarning
.
In Django 1.4 this same condition will raise DeprecationWarning, and in Django 1.5 will raise an
ImproperlyConfigured exception.
Everything else
Django
and
added lots of big ticket items to Django, like multiple-database support, model validation, and a session-based messages framework. However, this focus on big features came at the cost of lots of smaller features.
To compensate for this, the focus of the Django 1.3 development process has been on adding lots of smaller, long standing feature requests. These include:
• Improved tools for accessing and manipulating the current
object in
• A
for mocking requests in tests.
• A new test assertion –
– making it easier to test the database activity associated with a view.
• Support for lookups spanning relations in admin’s
• Support for HTTPOnly cookies.
•
and
now support easily attaching HTML content to messages.
•
now supports CC’s.
• Error emails now include more of the detail and formatting of the debug server error page.
•
now accepts a takes_context argument, making it easier to write simple template tags that require access to template context.
• A new
shortcut – an alternative to django.shortcuts.render_to_response() providing a
by default.
• Support for combining
with timedelta values when retrieving or updating database values.
Backwards-incompatible changes in 1.3
CSRF validation now applies to AJAX requests
Prior to Django 1.2.5, Django’s CSRF-prevention system exempted AJAX requests from CSRF verification; due to security issues reported to us, however, all requests are now subjected to CSRF verification. Consult
for details on how to handle CSRF verification in AJAX requests.
1632 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
Restricted filters in admin interface
Prior to Django 1.2.5, the Django administrative interface allowed filtering on any model field or relation – not just those specified in list_filter – via query string manipulation. Due to security issues reported to us, however, query string lookup arguments in the admin must be for fields or relations specified in list_filter or date_hierarchy
.
Deleting a model doesn’t delete associated files
In earlier Django versions, when a model instance containing a
was deleted,
took it upon itself to also delete the file from the backend storage. This opened the door to several data-loss scenarios, including rolled-back transactions and fields on different models referencing the same file. In Django 1.3, when a model is deleted the
’s delete() method won’t be called. If you need cleanup of orphaned files, you’ll need to
handle it yourself (for instance, with a custom management command that can be run manually or scheduled to run periodically via e.g. cron).
PasswordInput default rendering behavior
The
form widget, intended for use with form fields which represent passwords, accepts a boolean keyword argument render_value indicating whether to send its data back to the browser when displaying a submitted form with errors. Prior to Django 1.3, this argument defaulted to True, meaning that the submitted password would be sent back to the browser as part of the form. Developers who wished to add a bit of additional security by excluding that value from the redisplayed form could instantiate a
passing render_value=False
.
Due to the sensitive nature of passwords, however, Django 1.3 takes this step automatically; the default value of render_value is now False, and developers who want the password value returned to the browser on a submission with errors (the previous behavior) must now explicitly indicate this. For example:
class LoginForm
(forms.Form): username = forms.CharField(max_length= 100 ) password = forms.CharField(widget=forms.PasswordInput(render_value=True))
Clearable default widget for FileField
Django 1.3
now includes a
form widget in addition to
ClearableFileInput renders with a checkbox to clear the field’s value (if the field has a value and is not required); FileInput provided no means for clearing an existing file from a FileField.
ClearableFileInput is now the default widget for a FileField, so existing forms including FileField without assigning a custom widget will need to account for the possible extra checkbox in the rendered form output.
To return to the previous rendering (without the ability to clear the FileField), use the FileInput widget in place of ClearableFileInput. For instance, in a ModelForm for a hypothetical Document model with a
FileField named document:
from
django
import
forms
from
myapp.models
import
Document
class DocumentForm
(forms.ModelForm):
class Meta
: model = Document widgets = { 'document' : forms.FileInput}
9.1. Final releases 1633
Django Documentation, Release 2.0.dev20170914110741
New index on database session table
Prior to Django 1.3, the database table used by the database backend for the
app had no index on the expire_date column. As a result, date-based queries on the session table – such as the query that is needed to purge old sessions – would be very slow if there were lots of sessions.
If you have an existing project that is using the database session backend, you don’t have to do anything to accommodate this change. However, you may get a significant performance boost if you manually add the new index to the session table. The SQL that will add the index can be found by running the sqlindexes admin command: python manage.py sqlindexes sessions
No more naughty words
Django has historically provided (and enforced) a list of profanities. The comments app has enforced this list of profanities, preventing people from submitting comments that contained one of those profanities.
Unfortunately, the technique used to implement this profanities list was woefully naive, and prone to the Scunthorpe problem . Improving the built-in filter to fix this problem would require significant effort, and since natural language processing isn’t the normal domain of a web framework, we have “fixed” the problem by making the list of prohibited words an empty list.
If you want to restore the old behavior, simply put a PROFANITIES_LIST setting in your settings file that includes the words that you want to prohibit (see the commit that implemented this change if you want to see the list of words that was historically prohibited). However, if avoiding profanities is important to you, you would be well advised to seek out a better, less naive approach to the problem.
Localflavor changes
Django 1.3 introduces the following backwards-incompatible changes to local flavors:
• Canada (ca) – The province “Newfoundland and Labrador” has had its province code updated to “NL”, rather than the older “NF”. In addition, the Yukon Territory has had its province code corrected to “YT”, instead of
“YK”.
• Indonesia (id) – The province “Nanggroe Aceh Darussalam (NAD)” has been removed from the province list in favor of the new official designation “Aceh (ACE)”.
• United States of America (us) – The list of “states” used by USStateField has expanded to include Armed
Forces postal codes. This is backwards-incompatible if you were relying on USStateField not including them.
FormSet updates
In Django 1.3 FormSet creation behavior is modified slightly. Historically the class didn’t make a distinction between not being passed data and being passed empty dictionary. This was inconsistent with behavior in other parts of the framework. Starting with 1.3 if you pass in empty dictionary the FormSet will raise a ValidationError.
For example with a FormSet:
>>>
class ArticleForm
(Form):
...
title = CharField()
...
pub_date = DateField()
>>> ArticleFormSet = formset_factory(ArticleForm)
1634 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
the following code will raise a ValidationError:
>>> ArticleFormSet({})
Traceback (most recent call last):
...
ValidationError : [u'ManagementForm data is missing or has been tampered with'] if you need to instantiate an empty FormSet, don’t pass in the data or use None:
>>> formset = ArticleFormSet()
>>> formset = ArticleFormSet(data=None)
Callables in templates
Previously, a callable in a template would only be called automatically as part of the variable resolution process if it was retrieved via attribute lookup. This was an inconsistency that could result in confusing and unhelpful behavior:
>>> Template( "{{ user.get_full_name }}" ).render(Context({ 'user' : user})) u'Joe Bloggs'
>>> Template( "{{ full_name }}" ).render(Context({ 'full_name' : user.get_full_name})) u'<bound method User.get_full_name of <...
This has been resolved in Django 1.3 - the result in both cases will be u'Joe Bloggs'. Although the previous behavior was not useful for a template language designed for web designers, and was never deliberately supported, it is possible that some templates may be broken by this change.
Use of custom SQL to load initial data in tests
Django provides a custom SQL hooks as a way to inject hand-crafted SQL into the database synchronization process.
One of the possible uses for this custom SQL is to insert data into your database. If your custom SQL contains
INSERT statements, those insertions will be performed every time your database is synchronized. This includes the synchronization of any test databases that are created when you run a test suite.
However, in the process of testing the Django 1.3, it was discovered that this feature has never completely worked as advertised. When using database backends that don’t support transactions, or when using a TransactionTestCase, data that has been inserted using custom SQL will not be visible during the testing process.
Unfortunately, there was no way to rectify this problem without introducing a backwards incompatibility. Rather than leave SQL-inserted initial data in an uncertain state, Django now enforces the policy that data inserted by custom SQL will not be visible during testing.
This change only affects the testing process. You can still use custom SQL to load data into your production database as part of the syncdb process. If you require data to exist during test conditions, you should either insert it using
test fixtures , or using the setUp() method of your test case.
Changed priority of translation loading
Work has been done to simplify, rationalize and properly document the algorithm used by Django at runtime to build translations from the different translations found on disk, namely:
For translatable literals found in Python code and templates ('django' gettext domain):
• Priorities of translations included with applications listed in the
setting were changed. To provide a behavior consistent with other parts of Django that also use such setting (templates, etc.) now, when
9.1. Final releases 1635
Django Documentation, Release 2.0.dev20170914110741
building the translation that will be made available, the apps listed first have higher precedence than the ones listed later.
• Now it is possible to override the translations shipped with applications by using the
setting whose translations have now higher precedence than the translations of
applications. The relative priority among the values listed in this setting has also been modified so the paths listed first have higher precedence than the ones listed later.
• The locale subdirectory of the directory containing the settings, that usually coincides with and is known as the project directory is being deprecated in this release as a source of translations. (the precedence of these translations is intermediate between applications and
translations). See the
corresponding deprecated features section
of this document.
For translatable literals found in JavaScript code ('djangojs' gettext domain):
• Similarly to the 'django' domain translations: Overriding of translations shipped with applications by using the
setting is now possible for this domain too. These translations have higher precedence than the translations of Python packages passed to the javascript_catalog() view. Paths listed first have higher precedence than the ones listed later.
• Translations under the locale subdirectory of the project directory have never been taken in account for
JavaScript translations and remain in the same situation considering the deprecation of such location.
Transaction management
When using managed transactions – that is, anything but the default autocommit mode – it is important when a transaction is marked as “dirty”. Dirty transactions are committed by the commit_on_success decorator or the django.middleware.transaction.TransactionMiddleware
, and commit_manually forces them to be closed explicitly; clean transactions “get a pass”, which means they are usually rolled back at the end of a request when the connection is closed.
Until Django 1.3, transactions were only marked dirty when Django was aware of a modifying operation performed in them; that is, either some model was saved, some bulk update or delete was performed, or the user explicitly called transaction.set_dirty(). In Django 1.3, a transaction is marked dirty when any database operation is performed.
As a result of this change, you no longer need to set a transaction dirty explicitly when you execute raw SQL or use a data-modifying SELECT. However, you do need to explicitly close any read-only transactions that are being managed using commit_manually(). For example:
@transaction.commit_manually
def my_view
(request, name): obj = get_object_or_404(MyObject, name__iexact=name)
return
render_to_response( 'template' , { 'object' :obj})
Prior to Django 1.3, this would work without error.
However, under Django 1.3, this will raise a
because the read operation that retrieves the MyObject instance leaves the transaction in a dirty state.
No password reset for inactive users
Prior to Django 1.3, inactive users were able to request a password reset email and reset their password. In Django 1.3
inactive users will receive the same message as a nonexistent account.
1636 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
Password reset view now accepts from_email
The
django.contrib.auth.views.password_reset()
view now accepts a from_email parameter, which is passed to the password_reset_form’s save() method as a keyword argument. If you are using this view with a custom password reset form, then you will need to ensure your form’s save() method accepts this keyword argument.
Features deprecated in 1.3
Django 1.3 deprecates some features from earlier releases. These features are still supported, but will be gradually phased out over the next few release cycles.
Code taking advantage of any of the features below will raise a PendingDeprecationWarning in Django 1.3.
This warning will be silent by default, but may be turned on using Python’s warnings module, or by running Python with a -Wd or -Wall flag.
In Django 1.4, these warnings will become a DeprecationWarning, which is not silent. In Django 1.5 support for these features will be removed entirely.
See also:
For more details, see the documentation
and our
mod_python support
The mod_python library has not had a release since 2007 or a commit since 2008. The Apache Foundation board voted to remove mod_python from the set of active projects in its version control repositories, and its lead developer has shifted all of his efforts toward the lighter, slimmer, more stable, and more flexible mod_wsgi backend.
If you are currently using the mod_python request handler, you should redeploy your Django projects using another request handler.
is the request handler recommended by the Django project, but FastCGI is also supported.
Support for mod_python deployment will be removed in Django 1.5.
Function-based generic views
As a result of the introduction of class-based generic views, the function-based generic views provided by Django have been deprecated. The following modules and the views they contain have been deprecated:
• django.views.generic.create_update
• django.views.generic.date_based
• django.views.generic.list_detail
• django.views.generic.simple
Test client response template attribute
Django’s
returns
objects annotated with extra testing information. In Django versions prior to 1.3, this included a template attribute containing information about templates rendered in generating the response: either None, a single
object, or a list of
objects. This inconsistency in return values
(sometimes a list, sometimes not) made the attribute difficult to work with.
In Django 1.3 the template attribute is deprecated in favor of a new
attribute, which is always a list, even if it has only a single element or no elements.
9.1. Final releases 1637
Django Documentation, Release 2.0.dev20170914110741
DjangoTestRunner
As a result of the introduction of support for unittest2, the features of django.test.simple.
DjangoTestRunner (including fail-fast and Ctrl-C test termination) have been made redundant. In view of this redundancy, DjangoTestRunner has been turned into an empty placeholder class, and will be removed entirely in
Django 1.5.
Changes to url and ssi
Most template tags will allow you to pass in either constants or variables as arguments – for example:
{% extends "base.html"
%
} allows you to specify a base template as a constant, but if you have a context variable templ that contains the value base.html
:
{% extends templ %} is also legal.
However, due to an accident of history, the url and ssi are different. These tags use the second, quoteless syntax, but interpret the argument as a constant. This means it isn’t possible to use a context variable as the target of a url and ssi tag.
Django 1.3 marks the start of the process to correct this historical accident. Django 1.3 adds a new template library – future
– that provides alternate implementations of the url and ssi template tags. This future library implement behavior that makes the handling of the first argument consistent with the handling of all other variables. So, an existing template that contains:
{% url sample %} should be replaced with:
{% load url from future
%
}
{% url 'sample'
%
}
The tags implementing the old behavior have been deprecated, and in Django 1.5, the old behavior will be replaced with the new behavior. To ensure compatibility with future versions of Django, existing templates should be modified to use the new future libraries and syntax.
Changes to the login methods of the admin
In previous version the admin app defined login methods in multiple locations and ignored the almost identical implementation in the already used auth app. A side effect of this duplication was the missing adoption of the changes made in r12634 to support a broader set of characters for usernames.
This release refactors the admin’s login mechanism to use a subclass of the
instead of a manual form validation.
The previously undocumented method 'django.contrib.admin.sites.
AdminSite.display_login_form' has been removed in favor of a new
attribute.
reset and sqlreset management commands
Those commands have been deprecated. The flush and sqlflush commands can be used to delete everything.
You can also use ALTER TABLE or DROP TABLE statements manually.
1638 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
GeoDjango
• The function-based
previously used to execute the GeoDjango test suite, django.contrib.
gis.tests.run_gis_tests
, was deprecated for the class-based runner, django.contrib.gis.
tests.GeoDjangoTestSuiteRunner
.
• Previously, calling
would silently do nothing when GDAL wasn’t available.
Now, a
is properly raised to indicate possible faulty application code. A warning is now raised if
is called when the SRID of the geometry is less than 0 or None.
CZBirthNumberField.clean
Previously this field’s clean() method accepted a second, gender, argument which allowed stronger validation checks to be made, however since this argument could never actually be passed from the Django form machinery it is now pending deprecation.
CompatCookie
Previously, django.http exposed an undocumented CompatCookie class, which was a bugfix wrapper around the standard library SimpleCookie. As the fixes are moving upstream, this is now deprecated - you should use from django.http import SimpleCookie instead.
Loading of project-level translations
This release of Django starts the deprecation process for inclusion of translations located under the so-called project path in the translation building process performed at runtime. The
setting can be used for the same task by adding the filesystem path to a locale directory containing project-level translations to the value of that setting.
Rationale for this decision:
• The project path has always been a loosely defined concept (actually, the directory used for locating projectlevel translations is the directory containing the settings module) and there has been a shift in other parts of the framework to stop using it as a reference for location of assets at runtime.
• Detection of the locale subdirectory tends to fail when the deployment scenario is more complex than the basic one. e.g. it fails when the settings module is a directory (ticket #10765).
• There are potential strange development- and deployment-time problems like the fact that the project_dir/ locale/ subdir can generate spurious error messages when the project directory is added to the Python path
(manage.py runserver does this) and then it clashes with the equally named standard library module, this is a typical warning message:
/
usr/lib/python2. 6
/
gettext.py: 49 :
ImportWarning
: Not importing directory '/path/
˓→ to/project/locale' : missing
__init__ .
py.
import
locale
,
copy
,
os
,
re
,
struct
,
sys
• This location wasn’t included in the translation building process for JavaScript literals. This deprecation removes such inconsistency.
9.1. Final releases 1639
Django Documentation, Release 2.0.dev20170914110741
PermWrapper moved to django.contrib.auth.context_processors
In Django 1.2, we began the process of changing the location of the auth context processor from django.core.context_processors
to django.contrib.auth.context_processors.
However, the PermWrapper support class was mistakenly omitted from that migration.
In Django 1.3, the
PermWrapper class has also been moved to django.contrib.auth.context_processors, along with the PermLookupDict support class. The new classes are functionally identical to their old versions; only the module location has changed.
Removal of XMLField
When Django was first released, Django included an XMLField that performed automatic XML validation for any field input. However, this validation function hasn’t been performed since the introduction of newforms, prior to the 1.0 release. As a result, XMLField as currently implemented is functionally indistinguishable from a simple
For this reason, Django 1.3 has fast-tracked the deprecation of XMLField – instead of a two-release deprecation,
XMLField will be removed entirely in Django 1.4.
It’s easy to update your code to accommodate this change – just replace all uses of XMLField with TextField, and remove the schema_path keyword argument (if it is specified).
1.2 release
Django 1.2.7 release notes
September 10, 2011
Welcome to Django 1.2.7!
This is the seventh bugfix/security release in the Django 1.2 series. It replaces Django 1.2.6 due to problems with the
1.2.6 release tarball. Django 1.2.7 is a recommended upgrade for all users of any Django release in the 1.2.X series.
For more information, see the release advisory .
Django 1.2.6 release notes
September 9, 2011
Welcome to Django 1.2.6!
This is the sixth bugfix/security release in the Django 1.2 series, fixing several security issues present in Django 1.2.5.
Django 1.2.6 is a recommended upgrade for all users of any Django release in the 1.2.X series.
For a full list of issues addressed in this release, see the security advisory .
Django 1.2.5 release notes
Welcome to Django 1.2.5!
This is the fifth “bugfix” release in the Django 1.2 series, improving the stability and performance of the Django 1.2
codebase.
1640 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
With four exceptions, Django 1.2.5 maintains backwards compatibility with Django 1.2.4. It also contains a number of fixes and other improvements. Django 1.2.5 is a recommended upgrade for any development or deployment currently using or targeting Django 1.2.
For full details on the new features, backwards incompatibilities, and deprecated features in the 1.2 branch, see the
Backwards incompatible changes
CSRF exception for AJAX requests
Django includes a CSRF-protection mechanism, which makes use of a token inserted into outgoing forms. Middleware then checks for the token’s presence on form submission, and validates it.
Prior to Django 1.2.5, our CSRF protection made an exception for AJAX requests, on the following basis:
• Many AJAX toolkits add an X-Requested-With header when using XMLHttpRequest.
• Browsers have strict same-origin policies regarding XMLHttpRequest.
• In the context of a browser, the only way that a custom header of this nature can be added is with XMLHttpRequest.
Therefore, for ease of use, we did not apply CSRF checks to requests that appeared to be AJAX on the basis of the
X-Requested-With header. The Ruby on Rails web framework had a similar exemption.
Recently, engineers at Google made members of the Ruby on Rails development team aware of a combination of browser plugins and redirects which can allow an attacker to provide custom HTTP headers on a request to any website. This can allow a forged request to appear to be an AJAX request, thereby defeating CSRF protection which trusts the same-origin nature of AJAX requests.
Michael Koziarski of the Rails team brought this to our attention, and we were able to produce a proof-of-concept demonstrating the same vulnerability in Django’s CSRF handling.
To remedy this, Django will now apply full CSRF validation to all requests, regardless of apparent AJAX origin. This is technically backwards-incompatible, but the security risks have been judged to outweigh the compatibility concerns in this case.
Additionally, Django will now accept the CSRF token in the custom HTTP header X-CSRFTOKEN, as well as in the form submission itself, for ease of use with popular JavaScript toolkits which allow insertion of custom headers into all AJAX requests.
Please see the
CSRF docs for example jQuery code
that demonstrates this technique, ensuring that you are looking at the documentation for your version of Django, as the exact code necessary is different for some older versions of
Django.
FileField no longer deletes files
In earlier Django versions, when a model instance containing a
was deleted,
took it upon itself to also delete the file from the backend storage. This opened the door to several potentially serious data-loss scenarios, including rolled-back transactions and fields on different models referencing the same file. In Django 1.2.5,
will never delete files from the backend storage. If you need cleanup of orphaned files, you’ll need to handle it yourself (for instance, with a custom management command that can be run manually or scheduled to run periodically via e.g. cron).
9.1. Final releases 1641
Django Documentation, Release 2.0.dev20170914110741
Use of custom SQL to load initial data in tests
Django provides a custom SQL hooks as a way to inject hand-crafted SQL into the database synchronization process.
One of the possible uses for this custom SQL is to insert data into your database. If your custom SQL contains
INSERT statements, those insertions will be performed every time your database is synchronized. This includes the synchronization of any test databases that are created when you run a test suite.
However, in the process of testing the Django 1.3, it was discovered that this feature has never completely worked as advertised. When using database backends that don’t support transactions, or when using a TransactionTestCase, data that has been inserted using custom SQL will not be visible during the testing process.
Unfortunately, there was no way to rectify this problem without introducing a backwards incompatibility. Rather than leave SQL-inserted initial data in an uncertain state, Django now enforces the policy that data inserted by custom SQL will not be visible during testing.
This change only affects the testing process. You can still use custom SQL to load data into your production database as part of the syncdb process. If you require data to exist during test conditions, you should either insert it using
test fixtures , or using the setUp() method of your test case.
ModelAdmin.lookup_allowed signature changed
Django 1.2.4 introduced a method lookup_allowed on ModelAdmin, to cope with a security issue (changeset
[15033] ). Although this method was never documented, it seems some people have overridden lookup_allowed, especially to cope with regressions introduced by that changeset. While the method is still undocumented and not marked as stable, it may be helpful to know that the signature of this function has changed.
Django 1.2.4 release notes
Welcome to Django 1.2.4!
This is the fourth “bugfix” release in the Django 1.2 series, improving the stability and performance of the Django 1.2
codebase.
With one exception, Django 1.2.4 maintains backwards compatibility with Django 1.2.3. It also contains a number of fixes and other improvements. Django 1.2.4 is a recommended upgrade for any development or deployment currently using or targeting Django 1.2.
For full details on the new features, backwards incompatibilities, and deprecated features in the 1.2 branch, see the
Backwards incompatible changes
Restricted filters in admin interface
The Django administrative interface, django.contrib.admin, supports filtering of displayed lists of objects by fields on the corresponding models, including across database-level relationships. This is implemented by passing lookup arguments in the querystring portion of the URL, and options on the ModelAdmin class allow developers to specify particular fields or relationships which will generate automatic links for filtering.
One historically-undocumented and -unofficially-supported feature has been the ability for a user with sufficient knowledge of a model’s structure and the format of these lookup arguments to invent useful new filters on the fly by manipulating the querystring.
However, it has been demonstrated that this can be abused to gain access to information outside of an admin user’s permissions; for example, an attacker with access to the admin and sufficient knowledge of model structure and
1642 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
relations could construct query strings which – with repeated use of regular-expression lookups supported by the
Django database API – expose sensitive information such as users’ password hashes.
To remedy this, django.contrib.admin will now validate that querystring lookup arguments either specify only fields on the model being viewed, or cross relations which have been explicitly whitelisted by the application developer using the pre-existing mechanism mentioned above. This is backwards-incompatible for any users relying on the prior ability to insert arbitrary lookups.
One new feature
Ordinarily, a point release would not include new features, but in the case of Django 1.2.4, we have made an exception to this rule.
One of the bugs fixed in Django 1.2.4 involves a set of circumstances whereby a running a test suite on a multiple database configuration could cause the original source database (i.e., the actual production database) to be dropped, causing catastrophic loss of data. In order to provide a fix for this problem, it was necessary to introduce a new setting
–
– that allows you to define any creation order dependencies in your database configuration.
Most users – even users with multiple-database configurations – need not be concerned about the data loss bug, or the manual configuration of
original problem report documentation on
controlling the creation order of test databases
for details.
GeoDjango
The function-based
previously used to execute the GeoDjango test suite, django.contrib.gis.
tests.run_gis_tests
, was finally deprecated in favor of a class-based test runner, django.contrib.gis.
tests.GeoDjangoTestSuiteRunner
, added in this release.
In addition, the GeoDjango test suite is now included when
with runtests.py and using
Django 1.2.3 release notes
Django 1.2.3 fixed a couple of release problems in the 1.2.2 release and was released two days after 1.2.2.
This release corrects the following problems:
• The patch applied for the security issue covered in Django 1.2.2 caused issues with non-ASCII responses using
CSRF tokens.
• The patch also caused issues with some forms, most notably the user-editing forms in the Django administrative interface.
• The packaging manifest did not contain the full list of required files.
Django 1.2.2 release notes
Welcome to Django 1.2.2!
This is the second “bugfix” release in the Django 1.2 series, improving the stability and performance of the Django
1.2 codebase.
Django 1.2.2 maintains backwards compatibility with Django 1.2.1, but contain a number of fixes and other improvements. Django 1.2.2 is a recommended upgrade for any development or deployment currently using or targeting
Django 1.2.
9.1. Final releases 1643
Django Documentation, Release 2.0.dev20170914110741
For full details on the new features, backwards incompatibilities, and deprecated features in the 1.2 branch, see the
One new feature
Ordinarily, a point release would not include new features, but in the case of Django 1.2.2, we have made an exception to this rule.
In order to test a bug fix that forms part of the 1.2.2 release, it was necessary to add a feature – the enforce_csrf_checks flag – to the
test client . This flag forces the test client to perform full CSRF checks
on forms. The default behavior of the test client hasn’t changed, but if you want to do CSRF checks with the test client, it is now possible to do so.
Django 1.2.1 release notes
Django 1.2.1 was released almost immediately after 1.2.0 to correct two small bugs: one was in the documentation packaging script, the other was a bug that affected datetime form field widgets when localization was enabled.
Django 1.2 release notes
May 17, 2010.
Welcome to Django 1.2!
Nearly a year in the making, Django 1.2 packs an impressive list of
and lots of bug fixes. These release notes cover the new features, as well as important changes you’ll want to be aware of when upgrading from Django
1.1 or older versions.
Overview
Django 1.2 introduces several large, important new features, including:
• Support for
in a single Django instance.
•
inspired by Django’s form validation.
• Vastly
improved protection against Cross-Site Request Forgery
(CSRF).
• A new
with support for cookie- and session-based message for both anonymous and authenticated users.
• Hooks for
, permissions for anonymous users
, and more flexible username requirements
• Customization of email sending via
• New
which supports comparison operators.
These are just the highlights; full details and a complete list of features
See also:
Django Advent covered the release of Django 1.2 with a series of articles and tutorials that cover some of the new features in depth.
Wherever possible these features have been introduced in a backwards-compatible manner per
policy.
1644 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
However, a handful of features have changed in ways that, for some users, will be backwards-incompatible. The big changes are:
• Support for Python 2.3 has been dropped. See the full notes below.
• The new CSRF protection framework is not backwards-compatible with the old system. Users of the old system will not be affected until the old system is removed in Django 1.4.
However, upgrading to the new CSRF protection framework requires a few important backwards-incompatible changes, detailed in
• Authors of custom
subclasses should be aware that a number of methods have had a change in prototype, detailed under
get_db_prep_*() methods on Field , below.
• The internals of template tags have changed somewhat; authors of custom template tags that need to store state
(e.g. custom control flow tags) should ensure that their code follows the new rules for
• The
only apply to functions and no longer work on methods. There’s a simple one-line fix
Again, these are just the big features that will affect the most users. Users upgrading from previous versions of Django are heavily encouraged to consult the complete list of
backwards-incompatible changes
and the list of
Python compatibility
While not a new feature, it’s important to note that Django 1.2 introduces the first shift in our Python compatibility policy since Django’s initial public debut. Previous Django releases were tested and supported on 2.x Python versions from 2.3 up; Django 1.2, however, drops official support for Python 2.3. As such, the minimum Python version required for Django is now 2.4, and Django is tested and supported on Python 2.4, 2.5 and 2.6, and will be supported on the as-yet-unreleased Python 2.7.
This change should affect only a small number of Django users, as most operating-system vendors today are shipping
Python 2.4 or newer as their default version. If you’re still using Python 2.3, however, you’ll need to stick to Django
1.1 until you can upgrade; per
our support policy , Django 1.1 will continue to receive security support until the release
of Django 1.3.
A roadmap for Django’s overall 2.x Python support, and eventual transition to Python 3.x, is currently being developed, and will be announced prior to the release of Django 1.3.
What’s new in Django 1.2
Support for multiple databases
Django 1.2 adds the ability to use
in your Django project. Queries can be issued at a specific database with the using() method on QuerySet objects. Individual objects can be saved to a specific database by providing a using argument when you call save().
Model validation
Model instances now have support for
, and both model and form fields now accept config-
urable lists of
specifying reusable, encapsulated validation behavior. Note, however, that validation must still be performed explicitly. Simply invoking a model instance’s save() method will not perform any validation of the instance’s data.
9.1. Final releases 1645
Django Documentation, Release 2.0.dev20170914110741
Improved CSRF protection
Django now has much improved protection against
Cross-Site Request Forgery (CSRF) attacks . This type of attack
occurs when a malicious website contains a link, a form button or some JavaScript that is intended to perform some action on your website, using the credentials of a logged-in user who visits the malicious site in their browser. A related type of attack, “login CSRF,” where an attacking site tricks a user’s browser into logging into a site with someone else’s credentials, is also covered.
Messages framework
Django now includes a robust and configurable
with built-in support for cookie- and sessionbased messaging, for both anonymous and authenticated clients. The messages framework replaces the deprecated user message API and allows you to temporarily store messages in one request and retrieve them for display in a subsequent request (usually the next one).
Object-level permissions
A foundation for specifying permissions at the per-object level has been added. Although there is no implementation of this in core, a custom authentication backend can provide this implementation and it will be used by
for more information.
Permissions for anonymous users
If you provide a custom auth backend with supports_anonymous_user set to True, AnonymousUser will check the backend for permissions, just like User already did. This is useful for centralizing permission handling
- apps can always delegate the question of whether something is allowed or not to the authorization/authentication backend. See the
for more details.
Relaxed requirements for usernames
The built-in
model’s
field now allows a wider range of characters, including @, +, . and - characters.
Email backends
You can now
a configurable email backend to send messages. If your hosting provider uses a sandbox or some other non-SMTP technique for sending mail, you can now construct an email backend that will allow Django’s standard
to use those facilities.
This also makes it easier to debug mail sending. Django ships with backend implementations that allow you to send email to a
file , to the console , or to memory . You can even configure all email to be
“Smart” if tag
The
tag has been upgraded to be much more powerful. First, we’ve added support for comparison operators. No longer will you have to type:
1646 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
{% ifnotequal
a b
%}
...
{% endifnotequal %}
You can now do this:
{% if
a != b
%}
...
{% endif %}
There’s really no reason to use {% ifequal %} or {% ifnotequal %} anymore, unless you’re the nostalgic type.
The operators supported are ==, !=, <, >, <=, >=, in and not in, all of which work like the Python operators, in addition to and, or and not, which were already supported.
Also, filters may now be used in the if expression. For example:
< div
{% if
user.email
| lower ==
message.recipient
| lower %}
class
=
"highlight"
{% endif %}
>
{{
message
}}
</ div >
Template caching
In previous versions of Django, every time you rendered a template, it would be reloaded from disk. In Django 1.2, you can use a
to load templates once, then cache the result for every subsequent render. This can lead to a significant performance improvement if your templates are broken into lots of smaller subtemplates (using the {% extends %} or {% include %} tags).
As a side effect, it is now much easier to support non-Django template languages.
Class-based template loaders
As part of the changes made to introduce
and following a general trend in Django, the template loaders API has been modified to use template loading mechanisms that are encapsulated in Python classes as opposed to functions, the only method available until Django 1.1.
All the template loaders
have been ported to the new API but they still implement the functionbased API and the template core machinery still accepts function-based loaders (builtin or third party) so there is no immediate need to modify your TEMPLATE_LOADERS setting in existing projects, things will keep working if you leave it untouched up to and including the Django 1.3 release.
If you have developed your own custom template loaders we suggest to consider porting them to a class-based implementation because the code for backwards compatibility with function-based loaders starts its deprecation process in
Django 1.2 and will be removed in Django 1.4. There is a description of the API these loader classes must implement in the template API reference and you can also examine the source code of the loaders shipped with Django.
Natural keys in fixtures
Fixtures can now refer to remote objects using
. This lookup scheme is an alternative to the normal
primary-key based object references in a fixture, improving readability and resolving problems referring to objects whose primary key value may not be predictable or known.
9.1. Final releases 1647
Django Documentation, Release 2.0.dev20170914110741
Fast failure for tests
Both the
subcommand of django-admin.py and the runtests.py script used to run Django’s own test suite now support a --failfast option. When specified, this option causes the test runner to exit after encountering a failure instead of continuing with the test run. In addition, the handling of Ctrl-C during a test run has been improved to trigger a graceful exit from the test run that reports details of the tests that were run before the interruption.
BigIntegerField
Models can now use a 64-bit
type.
Improved localization
Django’s
internationalization framework
has been expanded with locale-aware formatting and form processing. That means, if enabled, dates and numbers on templates will be displayed using the format specified for the current locale.
Django will also use localized formats when parsing data in forms. See
for more details.
readonly_fields in ModelAdmin
django.contrib.admin.ModelAdmin.readonly_fields
has been added to enable non-editable fields in add/change pages for models and inlines. Field and calculated values can be displayed alongside editable fields.
Customizable syntax highlighting
You can now use a DJANGO_COLORS environment variable to modify or disable the colors used by django-admin.py
to provide
Syndication feeds as views
can now be used directly as views in your
. This means that you can maintain complete
control over the URL structure of your feeds. Like any other view, feeds views are passed a request object, so you can do anything you would normally do with a view, like user based access control, or making a feed a named URL.
GeoDjango
The most significant new feature for
in 1.2 is support for multiple spatial databases. As a result, the following
are now included:
• django.contrib.gis.db.backends.postgis
• django.contrib.gis.db.backends.mysql
• django.contrib.gis.db.backends.oracle
• django.contrib.gis.db.backends.spatialite
GeoDjango now supports the rich capabilities added in the PostGIS 1.5 release. New features include support for the
and enabling of
with non-point geometries on geographic coordinate systems.
1648 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
Support for 3D geometry fields was added, and may be enabled by setting the
keyword to 3 in your
aggregate and extent3d() GeoQuerySet method were added as a part of this feature.
The force_rhr(), reverse_geom(), and geohash() GeoQuerySet methods are new.
The GEOS interface was updated to use thread-safe C library functions when available on the platform.
The GDAL interface now allows the user to set a
on the features returned when iterating over a
Finally,
is now included with Django’s and is no longer hosted separately at geodjango.org
.
JavaScript-assisted handling of inline related objects in the admin
If a user has JavaScript enabled in their browser, the interface for inline objects in the admin now allows inline objects to be dynamically added and removed. Users without JavaScript-enabled browsers will see no change in the behavior of inline objects.
New now template tag format specifier characters: c and u
The argument to the
has gained two new format characters: c to specify that a datetime value should be formatted in ISO 8601 format, and u that allows output of the microseconds part of a datetime or time value.
These are also available in others parts like the
and
template filters, the humanize template tag library and the new
framework.
Backwards-incompatible changes in 1.2
Wherever possible the new features above have been introduced in a backwards-compatible manner per
policy. This means that practically all existing code which worked with Django 1.1 will continue to work with Django 1.2; such code will, however, begin issuing warnings (see below for details).
However, a handful of features have changed in ways that, for some users, will be immediately backwardsincompatible. Those changes are detailed below.
CSRF Protection
We’ve made large changes to the way CSRF protection works, detailed in
the CSRF documentation . Here are the
major changes you should be aware of:
• CsrfResponseMiddleware and CsrfMiddleware have been deprecated and will be removed completely in Django 1.4, in favor of a template tag that should be inserted into forms.
• All contrib apps use a csrf_protect decorator to protect the view.
This requires the use of the csrf_token template tag in the template. If you have used custom templates for contrib views, you MUST
READ THE UPGRADE INSTRUCTIONS to fix those templates.
Documentation removed
The upgrade notes have been removed in current Django docs. Please refer to the docs for Django 1.3 or older to find these instructions.
9.1. Final releases 1649
Django Documentation, Release 2.0.dev20170914110741
• CsrfViewMiddleware is included in MIDDLEWARE_CLASSES by default. This turns on CSRF protection by default, so views that accept POST requests need to be written to work with the middleware. Instructions on how to do this are found in the CSRF docs.
• All of the CSRF has moved from contrib to core (with backwards compatible imports in the old locations, which are deprecated and will cease to be supported in Django 1.4).
get_db_prep_*() methods on Field
Prior to Django 1.2, a custom Field had the option of defining several functions to support conversion of Python values into database-compatible values. A custom field might look something like:
class CustomModelField
(models.Field):
# ...
def db_type
( self ):
# ...
def get_db_prep_save
( self , value):
# ...
def get_db_prep_value
( self , value):
# ...
def get_db_prep_lookup
( self , lookup_type, value):
# ...
In 1.2, these three methods have undergone a change in prototype, and two extra methods have been introduced:
class CustomModelField
(models.Field):
# ...
def db_type
( self , connection):
# ...
def get_prep_value
( self , value):
# ...
def get_prep_lookup
( self , lookup_type, value):
# ...
def get_db_prep_save
( self , value, connection):
# ...
def get_db_prep_value
( self , value, connection, prepared=False):
# ...
def get_db_prep_lookup
( self , lookup_type, value, connection, prepared=False):
# ...
These changes are required to support multiple databases – db_type and get_db_prep_* can no longer make any assumptions regarding the database for which it is preparing. The connection argument now provides the preparation methods with the specific connection for which the value is being prepared.
The two new methods exist to differentiate general data-preparation requirements from requirements that are databasespecific.
The prepared argument is used to indicate to the database-preparation methods whether generic value preparation has been performed.
If an unprepared (i.e., prepared=False) value is provided to the
1650 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
get_db_prep_*() calls, they should invoke the corresponding get_prep_*() calls to perform generic data preparation.
We’ve provided conversion functions that will transparently convert functions adhering to the old prototype into functions compatible with the new prototype. However, these conversion functions will be removed in Django 1.4, so you should upgrade your Field definitions to use the new prototype as soon as possible.
If your get_db_prep_*() methods made no use of the database connection, you should be able to upgrade by renaming get_db_prep_value() to get_prep_value() and get_db_prep_lookup() to get_prep_lookup()
. If you require database specific conversions, then you will need to provide an implementation get_db_prep_* that uses the connection argument to resolve database-specific values.
Stateful template tags
Template tags that store rendering state on their Node subclass have always been vulnerable to thread-safety and other issues; as of Django 1.2, however, they may also cause problems when used with the new
All of the built-in Django template tags are safe to use with the cached loader, but if you’re using custom template tags that come from third party packages, or from your own code, you should ensure that the Node implementation for each tag is thread-safe. For more information, see
template tag thread safety considerations .
You may also need to update your templates if you were relying on the implementation of Django’s template tags not being thread safe. The
tag is the most likely to be affected in this way, especially when used in conjunction with the
tag. Consider the following template fragment:
{% for object
in
object_list %}
{% include "subtemplate.html"
%
}
{% endfor %} with a subtemplate.html that reads:
{% cycle 'even' 'odd'
%
}
Using the non-thread-safe, pre-Django 1.2 renderer, this would output: even odd even odd ...
Using the thread-safe Django 1.2 renderer, you will instead get: even even even even ...
This is because each rendering of the
tag is an independent rendering. When the
tag was not thread safe, the state of the
tag would leak between multiple renderings of the same
tag is thread safe, this leakage no longer occurs.
user_passes_test
, login_required and permission_required
django.contrib.auth.decorators
provides the decorators login_required , permission_required and user_passes_test.
Previously it was possible to use these decorators both on functions (where the first argument is ‘request’) and on methods (where the first argument is ‘self’, and the second argument is ‘request’). Unfortunately, flaws were discovered in the code supporting this: it only works in limited circumstances, and produces errors that are very difficult to debug when it does not work.
For this reason, the ‘auto adapt’ behavior has been removed, and if you are using these decorators on methods, you will need to manually apply
django.utils.decorators.method_decorator()
to convert the decorator to one that works with methods. For example, you would change code from this:
9.1. Final releases 1651
Django Documentation, Release 2.0.dev20170914110741
class MyClass
( object ):
@login_required
def my_view
( self , request):
pass
to this:
from
django.utils.decorators
import
method_decorator
class MyClass
( object ):
@method_decorator(login_required)
def my_view
( self , request):
pass
or:
from
django.utils.decorators
import
method_decorator login_required_m = method_decorator(login_required)
class MyClass
( object ):
@login_required_m
def my_view
( self , request):
pass
For those of you who’ve been following the development trunk, this change also applies to other decorators introduced since 1.1, including csrf_protect, cache_control and anything created using decorator_from_middleware
.
if tag changes
Due to new features in the
template tag, it no longer accepts ‘and’, ‘or’ and ‘not’ as valid variable names. Previously, these strings could be used as variable names. Now, the keyword status is always enforced, and template code such as {% if not %} or {% if and %} will throw a TemplateSyntaxError. Also, in is a new keyword and so is not a valid variable name in this tag.
LazyObject
LazyObject is an undocumented-but-often-used utility class used for lazily wrapping other objects of unknown type.
In Django 1.1 and earlier, it handled introspection in a non-standard way, depending on wrapped objects implementing a public method named get_all_members(). Since this could easily lead to name clashes, it has been changed to use the standard Python introspection method, involving __members__ and __dir__().
If you used LazyObject in your own code and implemented the get_all_members() method for wrapped objects, you’ll need to make a couple of changes:
First, if your class does not have special requirements for introspection (i.e., you have not implemented
__getattr__() or other methods that allow for attributes not discoverable by normal mechanisms), you can simply remove the get_all_members() method. The default implementation on LazyObject will do the right thing.
1652 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
If you have more complex requirements for introspection, first rename the get_all_members() method to
__dir__()
. This is the standard introspection method for Python 2.6 and above. If you require support for Python versions earlier than 2.6, add the following code to the class:
__members__ = property (lambda self : self
.
__dir__
())
__dict__ on model instances
Historically, the __dict__ attribute of a model instance has only contained attributes corresponding to the fields on a model.
In order to support multiple database configurations, Django 1.2 has added a _state attribute to object instances.
This attribute will appear in __dict__ for a model instance. If your code relies on iterating over __dict__ to obtain a list of fields, you must now be prepared to handle or filter out the _state attribute.
Test runner exit status code
The exit status code of the test runners (tests/runtests.py and python manage.py test) no longer represents the number of failed tests, because a failure of 256 or more tests resulted in a wrong exit status code. The exit status code for the test runner is now 0 for success (no failing tests) and 1 for any number of test failures. If needed, the number of test failures can be found at the end of the test runner’s output.
Cookie encoding
To fix bugs with cookies in Internet Explorer, Safari, and possibly other browsers, our encoding of cookie values was changed so that the comma and semicolon are treated as non-safe characters, and are therefore encoded as \054 and
\073 respectively. This could produce backwards incompatibilities, especially if you are storing comma or semicolon in cookies and have JavaScript code that parses and manipulates cookie values client-side.
ModelForm.is_valid() and ModelForm.errors
Much of the validation work for ModelForms has been moved down to the model level. As a result, the first time you call ModelForm.is_valid(), access ModelForm.errors or otherwise trigger form validation, your model will be cleaned in-place. This conversion used to happen when the model was saved. If you need an unmodified instance of your model, you should pass a copy to the ModelForm constructor.
BooleanField on MySQL
In previous versions of Django, a model’s BooleanField under MySQL would return its value as either 1 or 0, instead of True or False; for most people this wasn’t a problem because bool is a subclass of int in Python. In
Django 1.2, however, BooleanField on MySQL correctly returns a real bool. The only time this should ever be an issue is if you were expecting the repr of a BooleanField to print 1 or 0.
Changes to the interpretation of max_num in FormSets
As part of enhancements made to the handling of FormSets, the default value and interpretation of the max_num parameter to the
django.forms.formsets.formset_factory()
and
django.forms.models.modelformset_factory()
functions has changed slightly. This change also affects the way the
argument is used for inline admin objects.
9.1. Final releases 1653
Django Documentation, Release 2.0.dev20170914110741
Previously, the default value for max_num was 0 (zero). FormSets then used the boolean value of max_num to determine if a limit was to be imposed on the number of generated forms. The default value of 0 meant that there was no default limit on the number of forms in a FormSet.
Starting with 1.2, the default value for max_num has been changed to None, and FormSets will differentiate between a value of None and a value of 0. A value of None indicates that no limit on the number of forms is to be imposed; a value of 0 indicates that a maximum of 0 forms should be imposed. This doesn’t necessarily mean that no forms will be displayed – see the
for more details.
If you were manually specifying a value of 0 for max_num, you will need to update your FormSet and/or admin definitions.
See also:
JavaScript-assisted handling of inline related objects in the admin
email_re
An undocumented regular expression for validating email addresses has been moved from django.form.fields
to django.core.validators. You will need to update your imports if you are using it.
Features deprecated in 1.2
Finally, Django 1.2 deprecates some features from earlier releases. These features are still supported, but will be gradually phased out over the next few release cycles.
Code taking advantage of any of the features below will raise a PendingDeprecationWarning in Django 1.2.
This warning will be silent by default, but may be turned on using Python’s warnings module, or by running Python with a -Wd or -Wall flag.
In Django 1.3, these warnings will become a DeprecationWarning, which is not silent. In Django 1.4 support for these features will be removed entirely.
See also:
For more details, see the documentation
and our
Specifying databases
Prior to Django 1.2, Django used a number of settings to control access to a single database. Django 1.2 introduces support for multiple databases, and as a result the way you define database settings has changed.
Any existing Django settings file will continue to work as expected until Django 1.4. Until then, old-style database settings will be automatically translated to the new-style format.
In the old-style (pre 1.2) format, you had a number of DATABASE_ settings in your settings file. For example:
DATABASE_NAME = 'test_db'
DATABASE_ENGINE = 'postgresql_psycopg2'
DATABASE_USER = 'myusername'
DATABASE_PASSWORD = 's3krit'
These settings are now in a dictionary named
. Each item in the dictionary corresponds to a single
database connection, with the name 'default' describing the default database connection. The setting names have also been shortened. The previous sample settings would now look like this:
1654 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
DATABASES = {
'default' : {
'NAME' : 'test_db' ,
'ENGINE' : 'django.db.backends.postgresql_psycopg2' ,
'USER' : 'myusername' ,
'PASSWORD' : 's3krit' ,
}
}
This affects the following settings:
Old setting
DATABASE_ENGINE
DATABASE_HOST
New Setting
DATABASE_NAME
DATABASE_OPTIONS
DATABASE_PASSWORD
DATABASE_PORT
DATABASE_USER
TEST_DATABASE_CHARSET
TEST_DATABASE_COLLATION
TEST_DATABASE_NAME
These changes are also required if you have manually created a database connection using DatabaseWrapper() from your database backend of choice.
In addition to the change in structure, Django 1.2 removes the special handling for the built-in database backends.
All database backends must now be specified by a fully qualified module name (i.e., django.db.backends.
postgresql_psycopg2
, rather than just postgresql_psycopg2).
postgresql database backend
The psycopg1 library has not been updated since October 2005. As a result, the postgresql database backend, which uses this library, has been deprecated.
If you are currently using the postgresql backend, you should migrate to using the postgresql_psycopg2 backend. To update your code, install the psycopg2 library and change the
setting to use django.db.
backends.postgresql_psycopg2
.
CSRF response-rewriting middleware
CsrfResponseMiddleware
, the middleware that automatically inserted CSRF tokens into POST forms in outgoing pages, has been deprecated in favor of a template tag method (see above), and will be removed completely in Django 1.4. CsrfMiddleware, which includes the functionality of CsrfResponseMiddleware and CsrfViewMiddleware, has likewise been deprecated.
Also, the CSRF module has moved from contrib to core, and the old imports are deprecated, as described in the upgrading notes.
Documentation removed
The upgrade notes have been removed in current Django docs. Please refer to the docs for Django 1.3 or older to find these instructions.
9.1. Final releases 1655
Django Documentation, Release 2.0.dev20170914110741
SMTPConnection
The SMTPConnection class has been deprecated in favor of a generic email backend API. Old code that explicitly instantiated an instance of an SMTPConnection:
from
django.core.mail
import
SMTPConnection connection = SMTPConnection() messages = get_notification_email() connection.send_messages(messages)
...should now call
to instantiate a generic email connection:
from
django.core.mail
import
get_connection connection = get_connection() messages = get_notification_email() connection.send_messages(messages)
Depending on the value of the
setting, this may not return an SMTP connection. If you explicitly require an SMTP connection with which to send email, you can explicitly request an SMTP connection:
from
django.core.mail
import
get_connection connection = get_connection( 'django.core.mail.backends.smtp.EmailBackend' ) messages = get_notification_email() connection.send_messages(messages)
If your call to construct an instance of SMTPConnection required additional arguments, those arguments can be passed to the
call: connection = get_connection( 'django.core.mail.backends.smtp.EmailBackend' , hostname=
˓→
'localhost' , port= 1234 )
User Messages API
The API for storing messages in the user Message model (via user.message_set.create) is now deprecated and will be removed in Django 1.4 according to the standard
To upgrade your code, you need to replace any instances of this: user.message_set.create( 'a message' )
...with the following:
from
django.contrib
import
messages messages.add_message(request, messages.INFO, 'a message' )
Additionally, if you make use of the method, you need to replace the following:
for
message in user.get_and_delete_messages():
...
...with:
from
django.contrib
import
messages
for
message in messages.get_messages(request):
...
1656 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
For more information, see the full
messages documentation . You should begin to update your code to use the new API
immediately.
Date format helper functions
django.utils.translation.get_date_formats() and django.utils.translation.
get_partial_date_formats() have been deprecated in favor of the appropriate calls to django.
utils.formats.get_format() , which is locale-aware when
is set to True, and falls back to default settings if set to False.
To get the different date formats, instead of writing this:
from
django.utils.translation
import
get_date_formats date_format, datetime_format, time_format = get_date_formats()
...use:
from
django.utils
import
formats date_format = formats.get_format( 'DATE_FORMAT' ) datetime_format = formats.get_format( 'DATETIME_FORMAT' ) time_format = formats.get_format( 'TIME_FORMAT' )
Or, when directly formatting a date value:
from
django.utils
import
formats value_formatted = formats.date_format(value, 'DATETIME_FORMAT' )
The same applies to the globals found in django.forms.fields:
• DEFAULT_DATE_INPUT_FORMATS
• DEFAULT_TIME_INPUT_FORMATS
• DEFAULT_DATETIME_INPUT_FORMATS
Use django.utils.formats.get_format() to get the appropriate formats.
Function-based test runners
Django 1.2 changes the test runner tools to use a class-based approach. Old style function-based test runners will still work, but should be updated to use the new
Feed in django.contrib.syndication.feeds
The django.contrib.syndication.feeds.Feed class has been replaced by the
class. The old feeds.Feed class is deprecated, and will be removed in Django
1.4.
The new class has an almost identical API, but allows instances to be used as views. For example, consider the use of the old framework in the following
from
django.conf.urls.defaults
import * from
myproject.feeds
import
LatestEntries, LatestEntriesByCategory feeds = {
'latest' : LatestEntries,
9.1. Final releases 1657
Django Documentation, Release 2.0.dev20170914110741
'categories' : LatestEntriesByCategory,
} urlpatterns = patterns( '' ,
# ...
( r'^feeds/(?P<url>.*)/$' , 'django.contrib.syndication.views.feed' ,
{ 'feed_dict' : feeds}),
# ...
)
Using the new Feed class, these feeds can be deployed directly as views:
from
django.conf.urls.defaults
import * from
myproject.feeds
import
LatestEntries, LatestEntriesByCategory urlpatterns = patterns( '' ,
# ...
( r'^feeds/latest/$' , LatestEntries()),
( r'^feeds/categories/(?P<category_id>\d+)/$' , LatestEntriesByCategory()),
# ...
)
If you currently use the feed() view, the LatestEntries class would often not need to be modified apart from subclassing the new
class. The exception is if Django was automatically working out the name of the template to use to render the feed’s description and title elements (if you were not specifying the title_template and description_template attributes). You should ensure that you always specify title_template and description_template attributes, or provide item_title() and item_description() methods.
However, LatestEntriesByCategory uses the get_object() method with the bits argument to specify a specific category to show. In the new
class, get_object() method takes a request and arguments from the URL, so it would look like this:
from
django.contrib.syndication.views
import
Feed
from
django.shortcuts
import
get_object_or_404
from
myproject.models
import
Category
class LatestEntriesByCategory
(Feed):
def get_object
( self , request, category_id):
return
get_object_or_404(Category, id
=
category_id)
# ...
Additionally, the get_feed() method on Feed classes now take different arguments, which may impact you if you use the Feed classes directly. Instead of just taking an optional url argument, it now takes two arguments: the object returned by its own get_object() method, and the current request object.
To take into account Feed classes not being initialized for each request, the __init__() method now takes no arguments by default. Previously it would have taken the slug from the URL and the request object.
In accordance with RSS best practices , RSS feeds will now include an atom:link element. You may need to update your tests to take this into account.
For more information, see the full
syndication framework documentation .
1658 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
Technical message IDs
Up to version 1.1 Django used technical message IDs to provide localizers the possibility to translate date and time formats. They were translatable
that could be recognized because they were all upper case (for example
TIME_FORMAT ). They have been deprecated in favor of the new
infrastructure that allows localizers to specify that information in a formats.py file in the corresponding django/conf/locale/<locale name>/ directory.
GeoDjango
To allow support for multiple databases, the GeoDjango database internals were changed substantially.
The largest backwards-incompatible change is that the module django.contrib.gis.db.backend was renamed to
django.contrib.gis.db.backends
, where the full-fledged spatial database backends
now exist. The following sections provide information on the most-popular APIs that were affected by these changes.
SpatialBackend
Prior to the creation of the separate spatial backends, the django.contrib.gis.db.backend.
SpatialBackend object was provided as an abstraction to introspect on the capabilities of the spatial database.
All of the attributes and routines provided by SpatialBackend are now a part of the ops attribute of the database backend.
The old module django.contrib.gis.db.backend is still provided for backwards-compatibility access to a
SpatialBackend object, which is just an alias to the ops module of the default spatial database connection.
Users that were relying on undocumented modules and objects within django.contrib.gis.db.backend, rather the abstractions provided by SpatialBackend, are required to modify their code. For example, the following import which would work in 1.1 and below:
from
django.contrib.gis.db.backend.postgis
import
PostGISAdaptor
Would need to be changed:
from
django.db
import
connection
PostGISAdaptor = connection.ops.Adapter
SpatialRefSys and GeometryColumns models
In previous versions of GeoDjango,
had SpatialRefSys and
GeometryColumns models for querying the OGC spatial metadata tables spatial_ref_sys and geometry_columns
, respectively.
While these aliases are still provided, they are only for the default database connection and exist only if the default connection is using a supported spatial database backend.
Note: Because the table structure of the OGC spatial metadata tables differs across spatial databases, the
SpatialRefSys and GeometryColumns models can no longer be associated with the gis application name.
Thus, no models will be returned when using the get_models method in the following example:
>>>
from
django.db.models
import
get_app, get_models
>>> get_models(get_app( 'gis' ))
[]
9.1. Final releases 1659
Django Documentation, Release 2.0.dev20170914110741
To get the correct SpatialRefSys and GeometryColumns for your spatial database use the methods provided by the spatial backend:
>>>
from
django.db
import
connections
>>> SpatialRefSys = connections[ 'my_spatialite' ].ops.spatial_ref_sys()
>>> GeometryColumns = connections[ 'my_postgis' ].ops.geometry_columns()
Note: When using the models returned from the spatial_ref_sys() and geometry_columns() method, you’ll still need to use the correct database alias when querying on the non-default connection. In other words, to ensure that the models in the example above use the correct database: sr_qs = SpatialRefSys.objects.using( 'my_spatialite' ).filter(...) gc_qs = GeometryColumns.objects.using( 'my_postgis' ).filter(...)
Language code no
The currently used language code for Norwegian Bokmål no is being replaced by the more common language code nb
.
Function-based template loaders
Django 1.2 changes the template loading mechanism to use a class-based approach. Old style function-based template loaders will still work, but should be updated to use the new class-based template loaders.
1.1 release
Django 1.1.4 release notes
Welcome to Django 1.1.4!
This is the fourth “bugfix” release in the Django 1.1 series, improving the stability and performance of the Django 1.1
codebase.
With one exception, Django 1.1.4 maintains backwards compatibility with Django 1.1.3. It also contains a number of fixes and other improvements. Django 1.1.4 is a recommended upgrade for any development or deployment currently using or targeting Django 1.1.
For full details on the new features, backwards incompatibilities, and deprecated features in the 1.1 branch, see the
Backwards incompatible changes
CSRF exception for AJAX requests
Django includes a CSRF-protection mechanism, which makes use of a token inserted into outgoing forms. Middleware then checks for the token’s presence on form submission, and validates it.
Prior to Django 1.2.5, our CSRF protection made an exception for AJAX requests, on the following basis:
1660 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
• Many AJAX toolkits add an X-Requested-With header when using XMLHttpRequest.
• Browsers have strict same-origin policies regarding XMLHttpRequest.
• In the context of a browser, the only way that a custom header of this nature can be added is with XMLHttpRequest.
Therefore, for ease of use, we did not apply CSRF checks to requests that appeared to be AJAX on the basis of the
X-Requested-With header. The Ruby on Rails web framework had a similar exemption.
Recently, engineers at Google made members of the Ruby on Rails development team aware of a combination of browser plugins and redirects which can allow an attacker to provide custom HTTP headers on a request to any website. This can allow a forged request to appear to be an AJAX request, thereby defeating CSRF protection which trusts the same-origin nature of AJAX requests.
Michael Koziarski of the Rails team brought this to our attention, and we were able to produce a proof-of-concept demonstrating the same vulnerability in Django’s CSRF handling.
To remedy this, Django will now apply full CSRF validation to all requests, regardless of apparent AJAX origin. This is technically backwards-incompatible, but the security risks have been judged to outweigh the compatibility concerns in this case.
Additionally, Django will now accept the CSRF token in the custom HTTP header X-CSRFTOKEN, as well as in the form submission itself, for ease of use with popular JavaScript toolkits which allow insertion of custom headers into all AJAX requests.
Please see the
CSRF docs for example jQuery code
that demonstrates this technique, ensuring that you are looking at the documentation for your version of Django, as the exact code necessary is different for some older versions of
Django.
Django 1.1.3 release notes
Welcome to Django 1.1.3!
This is the third “bugfix” release in the Django 1.1 series, improving the stability and performance of the Django 1.1
codebase.
With one exception, Django 1.1.3 maintains backwards compatibility with Django 1.1.2. It also contains a number of fixes and other improvements. Django 1.1.2 is a recommended upgrade for any development or deployment currently using or targeting Django 1.1.
For full details on the new features, backwards incompatibilities, and deprecated features in the 1.1 branch, see the
Backwards incompatible changes
Restricted filters in admin interface
The Django administrative interface, django.contrib.admin, supports filtering of displayed lists of objects by fields on the corresponding models, including across database-level relationships. This is implemented by passing lookup arguments in the querystring portion of the URL, and options on the ModelAdmin class allow developers to specify particular fields or relationships which will generate automatic links for filtering.
One historically-undocumented and -unofficially-supported feature has been the ability for a user with sufficient knowledge of a model’s structure and the format of these lookup arguments to invent useful new filters on the fly by manipulating the querystring.
9.1. Final releases 1661
Django Documentation, Release 2.0.dev20170914110741
However, it has been demonstrated that this can be abused to gain access to information outside of an admin user’s permissions; for example, an attacker with access to the admin and sufficient knowledge of model structure and relations could construct query strings which – with repeated use of regular-expression lookups supported by the
Django database API – expose sensitive information such as users’ password hashes.
To remedy this, django.contrib.admin will now validate that querystring lookup arguments either specify only fields on the model being viewed, or cross relations which have been explicitly whitelisted by the application developer using the pre-existing mechanism mentioned above. This is backwards-incompatible for any users relying on the prior ability to insert arbitrary lookups.
Django 1.1.2 release notes
Welcome to Django 1.1.2!
This is the second “bugfix” release in the Django 1.1 series, improving the stability and performance of the Django
1.1 codebase.
Django 1.1.2 maintains backwards compatibility with Django 1.1.0, but contain a number of fixes and other improvements. Django 1.1.2 is a recommended upgrade for any development or deployment currently using or targeting
Django 1.1.
For full details on the new features, backwards incompatibilities, and deprecated features in the 1.1 branch, see the
Backwards-incompatible changes in 1.1.2
Test runner exit status code
The exit status code of the test runners (tests/runtests.py and python manage.py test) no longer represents the number of failed tests, since a failure of 256 or more tests resulted in a wrong exit status code. The exit status code for the test runner is now 0 for success (no failing tests) and 1 for any number of test failures. If needed, the number of test failures can be found at the end of the test runner’s output.
Cookie encoding
To fix bugs with cookies in Internet Explorer, Safari, and possibly other browsers, our encoding of cookie values was changed so that the characters comma and semi-colon are treated as non-safe characters, and are therefore encoded as
\054 and \073 respectively. This could produce backwards incompatibilities, especially if you are storing comma or semi-colon in cookies and have JavaScript code that parses and manipulates cookie values client-side.
One new feature
Ordinarily, a point release would not include new features, but in the case of Django 1.1.2, we have made an exception to this rule. Django 1.2 (the next major release of Django) will contain a feature that will improve protection against
Cross-Site Request Forgery (CSRF) attacks. This feature requires the use of a new
template tag in all forms that Django renders.
To make it easier to support both 1.1.X and 1.2.X versions of Django with the same templates, we have decided to introduce the
template tag to the 1.1.X branch. In the 1.1.X branch,
does nothing - it has no effect on templates or form processing. However, it means that the same template will work with Django 1.2.
1662 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
Django 1.1 release notes
July 29, 2009
Welcome to Django 1.1!
Django 1.1 includes a number of nifty
new features , lots of bug fixes, and an easy upgrade path from Django 1.0.
Backwards-incompatible changes in 1.1
Django has a policy of
API stability . This means that, in general, code you develop against Django 1.0 should continue
to work against 1.1 unchanged. However, we do sometimes make backwards-incompatible changes if they’re necessary to resolve bugs, and there are a handful of such (minor) changes between Django 1.0 and Django 1.1.
Before upgrading to Django 1.1 you should double-check that the following changes don’t impact you, and upgrade your code if they do.
Changes to constraint names
Django 1.1 modifies the method used to generate database constraint names so that names are consistent regardless of machine word size. This change is backwards incompatible for some users.
If you are using a 32-bit platform, you’re off the hook; you’ll observe no differences as a result of this change.
However, users on 64-bit platforms may experience some problems using the reset management command. Prior to this change, 64-bit platforms would generate a 64-bit, 16 character digest in the constraint name; for example:
ALTER TABLE myapp_sometable ADD CONSTRAINT object_id_refs_id_5e8f10c132091d1e FOREIGN
˓→
KEY ...
Following this change, all platforms, regardless of word size, will generate a 32-bit, 8 character digest in the constraint name; for example:
ALTER TABLE myapp_sometable ADD CONSTRAINT object_id_refs_id_32091d1e FOREIGN KEY ...
As a result of this change, you will not be able to use the reset management command on any table made by a 64-bit machine. This is because the new generated name will not match the historically generated name; as a result, the SQL constructed by the reset command will be invalid.
If you need to reset an application that was created with 64-bit constraints, you will need to manually drop the old constraint prior to invoking reset.
Test cases are now run in a transaction
Django 1.1 runs tests inside a transaction, allowing better test performance (see
for details).
This change is slightly backwards incompatible if existing tests need to test transactional behavior, if they rely on invalid assumptions about the test environment, or if they require a specific test case ordering.
For these cases,
can be used instead. This is a just a quick fix to get around test case errors revealed by the new rollback approach; in the long-term tests should be rewritten to correct the test case.
9.1. Final releases 1663
Django Documentation, Release 2.0.dev20170914110741
Removed SetRemoteAddrFromForwardedFor middleware
For convenience, Django 1.0 included an optional middleware class – django.middleware.http.
SetRemoteAddrFromForwardedFor – which updated the value of REMOTE_ADDR based on the HTTP
X-Forwarded-For header commonly set by some proxy configurations.
It has been demonstrated that this mechanism cannot be made reliable enough for general-purpose use, and that
(despite documentation to the contrary) its inclusion in Django may lead application developers to assume that the value of REMOTE_ADDR is “safe” or in some way reliable as a source of authentication.
While not directly a security issue, we’ve decided to remove this middleware with the Django 1.1 release. It has been replaced with a class that does nothing other than raise a DeprecationWarning.
If you’ve been relying on this middleware, the easiest upgrade path is:
• Examine the code as it existed before it was removed .
• Verify that it works correctly with your upstream proxy, modifying it to support your particular proxy (if necessary).
• Introduce your modified version of SetRemoteAddrFromForwardedFor as a piece of middleware in your own project.
Names of uploaded files are available later
In Django 1.0, files uploaded and stored in a model’s
were saved to disk before the model was saved to the database. This meant that the actual file name assigned to the file was available before saving. For example, it was available in a model’s pre-save signal handler.
In Django 1.1 the file is saved as part of saving the model in the database, so the actual file name used on disk cannot be relied on until after the model has been saved.
Changes to how model formsets are saved
In Django 1.1,
now calls ModelForm.save().
This is backwards-incompatible if you were modifying self.initial in a model formset’s __init__, or if you relied on the internal _total_form_count or _initial_form_count attributes of BaseFormSet. Those attributes are now public methods.
Fixed the join filter’s escaping behavior
The
filter no longer escapes the literal value that is passed in for the connector.
This is backwards incompatible for the special situation of the literal string containing one of the five special HTML characters. Thus, if you were writing {{ foo|join:"&" }}, you now have to write {{ foo|join:"&"
}}
.
The previous behavior was a bug and contrary to what was documented and expected.
Permanent redirects and the redirect_to() generic view
Django 1.1 adds a permanent argument to the django.views.generic.simple.redirect_to() view.
This is technically backwards-incompatible if you were using the redirect_to view with a format-string key called
‘permanent’, which is highly unlikely.
1664 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
Features deprecated in 1.1
One feature has been marked as deprecated in Django 1.1:
• You should no longer use AdminSite.root() to register that admin views. That is, if your URLconf contains the line:
( r'^admin/(.*)' , admin.site.root),
You should change it to read:
( r'^admin/' , include(admin.site.urls)),
You should begin to remove use of this feature from your code immediately.
AdminSite.root
will raise a PendingDeprecationWarning if used in Django 1.1. This warning is hidden by default. In Django 1.2, this warning will be upgraded to a DeprecationWarning, which will be displayed loudly. Django 1.3 will remove AdminSite.root() entirely.
For more details on our deprecation policies and strategy, see
What’s new in Django 1.1
Quite a bit: since Django 1.0, we’ve made 1,290 code commits, fixed 1,206 bugs, and added roughly 10,000 lines of documentation.
The major new features in Django 1.1 are:
ORM improvements
Two major enhancements have been added to Django’s object-relational mapper (ORM): aggregate support, and query expressions.
Aggregate support
It’s now possible to run SQL aggregate queries (i.e. COUNT(), MAX(), MIN(), etc.) from within Django’s ORM.
You can choose to either return the results of the aggregate directly, or else annotate the objects in a
with the results of the aggregate query.
This feature is available as new
and
methods, and is covered in detail in
the ORM aggregation documentation
Query expressions
Queries can now refer to a another field on the query and can traverse relationships to refer to fields on related models. This is implemented in the new
object; for full details, including examples, consult the
Model improvements
A number of features have been added to Django’s model layer:
9.1. Final releases 1665
Django Documentation, Release 2.0.dev20170914110741
“Unmanaged” models
You can now control whether or not Django manages the life-cycle of the database tables for a model using the
model option. This defaults to True, meaning that Django will create the appropriate database tables in syncdb and remove them as part of the reset command. That is, Django manages the database table’s lifecycle.
If you set this to False, however, no database table creating or deletion will be automatically performed for this model. This is useful if the model represents an existing table or a database view that has been created by some other means.
For more details, see the documentation for the
option.
Proxy models
You can now create
proxy models : subclasses of existing models that only add Python-level (rather than database-
level) behavior and aren’t represented by a new table. That is, the new model is a proxy for some underlying model, which stores all the real data.
All the details can be found in the
proxy models documentation . This feature is similar on the surface to unmanaged
models, so the documentation has an explanation of
how proxy models differ from unmanaged models .
Deferred fields
In some complex situations, your models might contain fields which could contain a lot of data (for example, large text fields), or require expensive processing to convert them to Python objects. If you know you don’t need those particular fields, you can now tell Django not to retrieve them from the database.
You’ll do this with the new queryset methods
and
Testing improvements
A few notable improvements have been made to the
Test performance improvements
Tests written using Django’s
now run dramatically faster (as much as 10 times faster in many cases).
This was accomplished through the introduction of transaction-based tests: when using
your tests will now be run in a transaction which is rolled back when finished, instead of by flushing and re-populating the database. This results in an immense speedup for most types of unit tests. See the documentation for
and
for a full description, and some important notes on database support.
Test client improvements
A couple of small – but highly useful – improvements have been made to the test client:
• The test
now can automatically follow redirects with the follow argument to
and
. This makes testing views that issue redirects simpler.
• It’s now easier to get at the template context in the response returned the test client: you’ll simply access the context as request.context[key]. The old way, which treats request.context as a list of contexts, one for each rendered template in the inheritance chain, is still available if you need it.
1666 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
New admin features
Django 1.1 adds a couple of nifty new features to Django’s admin interface:
Editable fields on the change list
You can now make fields editable on the admin list views via the new
admin option. These fields will show up as form widgets on the list pages, and can be edited and saved in bulk.
Admin “actions”
You can now define
that can perform some action to a group of models in bulk. Users will be able to select objects on the change list page and then apply these bulk actions to all selected objects.
Django ships with one pre-defined admin action to delete a group of objects in one fell swoop.
Conditional view processing
Django now has much better support for
using the standard ETag and Last-Modified
HTTP headers. This means you can now easily short-circuit view processing by testing less-expensive conditions. For many views this can lead to a serious improvement in speed and reduction in bandwidth.
URL namespaces
Django 1.1 improves
with the introduction of URL “namespaces.”
In short, this feature allows the same group of URLs, from the same application, to be included in a Django URLConf multiple times, with varying (and potentially nested) named prefixes which will be used when performing reverse resolution. In other words, reusable applications like Django’s admin interface may be registered multiple times without URL conflicts.
For full details, see
the documentation on defining URL namespaces
GeoDjango
In Django 1.1, GeoDjango (i.e. django.contrib.gis) has several new features:
• Support for SpatiaLite – a spatial database for SQLite – as a spatial backend.
• Geographic aggregates (Collect, Extent, MakeLine, Union) and F expressions.
• New GeoQuerySet methods: collect, geojson, and snap_to_grid.
• A new list interface methods for GEOSGeometry objects.
For more details, see the GeoDjango documentation.
Other improvements
Other new features and changes introduced since Django 1.0 include:
9.1. Final releases 1667
Django Documentation, Release 2.0.dev20170914110741
• The
has been split into two classes – CsrfViewMiddleware checks incoming requests, and CsrfResponseMiddleware processes outgoing responses.
The combined
CsrfMiddleware class (which does both) remains for backwards-compatibility, but using the split classes is now recommended in order to allow fine-grained control of when and where the CSRF processing takes place.
• reverse() and code which uses it (e.g., the {% url %} template tag) now works with URLs in Django’s administrative site, provided that the admin URLs are set up via include(admin.site.urls) (sending admin requests to the admin.site.root view still works, but URLs in the admin will not be “reversible” when configured this way).
• The include() function in Django URLconf modules can now accept sequences of URL patterns (generated by patterns()) in addition to module names.
• Instances of Django forms (see
the forms overview ) now have two additional methods, hidden_fields()
and visible_fields(), which return the list of hidden – i.e., <input type="hidden"> – and visible fields on the form, respectively.
• The redirect_to generic view now accepts an additional keyword argument permanent. If permanent is True, the view will emit an HTTP permanent redirect (status code 301). If False, the view will emit an
HTTP temporary redirect (status code 302).
• A new database lookup type – week_day – has been added for DateField and DateTimeField. This type of lookup accepts a number between 1 (Sunday) and 7 (Saturday), and returns objects where the field value matches that day of the week. See
for details.
• The {% for %} tag in Django’s template language now accepts an optional {% empty %} clause, to be displayed when {% for %} is asked to loop over an empty sequence. See
the list of built-in template tags
for examples of this.
• The
management command now accepts individual model names as arguments, allowing you to export the data just from particular models.
• There’s a new
template filter which works just like
for lists, marking each item in the list as safe.
•
now support incr() and decr() commands to increment and decrement the value of a cache key. On cache backends that support atomic increment/decrement – most notably, the memcached backend – these operations will be atomic, and quite fast.
• Django now can
easily delegate authentication to the Web server
via a new authentication backend that supports the standard REMOTE_USER environment variable used for this purpose.
• There’s a new
function that makes it easier to issue redirects given an object, a view name, or a URL.
• The postgresql_psycopg2 backend now supports
native PostgreSQL autocommit . This is an advanced,
PostgreSQL-specific feature, that can make certain read-heavy applications a good deal faster.
What’s next?
We’ll take a short break, and then work on Django 1.2 will begin – no rest for the weary! If you’d like to help, discussion of Django development, including progress toward the 1.2 release, takes place daily on the
mailing list and in the #django-dev IRC channel on irc.freenode.net. Feel free to join the discussions!
Django’s online documentation also includes pointers on how to contribute to Django:
•
Contributions on any level – developing code, writing documentation or simply triaging tickets and helping to test proposed bugfixes – are always welcome and appreciated.
1668 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
And that’s the way it is.
1.0 release
Django 1.0.2 release notes
Welcome to Django 1.0.2!
This is the second “bugfix” release in the Django 1.0 series, improving the stability and performance of the Django
1.0 codebase. As such, Django 1.0.2 contains no new features (and, pursuant to
our compatibility policy , maintains
backwards compatibility with Django 1.0.0), but does contain a number of fixes and other improvements. Django
1.0.2 is a recommended upgrade for any development or deployment currently using or targeting Django 1.0.
Fixes and improvements in Django 1.0.2
The primary reason behind this release is to remedy an issue in the recently-released Django 1.0.1; the packaging scripts used for Django 1.0.1 omitted some directories from the final release package, including one directory required by django.contrib.gis and part of Django’s unit-test suite.
Django 1.0.2 contains updated packaging scripts, and the release package contains the directories omitted from Django
1.0.1. As such, this release contains all of the fixes and improvements from Django 1.0.1; see
the Django 1.0.1 release notes
for details.
Additionally, in the period since Django 1.0.1 was released:
• Updated Hebrew and Danish translations have been added.
• The default __repr__ method of Django models has been made more robust in the face of bad Unicode data coming from the __unicode__ method; rather than raise an exception in such cases, repr() will now contain the string “[Bad Unicode data]” in place of the invalid Unicode.
• A bug involving the interaction of Django’s SafeUnicode class and the MySQL adapter has been resolved;
SafeUnicode instances (generated, for example, by template rendering) can now be assigned to model attributes and saved to MySQL without requiring an explicit intermediate cast to unicode.
• A bug affecting filtering on a nullable DateField in SQLite has been resolved.
• Several updates and improvements have been made to Django’s documentation.
Django 1.0.1 release notes
Welcome to Django 1.0.1!
This is the first “bugfix” release in the Django 1.0 series, improving the stability and performance of the Django
1.0 codebase. As such, Django 1.0.1 contains no new features (and, pursuant to
backwards compatibility with Django 1.0), but does contain a number of fixes and other improvements. Django 1.0.1
is a recommended upgrade for any development or deployment currently using or targeting Django 1.0.
Fixes and improvements in Django 1.0.1
Django 1.0.1 contains over two hundred fixes to the original Django 1.0 codebase; full details of every fix are available in the history of the 1.0.X branch , but here are some of the highlights:
• Several fixes in django.contrib.comments, pertaining to RSS feeds of comments, default ordering of comments and the XHTML and internationalization of the default templates for comments.
9.1. Final releases 1669
Django Documentation, Release 2.0.dev20170914110741
• Multiple fixes for Django’s support of Oracle databases, including pagination support for GIS QuerySets, more efficient slicing of results and improved introspection of existing databases.
• Several fixes for query support in the Django object-relational mapper, including repeated setting and resetting of ordering and fixes for working with INSERT-only queries.
• Multiple fixes for inline forms in formsets.
• Multiple fixes for unique and unique_together model constraints in automatically-generated forms.
• Fixed support for custom callable upload_to declarations when handling file uploads through automaticallygenerated forms.
• Fixed support for sorting an admin change list based on a callable attributes in list_display.
• A fix to the application of autoescaping for literal strings passed to the join template filter. Previously, literal strings passed to join were automatically escaped, contrary to
manually escape them; this is an incompatibility if you were relying on this bug, but not if you were relying on escaping behaving as documented.
• Improved and expanded translation files for many of the languages Django supports by default.
• And as always, a large number of improvements to Django’s documentation, including both corrections to existing documents and expanded and new documentation.
Django 1.0 release notes
Welcome to Django 1.0!
We’ve been looking forward to this moment for over three years, and it’s finally here. Django 1.0 represents the largest milestone in Django’s development to date: a Web framework that a group of perfectionists can truly be proud of.
Django 1.0 represents over three years of community development as an Open Source project. Django’s received contributions from hundreds of developers, been translated into fifty languages, and today is used by developers on every continent and in every kind of job.
An interesting historical note: when Django was first released in July 2005, the initial released version of Django came from an internal repository at revision number 8825. Django 1.0 represents revision 8961 of our public repository. It seems fitting that our 1.0 release comes at the moment where community contributions overtake those made privately.
Stability and forwards-compatibility
The release of Django 1.0 comes with a promise of API stability and forwards-compatibility. In a nutshell, this means that code you develop against Django 1.0 will continue to work against 1.1 unchanged, and you should need to make only minor changes for any 1.X release.
See the
for full details.
Backwards-incompatible changes
Django 1.0 has a number of backwards-incompatible changes from Django 0.96. If you have apps written against
Django 0.96 that you need to port, see our detailed porting guide:
1670 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
Porting your apps from Django 0.96 to 1.0
Django 1.0 breaks compatibility with 0.96 in some areas.
This guide will help you port 0.96 projects and apps to 1.0. The first part of this document includes the common changes needed to run with 1.0. If after going through the first part your code still breaks, check the section
for a list of a bunch of less-common compatibility issues.
See also:
The
cerned with helping you quickly update your code.
Common changes
This section describes the changes between 0.96 and 1.0 that most users will need to make.
Use Unicode
Change string literals ('foo') into Unicode literals (u'foo'). Django now uses Unicode strings throughout. In most places, raw strings will continue to work, but updating to use Unicode literals will prevent some obscure problems.
See
for full details.
Models
Common changes to your models file:
Rename maxlength to max_length
Rename your maxlength argument to max_length (this was changed to be consistent with form fields):
Replace __str__ with __unicode__
Replace your model’s __str__ function with a __unicode__ method, and make sure you
(u'foo') in that method.
Remove prepopulated_from
Remove the prepopulated_from argument on model fields. It’s no longer valid and has been moved to the
ModelAdmin class in admin.py. See
the admin , below, for more details about changes to the admin.
Remove core
Remove the core argument from your model fields. It is no longer necessary, since the equivalent functionality (part of
you get to
section, below. For now, remove all references to core.
9.1. Final releases 1671
Django Documentation, Release 2.0.dev20170914110741
Replace class Admin: with admin.py
Remove all your inner class Admin declarations from your models. They won’t break anything if you leave them, but they also won’t do anything. To register apps with the admin you’ll move those declarations to an admin.py file; see
below for more details.
See also:
A contributor to djangosnippets has written a script that’ll scan your models.py and generate a corresponding admin.py
.
Example
Below is an example models.py file with all the changes you’ll need to make:
Old (0.96) models.py:
class Author
(models.Model): first_name = models.CharField(maxlength= 30 ) last_name = models.CharField(maxlength= 30 ) slug = models.CharField(maxlength= 60 , prepopulate_from=( 'first_name' , 'last_name
˓→
' ))
class Admin
: list_display = [ 'first_name' , 'last_name' ]
def __str__
( self ):
return
'%s %s'
%
( self
.
first_name, self
.
last_name)
New (1.0) models.py:
class Author
(models.Model): first_name = models.CharField(max_length= 30 ) last_name = models.CharField(max_length= 30 ) slug = models.CharField(max_length= 60 )
def __unicode__
( self ):
return
u'%s %s'
%
( self
.
first_name, self
.
last_name)
New (1.0) admin.py:
from
django.contrib
import
admin
from
models
import
Author
class AuthorAdmin
(admin.ModelAdmin): list_display = [ 'first_name' , 'last_name' ] prepopulated_fields = {
'slug' : ( 'first_name' , 'last_name' )
} admin.site.register(Author, AuthorAdmin)
The Admin
One of the biggest changes in 1.0 is the new admin. The Django administrative interface (django.contrib.
admin
) has been completely refactored; admin definitions are now completely decoupled from model definitions,
1672 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
the framework has been rewritten to use Django’s new form-handling library and redesigned with extensibility and customization in mind.
Practically, this means you’ll need to rewrite all of your class Admin declarations. You’ve already seen in
above how to replace your class Admin with a admin.site.register() call in an admin.py file. Below are some more details on how to rewrite that Admin declaration into the new syntax.
Use new inline syntax
The new edit_inline options have all been moved to admin.py. Here’s an example:
Old (0.96):
class Parent
(models.Model):
...
class Child
(models.Model): parent = models.ForeignKey(Parent, edit_inline=models.STACKED, num_in_admin= 3 )
New (1.0):
class ChildInline
(admin.StackedInline): model = Child extra = 3
class ParentAdmin
(admin.ModelAdmin): model = Parent inlines = [ChildInline] admin.site.register(Parent, ParentAdmin)
See
for more details.
Simplify fields, or use fieldsets
The old fields syntax was quite confusing, and has been simplified. The old syntax still works, but you’ll need to use fieldsets instead.
Old (0.96):
class ModelOne
(models.Model):
...
class Admin
: fields = (
( None , { 'fields' : ( 'foo' , 'bar' )}),
)
class ModelTwo
(models.Model):
...
class Admin
: fields = (
( 'group1' , { 'fields' : ( 'foo' , 'bar' ), 'classes' : 'collapse' }),
( 'group2' , { 'fields' : ( 'spam' , 'eggs' ), 'classes' : 'collapse wide' }),
)
9.1. Final releases 1673
Django Documentation, Release 2.0.dev20170914110741
New (1.0):
class ModelOneAdmin
(admin.ModelAdmin): fields = ( 'foo' , 'bar' )
class ModelTwoAdmin
(admin.ModelAdmin): fieldsets = (
( 'group1' , { 'fields' : ( 'foo' , 'bar' ), 'classes' : 'collapse' }),
( 'group2' , { 'fields' : ( 'spam' , 'eggs' ), 'classes' : 'collapse wide' }),
)
See also:
• More detailed information about the changes and the reasons behind them can be found on the NewformsAdminBranch wiki page
• The new admin comes with a ton of new features; you can read about them in the
URLs
Update your root urls.py
If you’re using the admin site, you need to update your root urls.py.
Old (0.96) urls.py:
from
django.conf.urls.defaults
import *
urlpatterns = patterns( '' ,
( r'^admin/' , include( 'django.contrib.admin.urls' )),
# ... the rest of your URLs here ...
)
New (1.0) urls.py:
from
django.conf.urls.defaults
import *
# The next two lines enable the admin and load each admin.py file:
from
django.contrib
import
admin admin.autodiscover() urlpatterns = patterns( '' ,
( r'^admin/(.*)' , admin.site.root),
# ... the rest of your URLs here ...
)
Views
Use django.forms instead of newforms
Replace django.newforms with django.forms – Django 1.0 renamed the newforms module (introduced in
0.96) to plain old forms. The oldforms module was also removed.
1674 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
If you’re already using the newforms library, and you used our recommended import statement syntax, all you have to do is change your import statements.
Old:
from
django
import
newforms as forms
New:
from
django
import
forms
If you’re using the old forms system (formerly known as django.forms and django.oldforms), you’ll have to rewrite your forms. A good place to start is the
Handle uploaded files using the new API
Replace use of uploaded files – that is, entries in request.FILES – as simple dictionaries with the new
. The old dictionary syntax no longer works.
Thus, in a view like:
def my_view
(request): f = request.FILES[ 'file_field_name' ]
...
...you’d need to make the following changes:
Old (0.96) f['content'] f['filename']
New (1.0) f.read() f.name
f['content-type'] f.content_type
Work with file fields using the new API
The internal implementation of
have changed. A visible result of this is that the way you access special attributes (URL, filename, image size, etc.) of these model fields has changed. You will need to make the following changes, assuming your model’s
is called myfile:
Old (0.96) New (1.0) myfile.get_content_filename() myfile.content.path
myfile.get_content_url() myfile.get_content_size() myfile.content.url
myfile.content.size
myfile.save_content_file() myfile.get_content_width() myfile.get_content_height() myfile.content.save() myfile.content.width
myfile.content.height
Note that the width and height attributes only make sense for
fields. More details can be found in the
documentation.
Use Paginator instead of ObjectPaginator
The ObjectPaginator in 0.96 has been removed and replaced with an improved version,
9.1. Final releases 1675
Django Documentation, Release 2.0.dev20170914110741
Templates
Learn to love autoescaping
By default, the template system now automatically HTML-escapes the output of every variable. To learn more, see
To disable auto-escaping for an individual variable, use the
filter:
This will be escaped:
{{
data
}}
This will not be escaped:
{{
data
| safe }}
To disable auto-escaping for an entire template, wrap the template (or just a particular section of the template) in the
tag:
{% autoescape
off
%}
... unescaped template content here ...
{% endautoescape %}
Less-common changes
The following changes are smaller, more localized changes. They should only affect more advanced users, but it’s probably worth reading through the list and checking your code for these things.
Signals
• Add **kwargs to any registered signal handlers.
• Connect, disconnect, and send signals via methods on the
object instead of through module methods in django.dispatch.dispatcher.
• Remove any use of the Anonymous and Any sender options; they no longer exist. You can still receive signals sent by any sender by using sender=None
• Make any custom signals you’ve declared into instances of
instead of anonymous objects.
Here’s quick summary of the code changes you’ll need to make:
Old (0.96) def callback(sender) sig = object() dispatcher.connect(callback, sig) dispatcher.send(sig, sender) dispatcher.connect(callback, sig, sender=Any)
New (1.0) def callback(sender, **kwargs) sig = django.dispatch.Signal() sig.connect(callback) sig.send(sender) sig.connect(callback, sender=None)
Comments
If you were using Django 0.96’s django.contrib.comments app, you’ll need to upgrade to the new comments app introduced in 1.0. See the upgrade guide for details.
1676 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
Template tags spaceless tag
The spaceless template tag now removes all spaces between HTML tags, instead of preserving a single space.
Local flavors
U.S. local flavor
django.contrib.localflavor.usa
has been renamed to django.contrib.localflavor.us. This change was made to match the naming scheme of other local flavors. To migrate your code, all you need to do is change the imports.
Sessions
Getting a new session key
SessionBase.get_new_session_key() has been renamed to
_get_new_session_key()
.
get_new_session_object() no longer exists.
Fixtures
Loading a row no longer calls save()
Previously, loading a row automatically ran the model’s save() method. This is no longer the case, so any fields (for example: timestamps) that were auto-populated by a save() now need explicit values in any fixture.
Settings
Better exceptions
The old
EnvironmentError has split into an
ImportError when Django fails to find the settings module and a
RuntimeError when you try to reconfigure settings after having already used them.
LOGIN_URL has moved
The
constant moved from django.contrib.auth into the settings module. Instead of using from django.contrib.auth import LOGIN_URL refer to
APPEND_SLASH behavior has been updated
In 0.96, if a URL didn’t end in a slash or have a period in the final component of its path, and
was True, Django would redirect to the same URL, but with a slash appended to the end. Now, Django checks to see whether the pattern without the trailing slash would be matched by something in your URL patterns. If so, no redirection takes place, because it is assumed you deliberately wanted to catch that pattern.
9.1. Final releases 1677
Django Documentation, Release 2.0.dev20170914110741
For most people, this won’t require any changes. Some people, though, have URL patterns that look like this: r'/some_prefix/(.*)$'
Previously, those patterns would have been redirected to have a trailing slash. If you always want a slash on such
URLs, rewrite the pattern as: r'/some_prefix/(.*/)$'
Smaller model changes
Different exception from get()
Managers now return a
exception instead of
AssertionError
:
Old (0.96):
try
:
Model.objects.get(...)
except AssertionError
: handle_the_error()
New (1.0):
try
:
Model.objects.get(...)
except
Model.MultipleObjectsReturned: handle_the_error()
LazyDate has been fired
The LazyDate helper class no longer exists.
Default field values and query arguments can both be callable objects, so instances of LazyDate can be replaced with a reference to datetime.datetime.now:
Old (0.96):
class Article
(models.Model): title = models.CharField(maxlength= 100 ) published = models.DateField(default=LazyDate())
New (1.0):
import
datetime
class Article
(models.Model): title = models.CharField(max_length= 100 ) published = models.DateField(default=datetime.datetime.now)
DecimalField is new, and FloatField is now a proper float
Old (0.96):
1678 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
class MyModel
(models.Model): field_name = models.FloatField(max_digits= 10 , decimal_places= 3 )
...
New (1.0):
class MyModel
(models.Model): field_name = models.DecimalField(max_digits= 10 , decimal_places= 3 )
...
If you forget to make this change, you will see errors about FloatField not taking a max_digits attribute in
__init__
, because the new FloatField takes no precision-related arguments.
If you’re using MySQL or PostgreSQL, no further changes are needed.
The database column types for
DecimalField are the same as for the old FloatField.
If you’re using SQLite, you need to force the database to view the appropriate columns as decimal types, rather than floats. To do this, you’ll need to reload your data. Do this after you have made the change to using DecimalField in your code and updated the Django code.
Warning: Back up your database first!
For SQLite, this means making a copy of the single file that stores the database (the name of that file is the
DATABASE_NAME in your settings.py file).
To upgrade each application to use a DecimalField, you can do the following, replacing <app> in the code below with each app’s name:
$ ./manage.py dumpdata --format=xml <app> > data-dump.xml
$ ./manage.py reset <app>
$ ./manage.py loaddata data-dump.xml
Notes:
1. It’s important that you remember to use XML format in the first step of this process. We are exploiting a feature of the XML data dumps that makes porting floats to decimals with SQLite possible.
2. In the second step you will be asked to confirm that you are prepared to lose the data for the application(s) in question. Say yes; we’ll restore this data in the third step, of course.
3. DecimalField is not used in any of the apps shipped with Django prior to this change being made, so you do not need to worry about performing this procedure for any of the standard Django models.
If something goes wrong in the above process, just copy your backed up database file over the original file and start again.
Internationalization django.views.i18n.set_language() now requires a POST request
Previously, a GET request was used. The old behavior meant that state (the locale used to display the site) could be changed by a GET request, which is against the HTTP specification’s recommendations. Code calling this view must ensure that a POST request is now made, instead of a GET. This means you can no longer use a link to access the view, but must use a form submission of some kind (e.g. a button).
9.1. Final releases 1679
Django Documentation, Release 2.0.dev20170914110741
_() is no longer in builtins
_() (the callable object whose name is a single underscore) is no longer monkeypatched into builtins – that is, it’s no longer available magically in every module.
If you were previously relying on _() always being present, you should now explicitly import ugettext or ugettext_lazy
, if appropriate, and alias it to _ yourself:
from
django.utils.translation
import
ugettext as _
HTTP request/response objects
Dictionary access to HttpRequest
HttpRequest objects no longer directly support dictionary-style access; previously, both GET and POST data were directly available on the HttpRequest object (e.g., you could check for a piece of form data by using if
'some_form_key' in request or by reading request['some_form_key']. This is no longer supported; if you need access to the combined GET and POST data, use request.REQUEST instead.
It is strongly suggested, however, that you always explicitly look in the appropriate dictionary for the type of request you expect to receive (request.GET or request.POST); relying on the combined request.REQUEST
dictionary can mask the origin of incoming data.
Accessing HTTPResponse headers
django.http.HttpResponse.headers
has been renamed to _headers and
now supports containment checking directly. So use if header in response: instead of if header in response.
headers:
.
Generic relations
Generic relations have been moved out of core
The generic relation classes – GenericForeignKey and GenericRelation – have moved into the
module.
Testing django.test.Client.login() has changed
Old (0.96):
from
django.test
import
Client c = Client() c.login( '/path/to/login' , 'myuser' , 'mypassword' )
New (1.0):
# ... same as above, but then: c.login(username= 'myuser' , password= 'mypassword' )
1680 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
Management commands
Running management commands from your code
has been greatly refactored.
Calls to management services in your code now need to use call_command. For example, if you have some test code that calls flush and load_data:
from
django.core
import
management management.flush(verbosity= 0 , interactive= False ) management.load_data([ 'test_data' ], verbosity= 0 )
...you’ll need to change this code to read:
from
django.core
import
management management.call_command( 'flush' , verbosity= 0 , interactive= False ) management.call_command( 'loaddata' , 'test_data' , verbosity= 0 )
Subcommands must now precede options
django-admin.py
and manage.py now require subcommands to precede options. So:
$ django-admin.py --settings=foo.bar runserver
...no longer works and should be changed to:
$ django-admin.py runserver --settings=foo.bar
Syndication
Feed.__init__
has changed
The __init__() method of the syndication framework’s Feed class now takes an HttpRequest object as its second parameter, instead of the feed’s URL. This allows the syndication framework to work without requiring the sites framework. This only affects code that subclasses Feed and overrides the __init__() method, and code that calls Feed.__init__() directly.
Data structures
SortedDictFromList is gone
django.newforms.forms.SortedDictFromList
was removed. django.utils.datastructures.
SortedDict can now be instantiated with a sequence of tuples.
To update your code:
1. Use django.utils.datastructures.SortedDict wherever you were using django.newforms.
forms.SortedDictFromList
.
9.1. Final releases 1681
Django Documentation, Release 2.0.dev20170914110741
2. Because django.utils.datastructures.SortedDict.copy doesn’t return a deepcopy as
SortedDictFromList.copy() did, you will need to update your code if you were relying on a deepcopy. Do this by using copy.deepcopy directly.
Database backend functions
Database backend functions have been renamed
Almost all of the database backend-level functions have been renamed and/or relocated. None of these were documented, but you’ll need to change your code if you’re using any of these functions, all of which are in
Old (0.96) backend.get_autoinc_sql
backend.get_date_extract_sql
backend.get_date_trunc_sql
backend.get_datetime_cast_sql
backend.get_deferrable_sql
backend.get_drop_foreignkey_sql
backend.get_fulltext_search_sql
backend.get_last_insert_id
backend.get_limit_offset_sql
backend.get_max_name_length
backend.get_pk_default_value
backend.get_random_function_sql
backend.get_sql_flush
New (1.0) connection.ops.autoinc_sql
connection.ops.date_extract_sql
connection.ops.date_trunc_sql
connection.ops.datetime_cast_sql
connection.ops.deferrable_sql
connection.ops.drop_foreignkey_sql
connection.ops.fulltext_search_sql
connection.ops.last_insert_id
connection.ops.limit_offset_sql
connection.ops.max_name_length
connection.ops.pk_default_value
connection.ops.random_function_sql
connection.ops.sql_flush
backend.get_sql_sequence_reset
backend.get_start_transaction_sql
backend.get_tablespace_sql
backend.quote_name
backend.get_query_set_class
backend.get_field_cast_sql
backend.get_drop_sequence
backend.OPERATOR_MAPPING
connection.ops.sequence_reset_sql
connection.ops.start_transaction_sql
connection.ops.tablespace_sql
connection.ops.quote_name
connection.ops.query_set_class
connection.ops.field_cast_sql
connection.ops.drop_sequence_sql
connection.operators
backend.allows_group_by_ordinal
backend.allows_unique_and_pk
backend.autoindexes_primary_keys
backend.needs_datetime_string_cast
backend.needs_upper_for_iops
connection.features.allows_group_by_ordinal
connection.features.allows_unique_and_pk
connection.features.autoindexes_primary_keys
connection.features.needs_datetime_string_cast
connection.features.needs_upper_for_iops
backend.supports_constraints
backend.supports_tablespaces
connection.features.supports_constraints
connection.features.supports_tablespaces
backend.uses_case_insensitive_names
connection.features.uses_case_insensitive_names
backend.uses_custom_queryset
connection.features.uses_custom_queryset
A complete list of backwards-incompatible changes can be found at https://code.djangoproject.com/wiki/
BackwardsIncompatibleChanges .
What’s new in Django 1.0
A lot!
1682 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
Since Django 0.96, we’ve made over 4,000 code commits, fixed more than 2,000 bugs, and edited, added, or removed around 350,000 lines of code. We’ve also added 40,000 lines of new documentation, and greatly improved what was already there.
In fact, new documentation is one of our favorite features of Django 1.0, so we might as well start there. First, there’s a new documentation site:
• https://docs.djangoproject.com/
The documentation has been greatly improved, cleaned up, and generally made awesome. There’s now dedicated search, indexes, and more.
We can’t possibly document everything that’s new in 1.0, but the documentation will be your definitive guide. Anywhere you see something like:
This feature is new in Django 1.0
You’ll know that you’re looking at something new or changed.
The other major highlights of Django 1.0 are:
Re-factored admin application
The Django administrative interface (django.contrib.admin) has been completely refactored; admin definitions are now completely decoupled from model definitions (no more class Admin declaration in models!), rewritten to use Django’s new form-handling library (introduced in the 0.96 release as django.newforms, and now available as simply django.forms) and redesigned with extensibility and customization in mind. Full documentation for the admin application is available online in the official Django documentation:
See the
for details
Improved Unicode handling
Django’s internals have been refactored to use Unicode throughout; this drastically simplifies the task of dealing with non-Western-European content and data in Django. Additionally, utility functions have been provided to ease interoperability with third-party libraries and systems which may or may not handle Unicode gracefully. Details are available in Django’s Unicode-handling documentation.
See
An improved ORM
Django’s object-relational mapper – the component which provides the mapping between Django model classes and your database, and which mediates your database queries – has been dramatically improved by a massive refactoring.
For most users of Django this is backwards-compatible; the public-facing API for database querying underwent a few minor changes, but most of the updates took place in the ORM’s internals. A guide to the changes, including backwards-incompatible modifications and mentions of new features opened up by this refactoring, is available on the
Django wiki .
Automatic escaping of template variables
To provide improved security against cross-site scripting (XSS) vulnerabilities, Django’s template system now automatically escapes the output of variables. This behavior is configurable, and allows both variables and larger template constructs to be marked as safe (requiring no escaping) or unsafe (requiring escaping). A full guide to this feature is in the documentation for the
tag.
9.1. Final releases 1683
Django Documentation, Release 2.0.dev20170914110741
django.contrib.gis
(GeoDjango)
A project over a year in the making, this adds world-class GIS ( Geographic Information Systems ) support to Django, in the form of a contrib application. Its documentation is currently being maintained externally, and will be merged into the main Django documentation shortly. Huge thanks go to Justin Bronn, Jeremy Dunck, Brett Hoerner and Travis
Pinney for their efforts in creating and completing this feature.
See http://geodjango.org/ for details.
Pluggable file storage
Django’s built-in FileField and ImageField now can take advantage of pluggable file-storage backends, allowing extensive customization of where and how uploaded files get stored by Django. For details, see
Jython compatibility
Thanks to a lot of work from Leo Soto during a Google Summer of Code project, Django’s codebase has been refactored to remove incompatibilities with Jython , an implementation of Python written in Java, which runs Python code on the Java Virtual Machine. Django is now compatible with the forthcoming Jython 2.5 release.
See
Generic relations in forms and admin
Classes are now included in django.contrib.contenttypes which can be used to support generic relations in both the admin interface and in end-user forms. See
the documentation for generic relations
for details.
INSERT
/UPDATE distinction
Although Django’s default behavior of having a model’s save() method automatically determine whether to perform an INSERT or an UPDATE at the SQL level is suitable for the majority of cases, there are occasional situations where forcing one or the other is useful. As a result, models can now support an additional parameter to save() which can force a specific operation.
See
for details.
Split CacheMiddleware
Django’s CacheMiddleware has been split into three classes: CacheMiddleware itself still exists and retains all of its previous functionality, but it is now built from two separate middleware classes which handle the two parts of caching (inserting into and reading from the cache) separately, offering additional flexibility for situations where combining these functions into a single middleware posed problems.
Full details, including updated notes on appropriate use, are in
Refactored django.contrib.comments
As part of a Google Summer of Code project, Thejaswi Puthraya carried out a major rewrite and refactoring of
Django’s bundled comment system, greatly increasing its flexibility and customizability.
1684 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
Removal of deprecated features
A number of features and methods which had previously been marked as deprecated, and which were scheduled for removal prior to the 1.0 release, are no longer present in Django.
These include imports of the form library from django.newforms (now located simply at django.forms), the form_for_model and form_for_instance helper functions (which have been replaced by ModelForm) and a number of deprecated features which were replaced by the dispatcher, file-uploading and file-storage refactorings introduced in the Django
1.0 alpha releases.
Known issues
We’ve done our best to make Django 1.0 as solid as possible, but unfortunately there are a couple of issues that we know about in the release.
Multi-table model inheritance with to_field
If you’re using
multiple table model inheritance , be aware of this caveat: child models using a custom parent_link
and to_field will cause database integrity errors. A set of models like the following are not valid:
class Parent
(models.Model): name = models.CharField(max_length= 10 ) other_value = models.IntegerField(unique=True)
class Child
(Parent): father = models.OneToOneField(Parent, primary_key=True, to_field= "other_value" ,
˓→ parent_link=True) value = models.IntegerField()
This bug will be fixed in the next release of Django.
Caveats with support of certain databases
Django attempts to support as many features as possible on all database backends. However, not all database backends are alike, and in particular many of the supported database differ greatly from version to version. It’s a good idea to checkout our
•
•
•
Pre-1.0 releases
Django version 0.96 release notes
Welcome to Django 0.96!
The primary goal for 0.96 is a cleanup and stabilization of the features introduced in 0.95. There have been a few small
backwards-incompatible changes
since 0.95, but the upgrade process should be fairly simple and should not require major changes to existing applications.
9.1. Final releases 1685
Django Documentation, Release 2.0.dev20170914110741
However, we’re also releasing 0.96 now because we have a set of backwards-incompatible changes scheduled for the near future. Once completed, they will involve some code changes for application developers, so we recommend that you stick with Django 0.96 until the next official release; then you’ll be able to upgrade in one step instead of needing to make incremental changes to keep up with the development version of Django.
Backwards-incompatible changes
The following changes may require you to update your code when you switch from 0.95 to 0.96:
MySQLdb version requirement
Due to a bug in older versions of the MySQLdb Python module (which Django uses to connect to MySQL databases),
Django’s MySQL backend now requires version 1.2.1p2 or higher of MySQLdb, and will raise exceptions if you attempt to use an older version.
If you’re currently unable to upgrade your copy of MySQLdb to meet this requirement, a separate, backwardscompatible backend, called “mysql_old”, has been added to Django.
To use this backend, change the
DATABASE_ENGINE setting in your Django settings file from this:
DATABASE_ENGINE = "mysql" to this:
DATABASE_ENGINE = "mysql_old"
However, we strongly encourage MySQL users to upgrade to a more recent version of MySQLdb as soon as possible, The “mysql_old” backend is provided only to ease this transition, and is considered deprecated; aside from any necessary security fixes, it will not be actively maintained, and it will be removed in a future release of Django.
Also, note that some features, like the new DATABASE_OPTIONS setting (see the
for details), are only available on the “mysql” backend, and will not be made available for “mysql_old”.
Database constraint names changed
The format of the constraint names Django generates for foreign key references have changed slightly. These names are generally only used when it is not possible to put the reference directly on the affected column, so they are not always visible.
The effect of this change is that running manage.py reset and similar commands against an existing database may generate SQL with the new form of constraint name, while the database itself contains constraints named in the old form; this will cause the database server to raise an error message about modifying nonexistent constraints.
If you need to work around this, there are two methods available:
1. Redirect the output of manage.py to a file, and edit the generated SQL to use the correct constraint names before executing it.
2. Examine the output of manage.py sqlall to see the new-style constraint names, and use that as a guide to rename existing constraints in your database.
Name changes in manage.py
A few of the options to manage.py have changed with the addition of fixture support:
1686 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
• There are new dumpdata and loaddata commands which, as you might expect, will dump and load data to/from the database. These commands can operate against any of Django’s supported serialization formats.
• The sqlinitialdata command has been renamed to sqlcustom to emphasize that loaddata should be used for data (and sqlcustom for other custom SQL – views, stored procedures, etc.).
• The vestigial install command has been removed. Use syncdb.
Backslash escaping changed
The Django database API now escapes backslashes given as query parameters. If you have any database API code that matches backslashes, and it was working before (despite the lack of escaping), you’ll have to change your code to
“unescape” the slashes one level.
For example, this used to work:
# Find text containing a single backslash
MyModel.objects.filter(text__contains= '\\\\' )
The above is now incorrect, and should be rewritten as:
# Find text containing a single backslash
MyModel.objects.filter(text__contains= '\\' )
Removed ENABLE_PSYCO setting
The ENABLE_PSYCO setting no longer exists. If your settings file includes ENABLE_PSYCO it will have no effect; to use Psyco , we recommend writing a middleware class to activate it.
What’s new in 0.96?
This revision represents over a thousand source commits and over four hundred bug fixes, so we can’t possibly catalog all the changes. Here, we describe the most notable changes in this release.
New forms library
django.newforms
is Django’s new form-handling library. It’s a replacement for django.forms, the old form/manipulator/validation framework. Both APIs are available in 0.96, but over the next two releases we plan to switch completely to the new forms system, and deprecate and remove the old system.
There are three elements to this transition:
• We’ve copied the current django.forms to django.oldforms. This allows you to upgrade your code now rather than waiting for the backwards-incompatible change and rushing to fix your code after the fact. Just change your import statements like this:
from
django
import
forms # 0.95-style
from
django
import
oldforms as forms # 0.96-style
• The next official release of Django will move the current django.newforms to django.forms. This will be a backwards-incompatible change, and anyone still using the old version of django.forms at that time will need to change their import statements as described above.
• The next release after that will completely remove django.oldforms.
9.1. Final releases 1687
Django Documentation, Release 2.0.dev20170914110741
Although the newforms library will continue to evolve, it’s ready for use for most common cases. We recommend that anyone new to form handling skip the old forms system and start with the new.
For more information about django.newforms, read the
URLconf improvements
You can now use any callable as the callback in URLconfs (previously, only strings that referred to callables were allowed). This allows a much more natural use of URLconfs. For example, this URLconf:
from
django.conf.urls.defaults
import *
urlpatterns = patterns( '' ,
( '^myview/$' , 'mysite.myapp.views.myview' )
) can now be rewritten as:
from
django.conf.urls.defaults
import * from
mysite.myapp.views
import
myview urlpatterns = patterns( '' ,
( '^myview/$' , myview)
)
One useful application of this can be seen when using decorators; this change allows you to apply decorators to views in your URLconf . Thus, you can make a generic view require login very easily:
from
django.conf.urls.defaults
import * from
django.contrib.auth.decorators
import
login_required
from
django.views.generic.list_detail
import
object_list
from
mysite.myapp.models
import
MyModel info = {
"queryset" : MyModel.objects.all(),
} urlpatterns = patterns( '' ,
( '^myview/$' , login_required(object_list), info)
)
Note that both syntaxes (strings and callables) are valid, and will continue to be valid for the foreseeable future.
The test framework
Django now includes a test framework so you can start transmuting fear into boredom (with apologies to Kent Beck).
You can write tests based on doctest or unittest and test your views with a simple test client.
There is also new support for “fixtures” – initial data, stored in any of the supported
serialization formats , that will be
loaded into your database at the start of your tests. This makes testing with real data much easier.
See
for the full details.
1688 Chapter 9. Release notes
Django Documentation, Release 2.0.dev20170914110741
Improvements to the admin interface
A small change, but a very nice one: dedicated views for adding and updating users have been added to the admin interface, so you no longer need to worry about working with hashed passwords in the admin.
Thanks
Since 0.95, a number of people have stepped forward and taken a major new role in Django’s development. We’d like to thank these people for all their hard work:
• Russell Keith-Magee and Malcolm Tredinnick for their major code contributions. This release wouldn’t have been possible without them.
• Our new release manager, James Bennett, for his work in getting out 0.95.1, 0.96, and (hopefully) future release.
• Our ticket managers Chris Beaven (aka SmileyChris), Simon Greenhill, Michael Radziej, and Gary Wilson.
They agreed to take on the monumental task of wrangling our tickets into nicely cataloged submission. Figuring out what to work on is now about a million times easier; thanks again, guys.
• Everyone who submitted a bug report, patch or ticket comment. We can’t possibly thank everyone by name – over 200 developers submitted patches that went into 0.96 – but everyone who’s contributed to Django is listed in AUTHORS .
Django version 0.95 release notes
Welcome to the Django 0.95 release.
This represents a significant advance in Django development since the 0.91 release in January 2006. The details of every change in this release would be too extensive to list in full, but a summary is presented below.
Suitability and API stability
This release is intended to provide a stable reference point for developers wanting to work on production-level applications that use Django.
However, it’s not the 1.0 release, and we’ll be introducing further changes before 1.0. For a clear look at which areas of the framework will change (and which ones will not change) before 1.0, see the api-stability.txt file, which lives in the docs/ directory of the distribution.
You may have a need to use some of the features that are marked as “subject to API change” in that document, but that’s OK with us as long as it’s OK with you, and as long as you understand APIs may change in the future.
Fortunately, most of Django’s core APIs won’t be changing before version 1.0. There likely won’t be as big of a change between 0.95 and 1.0 versions as there was between 0.91 and 0.95.
Changes and new features
The major changes in this release (for developers currently using the 0.91 release) are a result of merging the ‘magicremoval’ branch of development. This branch removed a number of constraints in the way Django code had to be written that were a consequence of decisions made in the early days of Django, prior to its open-source release. It’s now possible to write more natural, Pythonic code that works as expected, and there’s less “black magic” happening behind the scenes.
9.1. Final releases 1689
Django Documentation, Release 2.0.dev20170914110741
Aside from that, another main theme of this release is a dramatic increase in usability. We’ve made countless improvements in error messages, documentation, etc., to improve developers’ quality of life.
The new features and changes introduced in 0.95 include:
• Django now uses a more consistent and natural filtering interface for retrieving objects from the database.
• User-defined models, functions and constants now appear in the module namespace they were defined in. (Previously everything was magically transferred to the django.models.* namespace.)
• Some optional applications, such as the FlatPage, Sites and Redirects apps, have been decoupled and moved into django.contrib
. If you don’t want to use these applications, you no longer have to install their database tables.
• Django now has support for managing database transactions.
• We’ve added the ability to write custom authentication and authorization backends for authenticating users against alternate systems, such as LDAP.
• We’ve made it easier to add custom table-level functions to models, through a new “Manager” API.
• It’s now possible to use Django without a database. This simply means that the framework no longer requires you to have a working database set up just to serve dynamic pages. In other words, you can just use URLconfs/views on their own. Previously, the framework required that a database be configured, regardless of whether you actually used it.
• It’s now more explicit and natural to override save() and delete() methods on models, rather than needing to hook into the pre_save() and post_save() method hooks.
• Individual pieces of the framework now can be configured without requiring the setting of an environment variable. This permits use of, for example, the Django templating system inside other applications.
• More and more parts of the framework have been internationalized, as we’ve expanded internationalization
(i18n) support. The Django codebase, including code and templates, has now been translated, at least in part, into 31 languages. From Arabic to Chinese to Hungarian to Welsh, it is now possible to use Django’s admin site in your native language.
The number of changes required to port from 0.91-compatible code to the 0.95 code base are significant in some cases.
However, they are, for the most part, reasonably routine and only need to be done once. A list of the necessary changes is described in the Removing The Magic wiki page. There is also an easy checklist for reference when undertaking the porting operation.
Problem reports and getting help
Need help resolving a problem with Django? The documentation in the distribution is also available
at the
Django website . The
document is especially recommended, as it contains a number of issues that come up time and again.
For more personalized help, the django-users mailing list is a very active list, with more than 2,000 subscribers who can help you solve any sort of Django problem. We recommend you search the archives first, though, because many common questions appear with some regularity, and any particular problem may already have been answered.
Finally, for those who prefer the more immediate feedback offered by IRC, there’s a #django channel on irc.freenode.net that is regularly populated by Django users and developers from around the world. Friendly people are usually available at any hour of the day – to help, or just to chat.
Thanks for using Django!
The Django Team July 2006
1690 Chapter 9. Release notes
Descarcă
Publicitate