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