1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105 |
- ============================================
- Django 1.6 release notes - UNDER DEVELOPMENT
- ============================================
- .. 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
- 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
- :doc:`our deprecation plan </internals/deprecation>`, and we've `begun the
- deprecation process for some features`_.
- .. _`new features`: `What's new in Django 1.6`_
- .. _`backwards incompatible changes`: `Backwards incompatible changes in 1.6`_
- .. _`begun the deprecation process for some features`: `Features deprecated in 1.6`_
- 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.
- What's new in Django 1.6
- ========================
- Simplified default project and app templates
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- The default templates used by :djadmin:`startproject` and :djadmin:`startapp`
- have been simplified and modernized. The :doc:`admin
- </ref/contrib/admin/index>` is now enabled by default in new projects; the
- :doc:`sites </ref/contrib/sites>` framework no longer is. :ref:`clickjacking
- prevention <clickjacking-prevention>` is now on and the database defaults to
- SQLite.
- If the default templates don't suit your tastes, you can use :ref:`custom
- project and app templates <custom-app-and-project-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 :doc:`transaction management docs
- </topics/db/transactions>`.
- Please review carefully the list of :ref:`known backwards-incompatibilities
- <transactions-upgrading-from-1.5>` to determine if you need to make changes in
- your code.
- Persistent database connections
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Django now supports reusing the same database connection for several requests.
- This avoids the overhead of re-establishing a connection at the beginning of
- each request. For backwards compatibility, this feature is disabled by
- default. See :ref:`persistent-database-connections` 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
- :setting:`INSTALLED_APPS`.
- 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
- :setting:`INSTALLED_APPS`. For more details, see :doc:`/topics/testing/index`.
- This change is backwards-incompatible; see the :ref:`backwards-incompatibility
- notes<new-test-runner>`.
- Time zone aware aggregation
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~
- The support for :doc:`time zones </topics/i18n/timezones>` introduced in
- Django 1.4 didn't work well with :meth:`QuerySet.dates()
- <django.db.models.query.QuerySet.dates>`: aggregation was always performed in
- UTC. This limitation was lifted in Django 1.6. Use :meth:`QuerySet.datetimes()
- <django.db.models.query.QuerySet.datetimes>` to perform time zone aware
- aggregation on a :class:`~django.db.models.DateTimeField`.
- Support for savepoints in SQLite
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Django 1.6 adds support for savepoints in SQLite, with some :ref:`limitations
- <savepoints-in-sqlite>`.
- ``BinaryField`` model field
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~
- A new :class:`django.db.models.BinaryField` model field allows storage of raw
- binary data in the database.
- GeoDjango form widgets
- ~~~~~~~~~~~~~~~~~~~~~~
- GeoDjango now provides :ref:`form fields and widgets <ref-gis-forms-api>` 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 :djadmin:`check` management command was added, enabling you to verify if your
- current configuration (currently oriented at settings) is compatible with the
- current version of Django.
- :meth:`Model.save() <django.db.models.Model.save()>` algorithm changed
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- The :meth:`Model.save() <django.db.models.Model.save()>` 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
- :meth:`Model.save() <django.db.models.Model.save()>` 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
- :attr:`django.db.models.Options.select_on_save` 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
- :setting:`CSRF_COOKIE_HTTPONLY`.
- * The :meth:`~django.test.TransactionTestCase.assertQuerysetEqual` now checks
- for undefined order and raises :exc:`~exceptions.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 :meth:`~django.db.models.query.QuerySet.earliest` for symmetry with
- :meth:`~django.db.models.query.QuerySet.latest`.
- * In addition to :lookup:`year`, :lookup:`month` and :lookup:`day`, the ORM
- now supports :lookup:`hour`, :lookup:`minute` and :lookup:`second` lookups.
- * Django now wraps all PEP-249 exceptions.
- * The default widgets for :class:`~django.forms.EmailField`,
- :class:`~django.forms.URLField`, :class:`~django.forms.IntegerField`,
- :class:`~django.forms.FloatField` and :class:`~django.forms.DecimalField` 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 :ref:`lazy plural translations
- <lazy-plural-translations>` 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
- :attr:`~django.core.management.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
- :attr:`~django.core.management.BaseCommand.leave_locale_alone` internal
- option. See :ref:`management-commands-and-locales` for more details.
- * The :attr:`~django.views.generic.edit.DeletionMixin.success_url` of
- :class:`~django.views.generic.edit.DeletionMixin` is now interpolated with
- its ``object``’s ``__dict__``.
- * :class:`~django.http.HttpResponseRedirect` and
- :class:`~django.http.HttpResponsePermanentRedirect` now provide an ``url``
- attribute (equivalent to the URL the response will redirect to).
- * The ``MemcachedCache`` cache backend now uses the latest :mod:`pickle`
- protocol available.
- * Added :class:`~django.contrib.messages.views.SuccessMessageMixin` which
- provides a ``success_message`` attribute for
- :class:`~django.views.generic.edit.FormView` based classes.
- * Added the :attr:`django.db.models.ForeignKey.db_constraint` and
- :attr:`django.db.models.ManyToManyField.db_constraint` options.
- * The jQuery library embedded in the admin has been upgraded to version 1.9.1.
- * Syndication feeds (:mod:`django.contrib.syndication`) can now pass extra
- context through to feed templates using a new
- :meth:`Feed.get_context_data()
- <django.contrib.syndication.Feed.get_context_data>` 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 :ref:`isolation level<database-isolation-level>` can be customized under
- PostgreSQL.
- * The :ttag:`blocktrans` template tag now respects
- :setting:`TEMPLATE_STRING_IF_INVALID` for variables not present in the
- context, just like other template constructs.
- * ``SimpleLazyObject``\s will now present more helpful representations in shell
- debugging situations.
- * Generic :class:`~django.contrib.gis.db.models.GeometryField` is now editable
- with the OpenLayers widget in the admin.
- * The documentation contains a :doc:`deployment checklist
- </howto/deployment/checklist>`.
- * The :djadmin:`diffsettings` 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
- :func:`~django.forms.formsets.formset_factory`, 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.
- .. _`Pillow`: https://pypi.python.org/pypi/Pillow
- .. _`PIL`: https://pypi.python.org/pypi/PIL
- * :class:`~django.forms.ModelForm` 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
- :ref:`modelforms-overriding-default-fields` 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
- :attr:`~django.http.HttpResponse.reason_phrase`.
- * When giving the URL of the next page for
- :func:`~django.contrib.auth.views.logout`,
- :func:`~django.contrib.auth.views.password_reset`,
- :func:`~django.contrib.auth.views.password_reset_confirm`,
- and :func:`~django.contrib.auth.views.password_change`, you can now pass
- URL names and they will be resolved.
- * The :djadmin:`dumpdata` ``manage.py`` command now has a :djadminopt:`--pks`
- option which will allow users to specify the primary keys of objects they
- want to dump. This option can only be used with one model.
- * Added ``QuerySet`` methods :meth:`~django.db.models.query.QuerySet.first`
- and :meth:`~django.db.models.query.QuerySet.last` which are convenience
- methods returning the first or last object matching the filters. Returns
- ``None`` if there are no objects matching.
- * :class:`~django.views.generic.base.View` and
- :class:`~django.views.generic.base.RedirectView` now support HTTP ``PATCH``
- method.
- * :class:`GenericForeignKey <django.contrib.contenttypes.generic.GenericForeignKey>`
- now takes an optional
- :attr:`~django.contrib.contenttypes.generic.GenericForeignKey.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 :class:`~django.middleware.locale.LocaleMiddleware` 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.
- * :exc:`~django.core.exceptions.SuspiciousOperation` 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 :exc:`~django.core.exceptions.DoesNotExist` exception now includes a
- message indicating the name of the attribute used for the lookup.
- * The :meth:`~django.db.models.query.QuerySet.get_or_create` method no longer
- requires at least one keyword argument.
- * The :class:`~django.test.SimpleTestCase` class includes a new assertion
- helper for testing formset errors:
- :meth:`~django.test.SimpleTestCase.assertFormsetError`.
- * The list of related fields added to a
- :class:`~django.db.models.query.QuerySet` by
- :meth:`~django.db.models.query.QuerySet.select_related` can be cleared using
- ``select_related(None)``.
- * The :meth:`~django.contrib.admin.InlineModelAdmin.get_extra` and
- :meth:`~django.contrib.admin.InlineModelAdmin.get_max_num` methods on
- :class:`~django.contrib.admin.InlineModelAdmin` may be overridden to
- customize the extra and maximum number of inline forms.
- * Formsets now have a
- :meth:`~django.forms.formsets.BaseFormSet.total_error_count` method.
- * :class:`~django.forms.ModelForm` fields can now override error messages
- defined in model fields by using the
- :attr:`~django.forms.Field.error_messages` argument of a ``Field``’s
- constructor. To take advantage of this new feature with your custom fields,
- :ref:`see the updated recommendation <raising-validation-error>` for raising
- a ``ValidationError``.
- * :class:`~django.contrib.admin.ModelAdmin` 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
- :attr:`~django.contrib.admin.ModelAdmin.preserve_filters` attribute to ``False``.
- * Added
- :meth:`FormMixin.get_prefix<django.views.generic.edit.FormMixin.get_prefix>`
- (which returns
- :attr:`FormMixin.prefix<django.views.generic.edit.FormMixin.prefix>` by
- default) to allow customizing the :attr:`~django.forms.Form.prefix` 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.
- Backwards incompatible changes in 1.6
- =====================================
- .. warning::
- In addition to the changes outlined in this section, be sure to review the
- :doc:`deprecation plan </internals/deprecation>` 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.
- 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 known backwards-incompatibilities, described in the :ref:`transaction
- management docs <transactions-upgrading-from-1.5>`. You should review your
- code to determine if you're affected.
- 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 :meth:`~django.test.TransactionTestCase.assertNumQueries` 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 :ref:`ignored
- <postgresql-autocommit-mode>` and can be removed.
- .. _new-test-runner:
- 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 :mod:`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:`TEST_RUNNER` 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.
- .. _recommendations in the Python documentation: http://docs.python.org/2/library/doctest.html#unittest-api
- Time zone-aware ``day``, ``month``, and ``week_day`` lookups
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Django 1.6 introduces time zone support for :lookup:`day`, :lookup:`month`,
- and :lookup:`week_day` lookups when :setting:`USE_TZ` is ``True``. These
- lookups were previously performed in UTC regardless of the current time zone.
- This requires :ref:`time zone definitions in the database
- <database-time-zone-definitions>`. 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`_.
- .. _pytz: http://pytz.sourceforge.net/
- .. _mysql_tzinfo_to_sql: http://dev.mysql.com/doc/refman/5.5/en/mysql-tzinfo-to-sql.html
- Addition of ``QuerySet.datetimes()``
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- When the :doc:`time zone support </topics/i18n/timezones>` added in Django 1.4
- was active, :meth:`QuerySet.dates() <django.db.models.query.QuerySet.dates>`
- lookups returned unexpected results, because the aggregation was performed in
- UTC. To fix this, Django 1.6 introduces a new API, :meth:`QuerySet.datetimes()
- <django.db.models.query.QuerySet.datetimes>`. This requires a few changes in
- your code.
- ``QuerySet.dates()`` returns ``date`` objects
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- :meth:`QuerySet.dates() <django.db.models.query.QuerySet.dates>` now returns a
- list of :class:`~datetime.date`. It used to return a list of
- :class:`~datetime.datetime`.
- :meth:`QuerySet.datetimes() <django.db.models.query.QuerySet.datetimes>`
- returns a list of :class:`~datetime.datetime`.
- ``QuerySet.dates()`` no longer usable on ``DateTimeField``
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- :meth:`QuerySet.dates() <django.db.models.query.QuerySet.dates>` raises an
- error if it's used on :class:`~django.db.models.DateTimeField` when time
- zone support is active. Use :meth:`QuerySet.datetimes()
- <django.db.models.query.QuerySet.datetimes>` instead.
- ``date_hierarchy`` requires time zone definitions
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- The :attr:`~django.contrib.admin.ModelAdmin.date_hierarchy` feature of the
- admin now relies on :meth:`QuerySet.datetimes()
- <django.db.models.query.QuerySet.datetimes>` when it's used on a
- :class:`~django.db.models.DateTimeField`.
- This requires time zone definitions in the database when :setting:`USE_TZ` is
- ``True``. :ref:`Learn more <database-time-zone-definitions>`.
- ``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 :class:`~django.db.models.DateTimeField` and :setting:`USE_TZ` is
- ``True``. :ref:`Learn more <database-time-zone-definitions>`.
- New lookups may clash with model fields
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Django 1.6 introduces ``hour``, ``minute``, and ``second`` lookups on
- :class:`~django.db.models.DateTimeField`. If you had model fields called
- ``hour``, ``minute``, or ``second``, the new lookups will clash with you field
- names. Append an explicit :lookup:`exact` lookup if this is an issue.
- ``BooleanField`` no longer defaults to ``False``
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- When a :class:`~django.db.models.BooleanField` doesn't have an explicit
- :attr:`~django.db.models.Field.default`, 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 :class:`~django.db.models.BooleanField`. 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
- :djadmin:`makemessages` command now correctly detects i18n constructs when
- they are located after a ``{#`` / ``#}``-type comment on the same line. E.g.:
- .. code-block:: html+django
- {# A comment #}{% trans "This literal was incorrectly ignored. Not anymore" %}
- Location of translator comments
- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- :ref:`translator-comments-in-templates` specified using ``{#`` / ``#}`` need to
- be at the end of a line. If they are not, the comments are ignored and
- :djadmin:`makemessages` will generate a warning. For example:
- .. code-block:: html+django
- {# Translators: This is ignored #}{% trans "Translate me" %}
- {{ title }}{# Translators: Extracted and associated with 'Welcome' below #}
- <h1>{% trans "Welcome" %}</h1>
- Quoting in :func:`~django.core.urlresolvers.reverse`
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- When reversing URLs, Django didn't apply :func:`~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 :func:`~django.core.urlresolvers.reverse`, this may
- result in double-quoting. If this happens, simply remove the URL quoting from
- your code.
- Storage of IP addresses in the comments app
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- The :doc:`comments </ref/contrib/comments/index>` 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:
- .. code-block:: sql
- ALTER TABLE django_comments MODIFY ip_address VARCHAR(39);
- For Oracle, execute this query:
- .. code-block:: sql
- 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
- :ref:`cursor.execute <executing-custom-sql>` 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.
- .. _m2m-help_text:
- Help text of model form fields for ManyToManyField fields
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- HTML rendering of model form fields corresponding to
- :class:`~django.db.models.ManyToManyField` ORM 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 :attr:`model <django.db.models.Field.help_text>` nor :attr:`form
- <django.forms.Field.help_text>` ``help_text`` attribute was specified by the
- user (or appended to, if ``help_text`` was provided.)
- This happened always, possibly even with form fields implementing user
- interactions that don't involve a keyboard and/or a mouse and was handled at the
- model field layer.
- Starting with Django 1.6 this doesn't happen anymore.
- 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.
- Applications that use Django :doc:`model form </topics/forms/modelforms>`
- facilities together with Django built-in form :doc:`fields </ref/forms/fields>`
- and :doc:`widgets </ref/forms/widgets>` aren't affected but need to be aware of
- what's described in :ref:`m2m-help_text-deprecation` below.
- This is because, as an ad-hoc temporary backward-compatibility provision, the
- described non-standard behavior has been preserved but moved to the model form
- field layer and occurs only when the associated widget is
- :class:`~django.forms.SelectMultiple` or selected subclasses.
- 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 :meth:`~django.db.models.query.QuerySet.iterator()`
- method.
- :meth:`BoundField.label_tag<django.forms.BoundField.label_tag>` now includes the form's :attr:`~django.forms.Form.label_suffix`
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- This is consistent with how methods like
- :meth:`Form.as_p<django.forms.Form.as_p>` and
- :meth:`Form.as_ul<django.forms.Form.as_ul>` render labels.
- If you manually render ``label_tag`` in your templates:
- .. code-block:: html+django
- {{ 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.
- .. code-block:: html+django
- {{ form.my_field.label_tag }} {{ form.my_field }}
- will render something like:
- .. code-block:: html
- <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 :meth:`~django.forms.BoundField.label_tag`.
- 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
- :attr:`~django.contrib.admin.ModelAdmin.preserve_filters` 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
- (:func:`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.
- :func:`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 :func:`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 :setting:`PASSWORD_RESET_TIMEOUT_DAYS`, 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 :setting:`PASSWORD_RESET_TIMEOUT_DAYS`.
- Default session serialization switched to JSON
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Historically, :mod:`django.contrib.sessions` used :mod:`pickle` to serialize
- session data before storing it in the backend. If you're using the :ref:`signed
- cookie session backend<cookie-session-backend>` and :setting:`SECRET_KEY` 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
- :setting:`SECRET_KEY` leak immediately escalates to a remote code execution
- vulnerability.
- This attack can be mitigated by serializing session data using JSON rather
- than :mod:`pickle`. To facilitate this, Django 1.5.3 introduced a new setting,
- :setting:`SESSION_SERIALIZER`, to customize the session serialization format.
- For backwards compatibility, this setting defaulted to using :mod:`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
- :mod:`pickle` does, we highly recommend using JSON-serialized sessions. Also,
- as JSON requires string keys, you will likely run into problems if you are
- using non-string keys in ``request.session``. See the
- :ref:`session_serialization` documentation for more details.
- 4096-byte limit on passwords
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- .. note::
- This behavior was also added in the Django 1.5.4 and 1.4.8 security
- releases.
- Historically, Django has imposed no length limit on plaintext
- passwords. This enables a denial-of-service 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.
- Django now imposes a 4096-byte limit on password length, and will fail
- authentication with any submitted password of greater length.
- Miscellaneous
- ~~~~~~~~~~~~~
- * The ``django.db.models.query.EmptyQuerySet`` can't be instantiated any more -
- it is only usable as a marker class for checking if
- :meth:`~django.db.models.query.QuerySet.none` 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 :attr:`~django.forms.Field.error_messages` 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 :class:`~django.forms.DecimalField` and
- :class:`~django.forms.ModelMultipleChoiceField`.
- * 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.
- * :class:`~django.db.models.GenericIPAddressField` 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 :class:`~django.core.urlresolvers.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
- ``{% url %}`` tag, it causes template rendering to fail like always when
- ``NoReverseMatch`` is raised.
- * :meth:`django.test.Client.logout` now calls
- :meth:`django.contrib.auth.logout` which will send the
- :func:`~django.contrib.auth.signals.user_logged_out` signal.
- * :ref:`Authentication views <built-in-auth-views>` 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
- :meth:`~django.conf.urls.url` 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')
- * :class:`~django.views.generic.base.RedirectView` 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
- :meth:`~django.contrib.auth.models.User.set_password()` would save a blank
- password as an unusable password like
- :meth:`~django.contrib.auth.models.User.set_unusable_password()` does, and
- thus :meth:`~django.contrib.auth.models.User.check_password()` always
- returned ``False`` for blank passwords. This has been corrected in this
- release: blank passwords are now valid.
- * The admin :attr:`~django.contrib.admin.ModelAdmin.changelist_view` 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.
- * :meth:`~django.core.validators.validate_email` now accepts email addresses
- with ``localhost`` as the domain.
- * The :djadminopt:`--keep-pot` option was added to :djadmin:`makemessages`
- to prevent django from deleting the temporary .pot file it generates before
- creating the .po file.
- 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``
- - ``django.db.transaction.commit_manually``
- - the ``TRANSACTIONS_MANAGED`` setting
- The reasons for this change and the upgrade path are described in the
- :ref:`transactions documentation <transactions-upgrading-from-1.5>`.
- ``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`__.
- __ https://disqus.com/
- __ https://github.com/django/django-contrib-comments
- 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 :ttag:`cycle` and :ttag:`firstof`
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- The template system generally escapes all variables to avoid XSS attacks.
- However, due to an accident of history, the :ttag:`cycle` and :ttag:`firstof`
- tags render their arguments as-is.
- Django 1.6 starts a process to correct this inconsistency. The ``future``
- template library provides alternate implementations of :ttag:`cycle` and
- :ttag:`firstof` that autoescape their inputs. If you're using these tags,
- you're encourage 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
- :func:`~django.utils.safestring.mark_safe` or :ttag:`{% autoescape off %}
- <autoescape>`.
- ``CACHE_MIDDLEWARE_ANONYMOUS_ONLY`` setting
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- ``CacheMiddleware`` 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.
- __ http://www.google.com/analytics/
- ``SEND_BROKEN_LINK_EMAILS`` setting
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- :class:`~django.middleware.common.CommonMiddleware` 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
- :class:`~django.middleware.common.CommonMiddleware` and
- :class:`~django.middleware.locale.LocaleMiddleware`, this feature was split
- out into a new middleware:
- :class:`~django.middleware.common.BrokenLinkEmailsMiddleware`.
- If you're relying on this feature, you should add
- ``'django.middleware.common.BrokenLinkEmailsMiddleware'`` to your
- :setting:`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.
- ``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``.
- ``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 :class:`~django.forms.ModelForm` 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
- <http://en.wikipedia.org/wiki/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.
- 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 :class:`~django.views.generic.edit.CreateView` and
- :class:`~django.views.generic.edit.UpdateView`, and anything else derived from
- :class:`~django.views.generic.edit.ModelFormMixin`, are vulnerable 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 :class:`~django.forms.ModelForm`
- ``Meta.fields`` attribute. Alternatively, you can set 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.
- .. _m2m-help_text-deprecation:
- 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
- :ref:`m2m-help_text` 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.
|