parts/django/docs/releases/1.2.txt
changeset 69 c6bca38c1cbf
equal deleted inserted replaced
68:5ff1fc726848 69:c6bca38c1cbf
       
     1 ========================
       
     2 Django 1.2 release notes
       
     3 ========================
       
     4 
       
     5 *May 17, 2010.*
       
     6 
       
     7 Welcome to Django 1.2!
       
     8 
       
     9 Nearly a year in the making, Django 1.2 packs an impressive list of `new
       
    10 features`_ and lots of bug fixes. These release notes cover the new features,
       
    11 as well as important changes you'll want to be aware of when upgrading from
       
    12 Django 1.1 or older versions.
       
    13 
       
    14 .. _new features: `What's new in Django 1.2`_
       
    15 
       
    16 Overview
       
    17 ========
       
    18 
       
    19 Django 1.2 introduces several large, important new features, including:
       
    20 
       
    21     * Support for `multiple database connections`_ in a single Django instance.
       
    22 
       
    23     * `Model validation`_ inspired by Django's form validation.
       
    24 
       
    25     * Vastly `improved protection against Cross-Site Request Forgery`_ (CSRF).
       
    26 
       
    27     * A new `user "messages" framework`_ with support for cookie- and session-based
       
    28       message for both anonymous and authenticated users.
       
    29 
       
    30     * Hooks for `object-level permissions`_, `permissions for anonymous users`_,
       
    31       and `more flexible username requirements`_.
       
    32 
       
    33     * Customization of e-mail sending via `e-mail backends`_.
       
    34 
       
    35     * New :ref:`"smart" if template tag <new-in-1.2-smart-if>` which supports
       
    36       comparison operators.
       
    37 
       
    38 .. _multiple database connections: `support for multiple databases`_
       
    39 .. _improved protection against Cross-Site Request Forgery: `improved CSRF protection`_
       
    40 .. _user "messages" framework: `messages framework`_
       
    41 .. _more flexible username requirements: `relaxed requirements for usernames`_
       
    42 
       
    43 These are just the highlights; full details and a complete list of features `may
       
    44 be found below`_.
       
    45 
       
    46 .. _may be found below: `what's new in django 1.2`_
       
    47 
       
    48 .. seealso::
       
    49 
       
    50     `Django Advent`_ covered the release of Django 1.2 with a series of
       
    51     articles and tutorials that cover some of the new features in depth.
       
    52 
       
    53 .. _django advent: http://djangoadvent.com/
       
    54 
       
    55 Wherever possible these features have been introduced in a backwards-compatible
       
    56 manner per :doc:`our API stability policy </misc/api-stability>` policy.
       
    57 
       
    58 However, a handful of features *have* changed in ways that, for some users, will be
       
    59 backwards-incompatible. The big changes are:
       
    60 
       
    61     * Support for Python 2.3 has been dropped. See the full notes
       
    62       below.
       
    63 
       
    64     * The new CSRF protection framework is not backwards-compatible with
       
    65       the old system. Users of the old system will not be affected until
       
    66       the old system is removed in Django 1.4.
       
    67 
       
    68       However, upgrading to the new CSRF protection framework requires a few
       
    69       important backwards-incompatible changes, detailed in `CSRF Protection`_,
       
    70       below.
       
    71 
       
    72     * Authors of custom :class:`~django.db.models.Field` subclasses should be
       
    73       aware that a number of methods have had a change in prototype, detailed
       
    74       under `get_db_prep_*() methods on Field`_, below.
       
    75 
       
    76     * The internals of template tags have changed somewhat; authors of custom
       
    77       template tags that need to store state (e.g. custom control flow tags)
       
    78       should ensure that their code follows the new rules for `stateful template
       
    79       tags`_
       
    80 
       
    81     * The :func:`~django.contrib.auth.decorators.user_passes_test`,
       
    82       :func:`~django.contrib.auth.decorators.login_required`, and
       
    83       :func:`~django.contrib.auth.decorators.permission_required`, decorators
       
    84       from :mod:`django.contrib.auth` only apply to functions and no longer
       
    85       work on methods. There's a simple one-line fix `detailed below`_.
       
    86 
       
    87 .. _detailed below: `user_passes_test, login_required and permission_required`_
       
    88 
       
    89 Again, these are just the big features that will affect the most users. Users
       
    90 upgrading from previous versions of Django are heavily encouraged to consult
       
    91 the complete list of :ref:`backwards-incompatible changes
       
    92 <backwards-incompatible-changes-1.2>` and the list of :ref:`deprecated
       
    93 features <deprecated-features-1.2>`.
       
    94 
       
    95 Python compatibility
       
    96 ====================
       
    97 
       
    98 While not a new feature, it's important to note that Django 1.2
       
    99 introduces the first shift in our Python compatibility policy since
       
   100 Django's initial public debut. Previous Django releases were tested
       
   101 and supported on 2.x Python versions from 2.3 up; Django 1.2, however,
       
   102 drops official support for Python 2.3. As such, the minimum Python
       
   103 version required for Django is now 2.4, and Django is tested and
       
   104 supported on Python 2.4, 2.5 and 2.6, and will be supported on the
       
   105 as-yet-unreleased Python 2.7.
       
   106 
       
   107 This change should affect only a small number of Django users, as most
       
   108 operating-system vendors today are shipping Python 2.4 or newer as
       
   109 their default version. If you're still using Python 2.3, however,
       
   110 you'll need to stick to Django 1.1 until you can upgrade; per
       
   111 :doc:`our support policy </internals/release-process>`, Django 1.1 will
       
   112 continue to receive security support until the release of Django 1.3.
       
   113 
       
   114 A roadmap for Django's overall 2.x Python support, and eventual
       
   115 transition to Python 3.x, is currently being developed, and will be
       
   116 announced prior to the release of Django 1.3.
       
   117 
       
   118 What's new in Django 1.2
       
   119 ========================
       
   120 
       
   121 Support for multiple databases
       
   122 ------------------------------
       
   123 
       
   124 Django 1.2 adds the ability to use :doc:`more than one database
       
   125 </topics/db/multi-db>` in your Django project. Queries can be issued at a
       
   126 specific database with the `using()` method on ``QuerySet`` objects. Individual
       
   127 objects can be saved to a specific database by providing a ``using`` argument
       
   128 when you call ``save()``.
       
   129 
       
   130 Model validation
       
   131 ----------------
       
   132 
       
   133 Model instances now have support for :ref:`validating their own data
       
   134 <validating-objects>`, and both model and form fields now accept configurable
       
   135 lists of :doc:`validators </ref/validators>` specifying reusable, encapsulated
       
   136 validation behavior. Note, however, that validation must still be performed
       
   137 explicitly. Simply invoking a model instance's ``save()`` method will not
       
   138 perform any validation of the instance's data.
       
   139 
       
   140 Improved CSRF protection
       
   141 ------------------------
       
   142 
       
   143 Django now has much improved protection against :doc:`Cross-Site Request Forgery
       
   144 (CSRF) attacks</ref/contrib/csrf>`. This type of attack occurs when a malicious
       
   145 Web site contains a link, a form button or some JavaScript that is intended to
       
   146 perform some action on your Web site, using the credentials of a logged-in user
       
   147 who visits the malicious site in their browser. A related type of attack, "login
       
   148 CSRF," where an attacking site tricks a user's browser into logging into a site
       
   149 with someone else's credentials, is also covered.
       
   150 
       
   151 Messages framework
       
   152 ------------------
       
   153 
       
   154 Django now includes a robust and configurable :doc:`messages framework
       
   155 </ref/contrib/messages>` with built-in support for cookie- and session-based
       
   156 messaging, for both anonymous and authenticated clients. The messages framework
       
   157 replaces the deprecated user message API and allows you to temporarily store
       
   158 messages in one request and retrieve them for display in a subsequent request
       
   159 (usually the next one).
       
   160 
       
   161 Object-level permissions
       
   162 ------------------------
       
   163 
       
   164 A foundation for specifying permissions at the per-object level has been added.
       
   165 Although there is no implementation of this in core, a custom authentication
       
   166 backend can provide this implementation and it will be used by
       
   167 :class:`django.contrib.auth.models.User`. See the :doc:`authentication docs
       
   168 </topics/auth>` for more information.
       
   169 
       
   170 Permissions for anonymous users
       
   171 -------------------------------
       
   172 
       
   173 If you provide a custom auth backend with ``supports_anonymous_user`` set to
       
   174 ``True``, AnonymousUser will check the backend for permissions, just like
       
   175 User already did.  This is useful for centralizing permission handling - apps
       
   176 can always delegate the question of whether something is allowed or not to
       
   177 the authorization/authentication backend. See the :doc:`authentication
       
   178 docs </topics/auth>` for more details.
       
   179 
       
   180 Relaxed requirements for usernames
       
   181 ----------------------------------
       
   182 
       
   183 The built-in :class:`~django.contrib.auth.models.User` model's
       
   184 :attr:`~django.contrib.auth.models.User.username` field now allows a wider range
       
   185 of characters, including ``@``, ``+``, ``.`` and ``-`` characters.
       
   186 
       
   187 E-mail backends
       
   188 ---------------
       
   189 
       
   190 You can now :ref:`configure the way that Django sends e-mail
       
   191 <topic-email-backends>`. Instead of using SMTP to send all e-mail, you
       
   192 can now choose a configurable e-mail backend to send messages. If your
       
   193 hosting provider uses a sandbox or some other non-SMTP technique for
       
   194 sending mail, you can now construct an e-mail backend that will allow
       
   195 Django's standard :doc:`mail sending methods</topics/email>` to use
       
   196 those facilities.
       
   197 
       
   198 This also makes it easier to debug mail sending. Django ships with
       
   199 backend implementations that allow you to send e-mail to a
       
   200 :ref:`file<topic-email-file-backend>`, to the
       
   201 :ref:`console<topic-email-console-backend>`, or to
       
   202 :ref:`memory<topic-email-memory-backend>`. You can even configure all
       
   203 e-mail to be :ref:`thrown away<topic-email-dummy-backend>`.
       
   204 
       
   205 .. _new-in-1.2-smart-if:
       
   206 
       
   207 "Smart" :ttag:`if` tag
       
   208 ----------------------
       
   209 
       
   210 The :ttag:`if` tag has been upgraded to be much more powerful. First, we've
       
   211 added support for comparison operators. No longer will you have to type:
       
   212 
       
   213 .. code-block:: html+django
       
   214 
       
   215     {% ifnotequal a b %}
       
   216      ...
       
   217     {% endifnotequal %}
       
   218 
       
   219 You can now do this:
       
   220 
       
   221 .. code-block:: html+django
       
   222 
       
   223     {% if a != b %}
       
   224      ...
       
   225     {% endif %}
       
   226 
       
   227 There's really no reason to use ``{% ifequal %}`` or ``{% ifnotequal %}``
       
   228 anymore, unless you're the nostalgic type.
       
   229 
       
   230 The operators supported are ``==``, ``!=``, ``<``, ``>``, ``<=``, ``>=``,
       
   231 ``in`` and ``not in``, all of which work like the Python operators, in addition
       
   232 to ``and``, ``or`` and ``not``, which were already supported.
       
   233 
       
   234 Also, filters may now be used in the ``if`` expression. For example:
       
   235 
       
   236 .. code-block:: html+django
       
   237 
       
   238       <div
       
   239         {% if user.email|lower == message.recipient|lower %}
       
   240           class="highlight"
       
   241         {% endif %}
       
   242       >{{ message }}</div>
       
   243 
       
   244 Template caching
       
   245 ----------------
       
   246 
       
   247 In previous versions of Django, every time you rendered a template, it
       
   248 would be reloaded from disk. In Django 1.2, you can use a :ref:`cached
       
   249 template loader <template-loaders>` to load templates once, then
       
   250 cache the result for every subsequent render. This can lead to a
       
   251 significant performance improvement if your templates are broken into
       
   252 lots of smaller subtemplates (using the ``{% extends %}`` or ``{%
       
   253 include %}`` tags).
       
   254 
       
   255 As a side effect, it is now much easier to support non-Django template
       
   256 languages. For more details, see the :ref:`notes on supporting
       
   257 non-Django template languages<topic-template-alternate-language>`.
       
   258 
       
   259 Natural keys in fixtures
       
   260 ------------------------
       
   261 
       
   262 Fixtures can now refer to remote objects using
       
   263 :ref:`topics-serialization-natural-keys`. This lookup scheme is an
       
   264 alternative to the normal primary-key based object references in a
       
   265 fixture, improving readability and resolving problems referring to
       
   266 objects whose primary key value may not be predictable or known.
       
   267 
       
   268 Fast failure for tests
       
   269 ----------------------
       
   270 
       
   271 Both the :djadmin:`test` subcommand of ``django-admin.py`` and the
       
   272 ``runtests.py`` script used to run Django's own test suite now support a
       
   273 ``--failfast`` option. When specified, this option causes the test runner to
       
   274 exit after encountering a failure instead of continuing with the test run. In
       
   275 addition, the handling of ``Ctrl-C`` during a test run has been improved to
       
   276 trigger a graceful exit from the test run that reports details of the tests that
       
   277 were run before the interruption.
       
   278 
       
   279 ``BigIntegerField``
       
   280 -------------------
       
   281 
       
   282 Models can now use a 64-bit :class:`~django.db.models.BigIntegerField` type.
       
   283 
       
   284 Improved localization
       
   285 ---------------------
       
   286 
       
   287 Django's :doc:`internationalization framework </topics/i18n/index>` has been expanded
       
   288 with locale-aware formatting and form processing. That means, if enabled, dates
       
   289 and numbers on templates will be displayed using the format specified for the
       
   290 current locale. Django will also use localized formats when parsing data in
       
   291 forms. See :ref:`Format localization <format-localization>` for more details.
       
   292 
       
   293 ``readonly_fields`` in ``ModelAdmin``
       
   294 -------------------------------------
       
   295 
       
   296 :attr:`django.contrib.admin.ModelAdmin.readonly_fields` has been added to
       
   297 enable non-editable fields in add/change pages for models and inlines. Field
       
   298 and calculated values can be displayed alongside editable fields.
       
   299 
       
   300 Customizable syntax highlighting
       
   301 --------------------------------
       
   302 
       
   303 You can now use a ``DJANGO_COLORS`` environment variable to modify or disable
       
   304 the colors used by ``django-admin.py`` to provide :ref:`syntax highlighting
       
   305 <syntax-coloring>`.
       
   306 
       
   307 Syndication feeds as views
       
   308 --------------------------
       
   309 
       
   310 :doc:`Syndication feeds </ref/contrib/syndication>` can now be used directly as
       
   311 views in your :doc:`URLconf </topics/http/urls>`. This means that you can
       
   312 maintain complete control over the URL structure of your feeds. Like any other
       
   313 view, feeds views are passed a ``request`` object, so you can do anything you
       
   314 would normally do with a view, like user based access control, or making a feed
       
   315 a named URL.
       
   316 
       
   317 GeoDjango
       
   318 ---------
       
   319 
       
   320 The most significant new feature for :doc:`GeoDjango </ref/contrib/gis/index>`
       
   321 in 1.2 is support for multiple spatial databases.  As a result,
       
   322 the following :ref:`spatial database backends <spatial-backends>`
       
   323 are now included:
       
   324 
       
   325 * :mod:`django.contrib.gis.db.backends.postgis`
       
   326 * :mod:`django.contrib.gis.db.backends.mysql`
       
   327 * :mod:`django.contrib.gis.db.backends.oracle`
       
   328 * :mod:`django.contrib.gis.db.backends.spatialite`
       
   329 
       
   330 GeoDjango now supports the rich capabilities added
       
   331 in the `PostGIS 1.5 release <http://postgis.refractions.net/documentation/manual-1.5/>`_.
       
   332 New features include suppport for the the :ref:`geography type <geography-type>`
       
   333 and enabling of :ref:`distance queries <distance-queries>`
       
   334 with non-point geometries on geographic coordinate systems.
       
   335 
       
   336 Support for 3D geometry fields was added, and may be enabled
       
   337 by setting the :attr:`~django.contrib.gis.db.models.GeometryField.dim`
       
   338 keyword to 3 in your :class:`~django.contrib.gis.db.models.GeometryField`.
       
   339 The :class:`~django.contrib.gis.db.models.Extent3D` aggregate
       
   340 and :meth:`~django.contrib.gis.db.models.GeoQuerySet.extent3d` ``GeoQuerySet``
       
   341 method were added as a part of this feature.
       
   342 
       
   343 The following :class:`~django.contrib.gis.db.models.GeoQuerySet`
       
   344 methods are new in 1.2:
       
   345 
       
   346 * :meth:`~django.contrib.gis.db.models.GeoQuerySet.force_rhr`
       
   347 * :meth:`~django.contrib.gis.db.models.GeoQuerySet.reverse_geom`
       
   348 * :meth:`~django.contrib.gis.db.models.GeoQuerySet.geohash`
       
   349 
       
   350 The :ref:`GEOS interface <ref-geos>` was updated to use
       
   351 thread-safe C library functions when available on the platform.
       
   352 
       
   353 The :ref:`GDAL interface <ref-gdal>` now allows the user to
       
   354 set a :attr:`~django.contrib.gis.gdal.Layer.spatial_filter` on
       
   355 the features returned when iterating over a
       
   356 :class:`~django.contrib.gis.gdal.Layer`.
       
   357 
       
   358 Finally, :doc:`GeoDjango's documentation </ref/contrib/gis/index>` is now
       
   359 included with Django's and is no longer
       
   360 hosted separately at `geodjango.org <http://geodjango.org/>`_.
       
   361 
       
   362 .. _1.2-js-assisted-inlines:
       
   363 
       
   364 JavaScript-assisted handling of inline related objects in the admin
       
   365 -------------------------------------------------------------------
       
   366 
       
   367 If a user has JavaScript enabled in their browser, the interface for
       
   368 inline objects in the admin now allows inline objects to be
       
   369 dynamically added and removed. Users without JavaScript-enabled
       
   370 browsers will see no change in the behavior of inline objects.
       
   371 
       
   372 New ``now`` template tag format specifier characters: ``c`` and ``u``
       
   373 ---------------------------------------------------------------------
       
   374 
       
   375 The argument to the :ttag:`now` has gained two new format characters:
       
   376 ``c`` to specify that a datetime value should be formatted in ISO 8601
       
   377 format, and ``u`` that allows output of the microseconds part of a
       
   378 datetime or time value.
       
   379 
       
   380 These are also available in others parts like the :tfilter:`date` and
       
   381 :tfilter:`time` template filters, the ``humanize`` template tag library
       
   382 and the new `format localization`_ framework.
       
   383 
       
   384 .. _format localization: `Improved localization`_
       
   385 
       
   386 .. _backwards-incompatible-changes-1.2:
       
   387 
       
   388 Backwards-incompatible changes in 1.2
       
   389 =====================================
       
   390 
       
   391 Wherever possible the new features above have been introduced in a
       
   392 backwards-compatible manner per :doc:`our API stability policy
       
   393 </misc/api-stability>` policy. This means that practically all existing
       
   394 code which worked with Django 1.1 will continue to work with Django
       
   395 1.2; such code will, however, begin issuing warnings (see below for
       
   396 details).
       
   397 
       
   398 However, a handful of features *have* changed in ways that, for some
       
   399 users, will be immediately backwards-incompatible. Those changes are
       
   400 detailed below.
       
   401 
       
   402 CSRF Protection
       
   403 ---------------
       
   404 
       
   405 We've made large changes to the way CSRF protection works, detailed in
       
   406 :doc:`the CSRF documentaton </ref/contrib/csrf>`. Here are the major changes you
       
   407 should be aware of:
       
   408 
       
   409  * ``CsrfResponseMiddleware`` and ``CsrfMiddleware`` have been deprecated and
       
   410    will be removed completely in Django 1.4, in favor of a template tag that
       
   411    should be inserted into forms.
       
   412 
       
   413  * All contrib apps use a ``csrf_protect`` decorator to protect the view. This
       
   414    requires the use of the ``csrf_token`` template tag in the template. If you
       
   415    have used custom templates for contrib views, you MUST READ THE :ref:`UPGRADE
       
   416    INSTRUCTIONS <ref-csrf-upgrading-notes>` to fix those templates.
       
   417 
       
   418  * ``CsrfViewMiddleware`` is included in :setting:`MIDDLEWARE_CLASSES` by
       
   419    default. This turns on CSRF protection by default, so views that accept
       
   420    POST requests need to be written to work with the middleware. Instructions
       
   421    on how to do this are found in the CSRF docs.
       
   422 
       
   423  * All of the CSRF has moved from contrib to core (with backwards
       
   424    compatible imports in the old locations, which are deprecated and
       
   425    will cease to be supported in Django 1.4).
       
   426 
       
   427 ``get_db_prep_*()`` methods on ``Field``
       
   428 ----------------------------------------
       
   429 
       
   430 Prior to Django 1.2, a custom ``Field`` had the option of defining
       
   431 several functions to support conversion of Python values into
       
   432 database-compatible values. A custom field might look something like::
       
   433 
       
   434     class CustomModelField(models.Field):
       
   435         # ...
       
   436         def db_type(self):
       
   437             # ...
       
   438 
       
   439         def get_db_prep_save(self, value):
       
   440             # ...
       
   441 
       
   442         def get_db_prep_value(self, value):
       
   443             # ...
       
   444 
       
   445         def get_db_prep_lookup(self, lookup_type, value):
       
   446             # ...
       
   447 
       
   448 In 1.2, these three methods have undergone a change in prototype, and
       
   449 two extra methods have been introduced::
       
   450 
       
   451     class CustomModelField(models.Field):
       
   452         # ...
       
   453 
       
   454         def db_type(self, connection):
       
   455             # ...
       
   456 
       
   457         def get_prep_value(self, value):
       
   458             # ...
       
   459 
       
   460         def get_prep_lookup(self, lookup_type, value):
       
   461             # ...
       
   462 
       
   463         def get_db_prep_save(self, value, connection):
       
   464             # ...
       
   465 
       
   466         def get_db_prep_value(self, value, connection, prepared=False):
       
   467             # ...
       
   468 
       
   469         def get_db_prep_lookup(self, lookup_type, value, connection, prepared=False):
       
   470             # ...
       
   471 
       
   472 These changes are required to support multiple databases --
       
   473 ``db_type`` and ``get_db_prep_*`` can no longer make any assumptions
       
   474 regarding the database for which it is preparing. The ``connection``
       
   475 argument now provides the preparation methods with the specific
       
   476 connection for which the value is being prepared.
       
   477 
       
   478 The two new methods exist to differentiate general data-preparation
       
   479 requirements from requirements that are database-specific. The
       
   480 ``prepared`` argument is used to indicate to the database-preparation
       
   481 methods whether generic value preparation has been performed. If
       
   482 an unprepared (i.e., ``prepared=False``) value is provided to the
       
   483 ``get_db_prep_*()`` calls, they should invoke the corresponding
       
   484 ``get_prep_*()`` calls to perform generic data preparation.
       
   485 
       
   486 We've provided conversion functions that will transparently
       
   487 convert functions adhering to the old prototype into functions
       
   488 compatible with the new prototype. However, these conversion functions
       
   489 will be removed in Django 1.4, so you should upgrade your ``Field``
       
   490 definitions to use the new prototype as soon as possible.
       
   491 
       
   492 If your ``get_db_prep_*()`` methods made no use of the database
       
   493 connection, you should be able to upgrade by renaming
       
   494 ``get_db_prep_value()`` to ``get_prep_value()`` and
       
   495 ``get_db_prep_lookup()`` to ``get_prep_lookup()``. If you require
       
   496 database specific conversions, then you will need to provide an
       
   497 implementation ``get_db_prep_*`` that uses the ``connection``
       
   498 argument to resolve database-specific values.
       
   499 
       
   500 Stateful template tags
       
   501 ----------------------
       
   502 
       
   503 Template tags that store rendering state on their ``Node`` subclass
       
   504 have always been vulnerable to thread-safety and other issues; as of
       
   505 Django 1.2, however, they may also cause problems when used with the
       
   506 new :ref:`cached template loader<template-loaders>`.
       
   507 
       
   508 All of the built-in Django template tags are safe to use with the cached
       
   509 loader, but if you're using custom template tags that come from third
       
   510 party packages, or from your own code, you should ensure that the
       
   511 ``Node`` implementation for each tag is thread-safe. For more
       
   512 information, see
       
   513 :ref:`template tag thread safety considerations<template_tag_thread_safety>`.
       
   514 
       
   515 You may also need to update your templates if you were relying on the
       
   516 implementation of Django's template tags *not* being thread safe. The
       
   517 :ttag:`cycle` tag is the most likely to be affected in this way,
       
   518 especially when used in conjunction with the :ttag:`include` tag.
       
   519 Consider the following template fragment::
       
   520 
       
   521     {% for object in object_list %}
       
   522         {% include "subtemplate.html" %}
       
   523     {% endfor %}
       
   524 
       
   525 with a ``subtemplate.html`` that reads::
       
   526 
       
   527     {% cycle 'even' 'odd' %}
       
   528 
       
   529 Using the non-thread-safe, pre-Django 1.2 renderer, this would output::
       
   530 
       
   531     even odd even odd ...
       
   532 
       
   533 Using the thread-safe Django 1.2 renderer, you will instead get::
       
   534 
       
   535     even even even even ...
       
   536 
       
   537 This is because each rendering of the :ttag:`include` tag is an
       
   538 independent rendering. When the :ttag:`cycle` tag was not thread safe,
       
   539 the state of the :ttag:`cycle` tag would leak between multiple
       
   540 renderings of the same :ttag:`include`. Now that the :ttag:`cycle` tag
       
   541 is thread safe, this leakage no longer occurs.
       
   542 
       
   543 ``user_passes_test``, ``login_required`` and ``permission_required``
       
   544 --------------------------------------------------------------------
       
   545 
       
   546 ``django.contrib.auth.decorators`` provides the decorators
       
   547 ``login_required``, ``permission_required`` and
       
   548 ``user_passes_test``. Previously it was possible to use these
       
   549 decorators both on functions (where the first argument is 'request')
       
   550 and on methods (where the first argument is 'self', and the second
       
   551 argument is 'request'). Unfortunately, flaws were discovered in the
       
   552 code supporting this: it only works in limited circumstances, and
       
   553 produces errors that are very difficult to debug when it does not
       
   554 work.
       
   555 
       
   556 For this reason, the 'auto adapt' behavior has been removed, and if
       
   557 you are using these decorators on methods, you will need to manually
       
   558 apply :func:`django.utils.decorators.method_decorator` to convert the
       
   559 decorator to one that works with methods. For example, you would
       
   560 change code from this::
       
   561 
       
   562     class MyClass(object):
       
   563 
       
   564         @login_required
       
   565         def my_view(self, request):
       
   566             pass
       
   567 
       
   568 to this::
       
   569 
       
   570     from django.utils.decorators import method_decorator
       
   571 
       
   572     class MyClass(object):
       
   573 
       
   574         @method_decorator(login_required)
       
   575         def my_view(self, request):
       
   576             pass
       
   577 
       
   578 or::
       
   579 
       
   580     from django.utils.decorators import method_decorator
       
   581 
       
   582     login_required_m = method_decorator(login_required)
       
   583 
       
   584     class MyClass(object):
       
   585 
       
   586         @login_required_m
       
   587         def my_view(self, request):
       
   588             pass
       
   589 
       
   590 For those of you who've been following the development trunk, this
       
   591 change also applies to other decorators introduced since 1.1,
       
   592 including ``csrf_protect``, ``cache_control`` and anything created
       
   593 using ``decorator_from_middleware``.
       
   594 
       
   595 :ttag:`if` tag changes
       
   596 ----------------------
       
   597 
       
   598 Due to new features in the :ttag:`if` template tag, it no longer
       
   599 accepts 'and', 'or' and 'not' as valid **variable** names. Previously,
       
   600 these strings could be used as variable names. Now, the keyword status
       
   601 is always enforced, and template code such as ``{% if not %}`` or ``{%
       
   602 if and %}`` will throw a ``TemplateSyntaxError``. Also, ``in`` is a
       
   603 new keyword and so is not a valid variable name in this tag.
       
   604 
       
   605 ``LazyObject``
       
   606 --------------
       
   607 
       
   608 ``LazyObject`` is an undocumented-but-often-used utility class used for lazily
       
   609 wrapping other objects of unknown type.
       
   610 
       
   611 In Django 1.1 and earlier, it handled introspection in a non-standard way,
       
   612 depending on wrapped objects implementing a public method named
       
   613 ``get_all_members()``. Since this could easily lead to name clashes, it has been
       
   614 changed to use the standard Python introspection method, involving
       
   615 ``__members__`` and ``__dir__()``.
       
   616 
       
   617 If you used ``LazyObject`` in your own code
       
   618 and implemented the ``get_all_members()`` method for wrapped objects, you'll need
       
   619 to make a couple of changes:
       
   620 
       
   621 First, if your class does not have special requirements for introspection (i.e.,
       
   622 you have not implemented ``__getattr__()`` or other methods that allow for
       
   623 attributes not discoverable by normal mechanisms), you can simply remove the
       
   624 ``get_all_members()`` method. The default implementation on ``LazyObject`` will
       
   625 do the right thing.
       
   626 
       
   627 If you have more complex requirements for introspection, first rename the
       
   628 ``get_all_members()`` method to ``__dir__()``. This is the standard
       
   629 introspection method for Python 2.6 and above. If you require support for Python
       
   630 versions earlier than 2.6, add the following code to the class::
       
   631 
       
   632     __members__ = property(lambda self: self.__dir__())
       
   633 
       
   634 ``__dict__`` on model instances
       
   635 -------------------------------
       
   636 
       
   637 Historically, the ``__dict__`` attribute of a model instance has only contained
       
   638 attributes corresponding to the fields on a model.
       
   639 
       
   640 In order to support multiple database configurations, Django 1.2 has
       
   641 added a ``_state`` attribute to object instances. This attribute will
       
   642 appear in ``__dict__`` for a model instance. If your code relies on
       
   643 iterating over ``__dict__`` to obtain a list of fields, you must now
       
   644 be prepared to handle or filter out the ``_state`` attribute.
       
   645 
       
   646 Test runner exit status code
       
   647 ----------------------------
       
   648 
       
   649 The exit status code of the test runners (``tests/runtests.py`` and ``python
       
   650 manage.py test``) no longer represents the number of failed tests, because a
       
   651 failure of 256 or more tests resulted in a wrong exit status code. The exit
       
   652 status code for the test runner is now 0 for success (no failing tests) and 1
       
   653 for any number of test failures. If needed, the number of test failures can be
       
   654 found at the end of the test runner's output.
       
   655 
       
   656 Cookie encoding
       
   657 ---------------
       
   658 
       
   659 To fix bugs with cookies in Internet Explorer, Safari, and possibly
       
   660 other browsers, our encoding of cookie values was changed so that the
       
   661 comma and semicolon are treated as non-safe characters, and are
       
   662 therefore encoded as ``\054`` and ``\073`` respectively.  This could
       
   663 produce backwards incompatibilities, especially if you are storing
       
   664 comma or semi-colon in cookies and have javascript code that parses
       
   665 and manipulates cookie values client-side.
       
   666 
       
   667 ``ModelForm.is_valid()`` and ``ModelForm.errors``
       
   668 -------------------------------------------------
       
   669 
       
   670 Much of the validation work for ModelForms has been moved down to the model
       
   671 level. As a result, the first time you call ``ModelForm.is_valid()``, access
       
   672 ``ModelForm.errors`` or otherwise trigger form validation, your model will be
       
   673 cleaned in-place. This conversion used to happen when the model was saved. If
       
   674 you need an unmodified instance of your model, you should pass a copy to the
       
   675 ``ModelForm`` constructor.
       
   676 
       
   677 ``BooleanField`` on MySQL
       
   678 --------------------------
       
   679 
       
   680 In previous versions of Django, a model's ``BooleanField`` under MySQL
       
   681 would return its value as either ``1`` or ``0``, instead of ``True``
       
   682 or ``False``; for most people this wasn't a problem because ``bool``
       
   683 is a subclass of ``int`` in Python. In Django 1.2, however,
       
   684 ``BooleanField`` on MySQL correctly returns a real ``bool``.  The only
       
   685 time this should ever be an issue is if you were expecting the
       
   686 ``repr`` of a ``BooleanField`` to print ``1`` or ``0``.
       
   687 
       
   688 Changes to the interpretation of ``max_num`` in FormSets
       
   689 --------------------------------------------------------
       
   690 
       
   691 As part of enhancements made to the handling of FormSets, the default
       
   692 value and interpretation of the ``max_num`` parameter to the
       
   693 :ref:`django.forms.formsets.formset_factory() <formsets-max-num>` and
       
   694 :ref:`django.forms.models.modelformset_factory()
       
   695 <model-formsets-max-num>` functions has changed slightly. This
       
   696 change also affects the way the ``max_num`` argument is :ref:`used for
       
   697 inline admin objects <ref-contrib-admin-inline-max-num>`
       
   698 
       
   699 Previously, the default value for ``max_num`` was ``0`` (zero).
       
   700 FormSets then used the boolean value of ``max_num`` to determine if a
       
   701 limit was to be imposed on the number of generated forms. The default
       
   702 value of ``0`` meant that there was no default limit on the number of
       
   703 forms in a FormSet.
       
   704 
       
   705 Starting with 1.2, the default value for ``max_num`` has been changed
       
   706 to ``None``, and FormSets will differentiate between a value of
       
   707 ``None`` and a value of ``0``. A value of ``None`` indicates that no
       
   708 limit on the number of forms is to be imposed; a value of ``0``
       
   709 indicates that a maximum of 0 forms should be imposed. This doesn't
       
   710 necessarily mean that no forms will be displayed -- see the
       
   711 :ref:`ModelFormSet documentation <model-formsets-max-num>` for more
       
   712 details.
       
   713 
       
   714 If you were manually specifying a value of ``0`` for ``max_num``, you
       
   715 will need to update your FormSet and/or admin definitions.
       
   716 
       
   717 .. seealso::
       
   718 
       
   719     :ref:`1.2-js-assisted-inlines`
       
   720 
       
   721 ``email_re``
       
   722 ------------
       
   723 
       
   724 An undocumented regular expression for validating email addresses has been moved
       
   725 from ``django.form.fields`` to ``django.core.validators``. You will need to
       
   726 update your imports if you are using it.
       
   727 
       
   728 .. _deprecated-features-1.2:
       
   729 
       
   730 Features deprecated in 1.2
       
   731 ==========================
       
   732 
       
   733 Finally, Django 1.2 deprecates some features from earlier releases.
       
   734 These features are still supported, but will be gradually phased out
       
   735 over the next few release cycles.
       
   736 
       
   737 Code taking advantage of any of the features below will raise a
       
   738 ``PendingDeprecationWarning`` in Django 1.2. This warning will be
       
   739 silent by default, but may be turned on using Python's `warnings
       
   740 module`_, or by running Python with a ``-Wd`` or `-Wall` flag.
       
   741 
       
   742 .. _warnings module: http://docs.python.org/library/warnings.html
       
   743 
       
   744 In Django 1.3, these warnings will become a ``DeprecationWarning``,
       
   745 which is *not* silent. In Django 1.4 support for these features will
       
   746 be removed entirely.
       
   747 
       
   748 .. seealso::
       
   749 
       
   750     For more details, see the documentation :doc:`Django's release process
       
   751     </internals/release-process>` and our :doc:`deprecation timeline
       
   752     </internals/deprecation>`.`
       
   753 
       
   754 .. _specifying-databases:
       
   755 
       
   756 Specifying databases
       
   757 --------------------
       
   758 
       
   759 Prior to Django 1.2, Django used a number of settings to control
       
   760 access to a single database. Django 1.2 introduces support for
       
   761 multiple databases, and as a result the way you define database
       
   762 settings has changed.
       
   763 
       
   764 Any existing Django settings file will continue to work as expected
       
   765 until Django 1.4. Until then, old-style database settings will be
       
   766 automatically translated to the new-style format.
       
   767 
       
   768 In the old-style (pre 1.2) format, you had a number of ``DATABASE_``
       
   769 settings in your settings file. For example::
       
   770 
       
   771     DATABASE_NAME = 'test_db'
       
   772     DATABASE_ENGINE = 'postgresql_psycopg2'
       
   773     DATABASE_USER = 'myusername'
       
   774     DATABASE_PASSWORD = 's3krit'
       
   775 
       
   776 These settings are now in a dictionary named
       
   777 :setting:`DATABASES`. Each item in the dictionary corresponds to a
       
   778 single database connection, with the name ``'default'`` describing the
       
   779 default database connection. The setting names have also been
       
   780 shortened. The previous sample settings would now look like this::
       
   781 
       
   782     DATABASES = {
       
   783         'default': {
       
   784             'NAME': 'test_db',
       
   785             'ENGINE': 'django.db.backends.postgresql_psycopg2',
       
   786             'USER': 'myusername',
       
   787             'PASSWORD': 's3krit',
       
   788         }
       
   789     }
       
   790 
       
   791 This affects the following settings:
       
   792 
       
   793     =========================================  ==========================
       
   794      Old setting                                New Setting
       
   795     =========================================  ==========================
       
   796     :setting:`DATABASE_ENGINE`                 :setting:`ENGINE`
       
   797     :setting:`DATABASE_HOST`                   :setting:`HOST`
       
   798     :setting:`DATABASE_NAME`                   :setting:`NAME`
       
   799     :setting:`DATABASE_OPTIONS`                :setting:`OPTIONS`
       
   800     :setting:`DATABASE_PASSWORD`               :setting:`PASSWORD`
       
   801     :setting:`DATABASE_PORT`                   :setting:`PORT`
       
   802     :setting:`DATABASE_USER`                   :setting:`USER`
       
   803     :setting:`TEST_DATABASE_CHARSET`           :setting:`TEST_CHARSET`
       
   804     :setting:`TEST_DATABASE_COLLATION`         :setting:`TEST_COLLATION`
       
   805     :setting:`TEST_DATABASE_NAME`              :setting:`TEST_NAME`
       
   806     =========================================  ==========================
       
   807 
       
   808 These changes are also required if you have manually created a database
       
   809 connection using ``DatabaseWrapper()`` from your database backend of choice.
       
   810 
       
   811 In addition to the change in structure, Django 1.2 removes the special
       
   812 handling for the built-in database backends. All database backends
       
   813 must now be specified by a fully qualified module name (i.e.,
       
   814 ``django.db.backends.postgresql_psycopg2``, rather than just
       
   815 ``postgresql_psycopg2``).
       
   816 
       
   817 ``postgresql`` database backend
       
   818 -------------------------------
       
   819 
       
   820 The ``psycopg1`` library has not been updated since October 2005. As a
       
   821 result, the ``postgresql`` database backend, which uses this library,
       
   822 has been deprecated.
       
   823 
       
   824 If you are currently using the ``postgresql`` backend, you should
       
   825 migrate to using the ``postgresql_psycopg2`` backend. To update your
       
   826 code, install the ``psycopg2`` library and change the
       
   827 :setting:`DATABASE_ENGINE` setting to use
       
   828 ``django.db.backends.postgresql_psycopg2``.
       
   829 
       
   830 CSRF response-rewriting middleware
       
   831 ----------------------------------
       
   832 
       
   833 ``CsrfResponseMiddleware``, the middleware that automatically inserted
       
   834 CSRF tokens into ``POST`` forms in outgoing pages, has been deprecated
       
   835 in favor of a template tag method (see above), and will be removed
       
   836 completely in Django 1.4. ``CsrfMiddleware``, which includes the
       
   837 functionality of ``CsrfResponseMiddleware`` and
       
   838 ``CsrfViewMiddleware``, has likewise been deprecated.
       
   839 
       
   840 Also, the CSRF module has moved from contrib to core, and the old
       
   841 imports are deprecated, as described in the :ref:`upgrading notes
       
   842 <ref-csrf-upgrading-notes>`.
       
   843 
       
   844 ``SMTPConnection``
       
   845 ------------------
       
   846 
       
   847 The ``SMTPConnection`` class has been deprecated in favor of a generic
       
   848 e-mail backend API. Old code that explicitly instantiated an instance
       
   849 of an SMTPConnection::
       
   850 
       
   851     from django.core.mail import SMTPConnection
       
   852     connection = SMTPConnection()
       
   853     messages = get_notification_email()
       
   854     connection.send_messages(messages)
       
   855 
       
   856 ...should now call :meth:`~django.core.mail.get_connection()` to
       
   857 instantiate a generic e-mail connection::
       
   858 
       
   859     from django.core.mail import get_connection
       
   860     connection = get_connection()
       
   861     messages = get_notification_email()
       
   862     connection.send_messages(messages)
       
   863 
       
   864 Depending on the value of the :setting:`EMAIL_BACKEND` setting, this
       
   865 may not return an SMTP connection. If you explicitly require an SMTP
       
   866 connection with which to send e-mail, you can explicitly request an
       
   867 SMTP connection::
       
   868 
       
   869     from django.core.mail import get_connection
       
   870     connection = get_connection('django.core.mail.backends.smtp.EmailBackend')
       
   871     messages = get_notification_email()
       
   872     connection.send_messages(messages)
       
   873 
       
   874 If your call to construct an instance of ``SMTPConnection`` required
       
   875 additional arguments, those arguments can be passed to the
       
   876 :meth:`~django.core.mail.get_connection()` call::
       
   877 
       
   878     connection = get_connection('django.core.mail.backends.smtp.EmailBackend', hostname='localhost', port=1234)
       
   879 
       
   880 User Messages API
       
   881 -----------------
       
   882 
       
   883 The API for storing messages in the user ``Message`` model (via
       
   884 ``user.message_set.create``) is now deprecated and will be removed in Django
       
   885 1.4 according to the standard :doc:`release process </internals/release-process>`.
       
   886 
       
   887 To upgrade your code, you need to replace any instances of this::
       
   888 
       
   889     user.message_set.create('a message')
       
   890 
       
   891 ...with the following::
       
   892 
       
   893     from django.contrib import messages
       
   894     messages.add_message(request, messages.INFO, 'a message')
       
   895 
       
   896 Additionally, if you make use of the method, you need to replace the
       
   897 following::
       
   898 
       
   899     for message in user.get_and_delete_messages():
       
   900         ...
       
   901 
       
   902 ...with::
       
   903 
       
   904     from django.contrib import messages
       
   905     for message in messages.get_messages(request):
       
   906         ...
       
   907 
       
   908 For more information, see the full
       
   909 :doc:`messages documentation </ref/contrib/messages>`. You should begin to
       
   910 update your code to use the new API immediately.
       
   911 
       
   912 Date format helper functions
       
   913 ----------------------------
       
   914 
       
   915 ``django.utils.translation.get_date_formats()`` and
       
   916 ``django.utils.translation.get_partial_date_formats()`` have been deprecated
       
   917 in favor of the appropriate calls to ``django.utils.formats.get_format()``,
       
   918 which is locale-aware when :setting:`USE_L10N` is set to ``True``, and falls
       
   919 back to default settings if set to ``False``.
       
   920 
       
   921 To get the different date formats, instead of writing this::
       
   922 
       
   923     from django.utils.translation import get_date_formats
       
   924     date_format, datetime_format, time_format = get_date_formats()
       
   925 
       
   926 ...use::
       
   927 
       
   928     from django.utils import formats
       
   929     date_format = formats.get_format('DATE_FORMAT')
       
   930     datetime_format = formats.get_format('DATETIME_FORMAT')
       
   931     time_format = formats.get_format('TIME_FORMAT')
       
   932 
       
   933 Or, when directly formatting a date value::
       
   934 
       
   935     from django.utils import formats
       
   936     value_formatted = formats.date_format(value, 'DATETIME_FORMAT')
       
   937 
       
   938 The same applies to the globals found in ``django.forms.fields``:
       
   939 
       
   940   * ``DEFAULT_DATE_INPUT_FORMATS``
       
   941   * ``DEFAULT_TIME_INPUT_FORMATS``
       
   942   * ``DEFAULT_DATETIME_INPUT_FORMATS``
       
   943 
       
   944 Use ``django.utils.formats.get_format()`` to get the appropriate formats.
       
   945 
       
   946 Function-based test runners
       
   947 ---------------------------
       
   948 
       
   949 Django 1.2 changes the test runner tools to use a class-based
       
   950 approach. Old style function-based test runners will still work, but
       
   951 should be updated to use the new :ref:`class-based runners
       
   952 <topics-testing-test_runner>`.
       
   953 
       
   954 .. _1.2-updating-feeds:
       
   955 
       
   956 ``Feed`` in ``django.contrib.syndication.feeds``
       
   957 ------------------------------------------------
       
   958 
       
   959 The :class:`django.contrib.syndication.feeds.Feed` class has been
       
   960 replaced by the :class:`django.contrib.syndication.views.Feed` class.
       
   961 The old ``feeds.Feed`` class is deprecated, and will be removed in
       
   962 Django 1.4.
       
   963 
       
   964 The new class has an almost identical API, but allows instances to be
       
   965 used as views. For example, consider the use of the old framework in
       
   966 the following :doc:`URLconf </topics/http/urls>`::
       
   967 
       
   968     from django.conf.urls.defaults import *
       
   969     from myproject.feeds import LatestEntries, LatestEntriesByCategory
       
   970 
       
   971     feeds = {
       
   972         'latest': LatestEntries,
       
   973         'categories': LatestEntriesByCategory,
       
   974     }
       
   975 
       
   976     urlpatterns = patterns('',
       
   977         # ...
       
   978         (r'^feeds/(?P<url>.*)/$', 'django.contrib.syndication.views.feed',
       
   979             {'feed_dict': feeds}),
       
   980         # ...
       
   981     )
       
   982 
       
   983 Using the new Feed class, these feeds can be deployed directly as views::
       
   984 
       
   985     from django.conf.urls.defaults import *
       
   986     from myproject.feeds import LatestEntries, LatestEntriesByCategory
       
   987 
       
   988     urlpatterns = patterns('',
       
   989         # ...
       
   990         (r'^feeds/latest/$', LatestEntries()),
       
   991         (r'^feeds/categories/(?P<category_id>\d+)/$', LatestEntriesByCategory()),
       
   992         # ...
       
   993     )
       
   994 
       
   995 If you currently use the ``feed()`` view, the ``LatestEntries`` class would
       
   996 often not need to be modified apart from subclassing the new
       
   997 :class:`~django.contrib.syndication.views.Feed` class. The exception is if
       
   998 Django was automatically working out the name of the template to use to render
       
   999 the feed's description and title elements (if you were not specifying the
       
  1000 ``title_template`` and ``description_template`` attributes). You should ensure
       
  1001 that you always specify ``title_template`` and ``description_template``
       
  1002 attributes, or provide ``item_title()`` and ``item_description()`` methods.
       
  1003 
       
  1004 However, ``LatestEntriesByCategory`` uses the ``get_object()`` method
       
  1005 with the ``bits`` argument to specify a specific category to show. In
       
  1006 the new :class:`~django.contrib.syndication.views.Feed` class,
       
  1007 ``get_object()`` method takes a ``request`` and arguments from the
       
  1008 URL, so it would look like this::
       
  1009 
       
  1010     from django.contrib.syndication.views import Feed
       
  1011     from django.shortcuts import get_object_or_404
       
  1012     from myproject.models import Category
       
  1013 
       
  1014     class LatestEntriesByCategory(Feed):
       
  1015         def get_object(self, request, category_id):
       
  1016             return get_object_or_404(Category, id=category_id)
       
  1017 
       
  1018         # ...
       
  1019 
       
  1020 Additionally, the ``get_feed()`` method on ``Feed`` classes now take
       
  1021 different arguments, which may impact you if you use the ``Feed``
       
  1022 classes directly. Instead of just taking an optional ``url`` argument,
       
  1023 it now takes two arguments: the object returned by its own
       
  1024 ``get_object()`` method, and the current ``request`` object.
       
  1025 
       
  1026 To take into account ``Feed`` classes not being initialized for each
       
  1027 request, the ``__init__()`` method now takes no arguments by default.
       
  1028 Previously it would have taken the ``slug`` from the URL and the
       
  1029 ``request`` object.
       
  1030 
       
  1031 In accordance with `RSS best practices`_, RSS feeds will now include
       
  1032 an ``atom:link`` element. You may need to update your tests to take
       
  1033 this into account.
       
  1034 
       
  1035 For more information, see the full :doc:`syndication framework
       
  1036 documentation </ref/contrib/syndication>`.
       
  1037 
       
  1038 .. _RSS best practices: http://www.rssboard.org/rss-profile
       
  1039 
       
  1040 Technical message IDs
       
  1041 ---------------------
       
  1042 
       
  1043 Up to version 1.1 Django used :ref:`technical message IDs<technical-messages>`
       
  1044 to provide localizers the possibility to translate date and time formats. They
       
  1045 were translatable :term:`translation strings <translation string>` that could
       
  1046 be recognized because they were all upper case (for example
       
  1047 ``DATETIME_FORMAT``, ``DATE_FORMAT``, ``TIME_FORMAT``). They have been
       
  1048 deprecated in favor of the new :ref:`Format localization
       
  1049 <format-localization>` infrastructure that allows localizers to specify that
       
  1050 information in a ``formats.py`` file in the corresponding
       
  1051 ``django/conf/locale/<locale name>/`` directory.
       
  1052 
       
  1053 GeoDjango
       
  1054 ---------
       
  1055 
       
  1056 To allow support for multiple databases, the GeoDjango database internals were
       
  1057 changed substantially.  The largest backwards-incompatible change is that
       
  1058 the module ``django.contrib.gis.db.backend`` was renamed to
       
  1059 :mod:`django.contrib.gis.db.backends`, where the full-fledged
       
  1060 :ref:`spatial database backends <spatial-backends>` now exist.  The
       
  1061 following sections provide information on the most-popular APIs that
       
  1062 were affected by these changes.
       
  1063 
       
  1064 ``SpatialBackend``
       
  1065 ^^^^^^^^^^^^^^^^^^
       
  1066 
       
  1067 Prior to the creation of the separate spatial backends, the
       
  1068 ``django.contrib.gis.db.backend.SpatialBackend`` object was
       
  1069 provided as an abstraction to introspect on the capabilities of
       
  1070 the spatial database.  All of the attributes and routines provided by
       
  1071 ``SpatialBackend`` are now a part of the ``ops`` attribute of the
       
  1072 database backend.
       
  1073 
       
  1074 The old module ``django.contrib.gis.db.backend`` is still provided
       
  1075 for backwards-compatibility access to a ``SpatialBackend`` object,
       
  1076 which is just an alias to the ``ops`` module of the
       
  1077 *default* spatial database connection.
       
  1078 
       
  1079 Users that were relying on undocumented modules and objects
       
  1080 within ``django.contrib.gis.db.backend``, rather the abstractions
       
  1081 provided by ``SpatialBackend``, are required to modify their code.
       
  1082 For example, the following import which would work in 1.1 and
       
  1083 below::
       
  1084 
       
  1085     from django.contrib.gis.db.backend.postgis import PostGISAdaptor
       
  1086 
       
  1087 Would need to be changed::
       
  1088 
       
  1089     from django.db import connection
       
  1090     PostGISAdaptor = connection.ops.Adapter
       
  1091 
       
  1092 ``SpatialRefSys`` and ``GeometryColumns`` models
       
  1093 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
       
  1094 
       
  1095 In previous versions of GeoDjango, :mod:`django.contrib.gis.db.models`
       
  1096 had ``SpatialRefSys`` and ``GeometryColumns`` models for querying
       
  1097 the OGC spatial metadata tables ``spatial_ref_sys`` and ``geometry_columns``,
       
  1098 respectively.
       
  1099 
       
  1100 While these aliases are still provided, they are only for the
       
  1101 *default* database connection and exist only if the default connection
       
  1102 is using a supported spatial database backend.
       
  1103 
       
  1104 .. note::
       
  1105 
       
  1106     Because the table structure of the OGC spatial metadata tables
       
  1107     differs across spatial databases, the ``SpatialRefSys`` and
       
  1108     ``GeometryColumns`` models can no longer be associated with
       
  1109     the ``gis`` application name.  Thus, no models will be returned
       
  1110     when using the ``get_models`` method in the following example::
       
  1111 
       
  1112         >>> from django.db.models import get_app, get_models
       
  1113         >>> get_models(get_app('gis'))
       
  1114         []
       
  1115 
       
  1116 To get the correct ``SpatialRefSys`` and ``GeometryColumns``
       
  1117 for your spatial database use the methods provided by the spatial backend::
       
  1118 
       
  1119      >>> from django.db import connections
       
  1120      >>> SpatialRefSys = connections['my_spatialite'].ops.spatial_ref_sys()
       
  1121      >>> GeometryColumns = connections['my_postgis'].ops.geometry_columns()
       
  1122 
       
  1123 .. note::
       
  1124 
       
  1125     When using the models returned from the ``spatial_ref_sys()`` and
       
  1126     ``geometry_columns()`` method, you'll still need to use the
       
  1127     correct database alias when querying on the non-default connection.
       
  1128     In other words, to ensure that the models in the example above
       
  1129     use the correct database::
       
  1130 
       
  1131         sr_qs = SpatialRefSys.objects.using('my_spatialite').filter(...)
       
  1132         gc_qs = GeometryColumns.objects.using('my_postgis').filter(...)
       
  1133 
       
  1134 Language code ``no``
       
  1135 --------------------
       
  1136 
       
  1137 The currently used language code for Norwegian Bokmål ``no`` is being
       
  1138 replaced by the more common language code ``nb``.
       
  1139