| 1 | ============================== |
| 2 | Django 1.4 beta release notes |
| 3 | ============================== |
| 4 | |
| 5 | December 22, 2011. |
| 6 | |
| 7 | Welcome to Django 1.4 beta! |
| 8 | |
| 9 | This is the first in a series of preview/development releases leading up to |
| 10 | the eventual release of Django 1.4, scheduled for March 2012. This release is |
| 11 | primarily targeted at developers who are interested in trying out new features |
| 12 | and testing the Django codebase to help identify and resolve bugs prior to the |
| 13 | final 1.4 release. |
| 14 | |
| 15 | As such, this release is *not* intended for production use, and any such use |
| 16 | is discouraged. |
| 17 | |
| 18 | Django 1.4 beta includes various `new features`_ and some minor `backwards |
| 19 | incompatible changes`_. There are also some features that have been dropped, |
| 20 | which are detailed in :doc:`our deprecation plan </internals/deprecation>`, |
| 21 | and we've `begun the deprecation process for some features`_. |
| 22 | |
| 23 | .. _new features: `What's new in Django 1.4`_ |
| 24 | .. _backwards incompatible changes: `Backwards incompatible changes in 1.4`_ |
| 25 | .. _begun the deprecation process for some features: `Features deprecated in 1.4`_ |
| 26 | |
| 27 | Python compatibility |
| 28 | ==================== |
| 29 | |
| 30 | While not a new feature, it's important to note that Django 1.4 introduces the |
| 31 | second shift in our Python compatibility policy since Django's initial public |
| 32 | debut. Django 1.2 dropped support for Python 2.3; now Django 1.4 drops support |
| 33 | for Python 2.4. As such, the minimum Python version required for Django is now |
| 34 | 2.5, and Django is tested and supported on Python 2.5, 2.6 and 2.7. |
| 35 | |
| 36 | This change should affect only a small number of Django users, as most |
| 37 | operating-system vendors today are shipping Python 2.5 or newer as their default |
| 38 | version. If you're still using Python 2.4, however, you'll need to stick to |
| 39 | Django 1.3 until you can upgrade; per :doc:`our support policy |
| 40 | </internals/release-process>`, Django 1.3 will continue to receive security |
| 41 | support until the release of Django 1.5. |
| 42 | |
| 43 | Django does not support Python 3.x at this time. A document outlining our full |
| 44 | timeline for deprecating Python 2.x and moving to Python 3.x will be published |
| 45 | before the release of Django 1.4. |
| 46 | |
| 47 | What's new in Django 1.4 |
| 48 | ======================== |
| 49 | |
| 50 | ``BooleanField`` set to None when default value not specified |
| 51 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 52 | |
| 53 | In previous versions of Django, a model's ``BooleanField`` would get ``False`` |
| 54 | value when no default was provided. Now ``None`` value is used. |
| 55 | |
| 56 | Support for in-browser testing frameworks |
| 57 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 58 | |
| 59 | Django 1.4 now supports integration with in-browser testing frameworks such |
| 60 | as Selenium_ or Windmill_ thanks to the :class:`django.test.LiveServerTestCase` |
| 61 | base class, allowing you to test the interactions between your site's front and |
| 62 | back ends more comprehensively. See the |
| 63 | :class:`documentation<django.test.LiveServerTestCase>` for more details and |
| 64 | concrete examples. |
| 65 | |
| 66 | .. _Windmill: http://www.getwindmill.com/ |
| 67 | .. _Selenium: http://seleniumhq.org/ |
| 68 | |
| 69 | ``SELECT FOR UPDATE`` support |
| 70 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 71 | |
| 72 | Django 1.4 now includes a :meth:`QuerySet.select_for_update() |
| 73 | <django.db.models.query.QuerySet.select_for_update>` method which generates a |
| 74 | ``SELECT ... FOR UPDATE`` SQL query. This will lock rows until the end of the |
| 75 | transaction, meaning that other transactions cannot modify or delete rows |
| 76 | matched by a ``FOR UPDATE`` query. |
| 77 | |
| 78 | For more details, see the documentation for |
| 79 | :meth:`~django.db.models.query.QuerySet.select_for_update`. |
| 80 | |
| 81 | ``Model.objects.bulk_create`` in the ORM |
| 82 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 83 | |
| 84 | This method allows for more efficient creation of multiple objects in the ORM. |
| 85 | It can provide significant performance increases if you have many objects. |
| 86 | Django makes use of this internally, meaning some operations (such as database |
| 87 | setup for test suites) have seen a performance benefit as a result. |
| 88 | |
| 89 | See the :meth:`~django.db.models.query.QuerySet.bulk_create` docs for more |
| 90 | information. |
| 91 | |
| 92 | ``QuerySet.prefetch_related`` |
| 93 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 94 | |
| 95 | Similar to :meth:`~django.db.models.query.QuerySet.select_related` but with a |
| 96 | different strategy and broader scope, |
| 97 | :meth:`~django.db.models.query.QuerySet.prefetch_related` has been added to |
| 98 | :class:`~django.db.models.query.QuerySet`. This method returns a new |
| 99 | ``QuerySet`` that will prefetch each of the specified related lookups in a |
| 100 | single batch as soon as the query begins to be evaluated. Unlike |
| 101 | ``select_related``, it does the joins in Python, not in the database, and |
| 102 | supports many-to-many relationships, |
| 103 | :class:`~django.contrib.contenttypes.generic.GenericForeignKey` and more. This |
| 104 | allows you to fix a very common performance problem in which your code ends up |
| 105 | doing O(n) database queries (or worse) if objects on your primary ``QuerySet`` |
| 106 | each have many related objects that you also need. |
| 107 | |
| 108 | Improved password hashing |
| 109 | ~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 110 | |
| 111 | Django's auth system (``django.contrib.auth``) stores passwords using a one-way |
| 112 | algorithm. Django 1.3 uses the SHA1_ algorithm, but increasing processor speeds |
| 113 | and theoretical attacks have revealed that SHA1 isn't as secure as we'd like. |
| 114 | Thus, Django 1.4 introduces a new password storage system: by default Django now |
| 115 | uses the PBKDF2_ algorithm (as recommended by NIST_). You can also easily choose |
| 116 | a different algorithm (including the popular bcrypt_ algorithm). For more |
| 117 | details, see :ref:`auth_password_storage`. |
| 118 | |
| 119 | .. _sha1: http://en.wikipedia.org/wiki/SHA1 |
| 120 | .. _pbkdf2: http://en.wikipedia.org/wiki/PBKDF2 |
| 121 | .. _nist: http://csrc.nist.gov/publications/nistpubs/800-132/nist-sp800-132.pdf |
| 122 | .. _bcrypt: http://en.wikipedia.org/wiki/Bcrypt |
| 123 | |
| 124 | |
| 125 | HTML5 Doctype |
| 126 | ~~~~~~~~~~~~~ |
| 127 | |
| 128 | We've switched the admin and other bundled templates to use the HTML5 |
| 129 | doctype. While Django will be careful to maintain compatibility with older |
| 130 | browsers, this change means that you can use any HTML5 features you need in |
| 131 | admin pages without having to lose HTML validity or override the provided |
| 132 | templates to change the doctype. |
| 133 | |
| 134 | List filters in admin interface |
| 135 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 136 | |
| 137 | Prior to Django 1.4, the :mod:`~django.contrib.admin` app allowed you to specify |
| 138 | change list filters by specifying a field lookup, but didn't allow you to create |
| 139 | custom filters. This has been rectified with a simple API (previously used |
| 140 | internally and known as "FilterSpec"). For more details, see the documentation |
| 141 | for :attr:`~django.contrib.admin.ModelAdmin.list_filter`. |
| 142 | |
| 143 | Multiple sort in admin interface |
| 144 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 145 | |
| 146 | The admin change list now supports sorting on multiple columns. It respects all |
| 147 | elements of the :attr:`~django.contrib.admin.ModelAdmin.ordering` attribute, and |
| 148 | sorting on multiple columns by clicking on headers is designed to mimic the |
| 149 | behavior of desktop GUIs. The |
| 150 | :meth:`~django.contrib.admin.ModelAdmin.get_ordering` method for specifying the |
| 151 | ordering dynamically (e.g. depending on the request) has also been added. |
| 152 | |
| 153 | New ``ModelAdmin`` methods |
| 154 | ~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 155 | |
| 156 | A new :meth:`~django.contrib.admin.ModelAdmin.save_related` method was added to |
| 157 | :mod:`~django.contrib.admin.ModelAdmin` to ease customization of how |
| 158 | related objects are saved in the admin. |
| 159 | |
| 160 | Two other new methods, |
| 161 | :meth:`~django.contrib.admin.ModelAdmin.get_list_display` and |
| 162 | :meth:`~django.contrib.admin.ModelAdmin.get_list_display_links` |
| 163 | were added to :class:`~django.contrib.admin.ModelAdmin` to enable the dynamic |
| 164 | customization of fields and links displayed on the admin change list. |
| 165 | |
| 166 | Admin inlines respect user permissions |
| 167 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 168 | |
| 169 | Admin inlines will now only allow those actions for which the user has |
| 170 | permission. For ``ManyToMany`` relationships with an auto-created intermediate |
| 171 | model (which does not have its own permissions), the change permission for the |
| 172 | related model determines if the user has the permission to add, change or |
| 173 | delete relationships. |
| 174 | |
| 175 | Tools for cryptographic signing |
| 176 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 177 | |
| 178 | Django 1.4 adds both a low-level API for signing values and a high-level API |
| 179 | for setting and reading signed cookies, one of the most common uses of |
| 180 | signing in Web applications. |
| 181 | |
| 182 | See the :doc:`cryptographic signing </topics/signing>` docs for more |
| 183 | information. |
| 184 | |
| 185 | Cookie-based session backend |
| 186 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 187 | |
| 188 | Django 1.4 introduces a new cookie-based backend for the session framework |
| 189 | which uses the tools for :doc:`cryptographic signing </topics/signing>` to |
| 190 | store the session data in the client's browser. |
| 191 | |
| 192 | See the :ref:`cookie-based session backend <cookie-session-backend>` docs for |
| 193 | more information. |
| 194 | |
| 195 | New form wizard |
| 196 | ~~~~~~~~~~~~~~~ |
| 197 | |
| 198 | The previous ``FormWizard`` from the formtools contrib app has been |
| 199 | replaced with a new implementation based on the class-based views |
| 200 | introduced in Django 1.3. It features a pluggable storage API and doesn't |
| 201 | require the wizard to pass around hidden fields for every previous step. |
| 202 | |
| 203 | Django 1.4 ships with a session-based storage backend and a cookie-based |
| 204 | storage backend. The latter uses the tools for |
| 205 | :doc:`cryptographic signing </topics/signing>` also introduced in |
| 206 | Django 1.4 to store the wizard's state in the user's cookies. |
| 207 | |
| 208 | See the :doc:`form wizard </ref/contrib/formtools/form-wizard>` docs for |
| 209 | more information. |
| 210 | |
| 211 | ``reverse_lazy`` |
| 212 | ~~~~~~~~~~~~~~~~ |
| 213 | |
| 214 | A lazily evaluated version of :func:`django.core.urlresolvers.reverse` was |
| 215 | added to allow using URL reversals before the project's URLConf gets loaded. |
| 216 | |
| 217 | Translating URL patterns |
| 218 | ~~~~~~~~~~~~~~~~~~~~~~~~ |
| 219 | |
| 220 | Django 1.4 gained the ability to look for a language prefix in the URL pattern |
| 221 | when using the new :func:`~django.conf.urls.i18n.i18n_patterns` helper function. |
| 222 | Additionally, it's now possible to define translatable URL patterns using |
| 223 | :func:`~django.utils.translation.ugettext_lazy`. See |
| 224 | :ref:`url-internationalization` for more information about the language prefix |
| 225 | and how to internationalize URL patterns. |
| 226 | |
| 227 | Contextual translation support for ``{% trans %}`` and ``{% blocktrans %}`` |
| 228 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 229 | |
| 230 | The :ref:`contextual translation<contextual-markers>` support introduced in |
| 231 | Django 1.3 via the ``pgettext`` function has been extended to the |
| 232 | :ttag:`trans` and :ttag:`blocktrans` template tags using the new ``context`` |
| 233 | keyword. |
| 234 | |
| 235 | Customizable ``SingleObjectMixin`` URLConf kwargs |
| 236 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 237 | |
| 238 | Two new attributes, |
| 239 | :attr:`pk_url_kwarg<django.views.generic.detail.SingleObjectMixin.pk_url_kwarg>` |
| 240 | and |
| 241 | :attr:`slug_url_kwarg<django.views.generic.detail.SingleObjectMixin.slug_url_kwarg>`, |
| 242 | have been added to :class:`~django.views.generic.detail.SingleObjectMixin` to |
| 243 | enable the customization of URLConf keyword arguments used for single |
| 244 | object generic views. |
| 245 | |
| 246 | Assignment template tags |
| 247 | ~~~~~~~~~~~~~~~~~~~~~~~~ |
| 248 | |
| 249 | A new :ref:`assignment_tag<howto-custom-template-tags-assignment-tags>` helper |
| 250 | function was added to ``template.Library`` to ease the creation of template |
| 251 | tags that store data in a specified context variable. |
| 252 | |
| 253 | ``*args`` and ``**kwargs`` support for template tag helper functions |
| 254 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 255 | |
| 256 | The :ref:`simple_tag<howto-custom-template-tags-simple-tags>`, |
| 257 | :ref:`inclusion_tag <howto-custom-template-tags-inclusion-tags>` and |
| 258 | newly introduced |
| 259 | :ref:`assignment_tag<howto-custom-template-tags-assignment-tags>` template |
| 260 | helper functions may now accept any number of positional or keyword arguments. |
| 261 | For example: |
| 262 | |
| 263 | .. code-block:: python |
| 264 | |
| 265 | @register.simple_tag |
| 266 | def my_tag(a, b, *args, **kwargs): |
| 267 | warning = kwargs['warning'] |
| 268 | profile = kwargs['profile'] |
| 269 | ... |
| 270 | return ... |
| 271 | |
| 272 | Then in the template any number of arguments may be passed to the template tag. |
| 273 | For example: |
| 274 | |
| 275 | .. code-block:: html+django |
| 276 | |
| 277 | {% my_tag 123 "abcd" book.title warning=message|lower profile=user.profile %} |
| 278 | |
| 279 | No wrapping of exceptions in ``TEMPLATE_DEBUG`` mode |
| 280 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 281 | |
| 282 | In previous versions of Django, whenever the :setting:`TEMPLATE_DEBUG` setting |
| 283 | was ``True``, any exception raised during template rendering (even exceptions |
| 284 | unrelated to template syntax) were wrapped in ``TemplateSyntaxError`` and |
| 285 | re-raised. This was done in order to provide detailed template source location |
| 286 | information in the debug 500 page. |
| 287 | |
| 288 | In Django 1.4, exceptions are no longer wrapped. Instead, the original |
| 289 | exception is annotated with the source information. This means that catching |
| 290 | exceptions from template rendering is now consistent regardless of the value of |
| 291 | :setting:`TEMPLATE_DEBUG`, and there's no need to catch and unwrap |
| 292 | ``TemplateSyntaxError`` in order to catch other errors. |
| 293 | |
| 294 | ``truncatechars`` template filter |
| 295 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 296 | |
| 297 | Added a filter which truncates a string to be no longer than the specified |
| 298 | number of characters. Truncated strings end with a translatable ellipsis |
| 299 | sequence ("..."). See the documentation for :tfilter:`truncatechars` for |
| 300 | more details. |
| 301 | |
| 302 | ``static`` template tag |
| 303 | ~~~~~~~~~~~~~~~~~~~~~~~ |
| 304 | |
| 305 | The :mod:`staticfiles<django.contrib.staticfiles>` contrib app has a new |
| 306 | :ttag:`static<staticfiles-static>` template tag to refer to files saved with |
| 307 | the :setting:`STATICFILES_STORAGE` storage backend. It uses the storage |
| 308 | backend's ``url`` method and therefore supports advanced features such as |
| 309 | :ref:`serving files from a cloud service<staticfiles-from-cdn>`. |
| 310 | |
| 311 | ``CachedStaticFilesStorage`` storage backend |
| 312 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 313 | |
| 314 | In addition to the `static template tag`_, the |
| 315 | :mod:`staticfiles<django.contrib.staticfiles>` contrib app now has a |
| 316 | :class:`~django.contrib.staticfiles.storage.CachedStaticFilesStorage` backend |
| 317 | which caches the files it saves (when running the :djadmin:`collectstatic` |
| 318 | management command) by appending the MD5 hash of the file's content to the |
| 319 | filename. For example, the file ``css/styles.css`` would also be saved as |
| 320 | ``css/styles.55e7cbb9ba48.css`` |
| 321 | |
| 322 | See the :class:`~django.contrib.staticfiles.storage.CachedStaticFilesStorage` |
| 323 | docs for more information. |
| 324 | |
| 325 | Simple clickjacking protection |
| 326 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 327 | |
| 328 | We've added a middleware to provide easy protection against `clickjacking |
| 329 | <http://en.wikipedia.org/wiki/Clickjacking>`_ using the ``X-Frame-Options`` |
| 330 | header. It's not enabled by default for backwards compatibility reasons, but |
| 331 | you'll almost certainly want to :doc:`enable it </ref/clickjacking/>` to help |
| 332 | plug that security hole for browsers that support the header. |
| 333 | |
| 334 | CSRF improvements |
| 335 | ~~~~~~~~~~~~~~~~~ |
| 336 | |
| 337 | We've made various improvements to our CSRF features, including the |
| 338 | :func:`~django.views.decorators.csrf.ensure_csrf_cookie` decorator which can |
| 339 | help with AJAX heavy sites, protection for PUT and DELETE requests, and the |
| 340 | :setting:`CSRF_COOKIE_SECURE` and :setting:`CSRF_COOKIE_PATH` settings which can |
| 341 | improve the security and usefulness of the CSRF protection. See the :doc:`CSRF |
| 342 | docs </ref/contrib/csrf>` for more information. |
| 343 | |
| 344 | Error report filtering |
| 345 | ~~~~~~~~~~~~~~~~~~~~~~ |
| 346 | |
| 347 | Two new function decorators, :func:`sensitive_variables` and |
| 348 | :func:`sensitive_post_parameters`, were added to allow designating the |
| 349 | local variables and POST parameters which may contain sensitive |
| 350 | information and should be filtered out of error reports. |
| 351 | |
| 352 | All POST parameters are now systematically filtered out of error reports for |
| 353 | certain views (``login``, ``password_reset_confirm``, ``password_change``, and |
| 354 | ``add_view`` in :mod:`django.contrib.auth.views`, as well as |
| 355 | ``user_change_password`` in the admin app) to prevent the leaking of sensitive |
| 356 | information such as user passwords. |
| 357 | |
| 358 | You may override or customize the default filtering by writing a :ref:`custom |
| 359 | filter<custom-error-reports>`. For more information see the docs on |
| 360 | :ref:`Filtering error reports<filtering-error-reports>`. |
| 361 | |
| 362 | Extended IPv6 support |
| 363 | ~~~~~~~~~~~~~~~~~~~~~ |
| 364 | |
| 365 | The previously added support for IPv6 addresses when using the runserver |
| 366 | management command in Django 1.3 has now been further extended by adding |
| 367 | a :class:`~django.db.models.fields.GenericIPAddressField` model field, |
| 368 | a :class:`~django.forms.fields.GenericIPAddressField` form field and |
| 369 | the validators :data:`~django.core.validators.validate_ipv46_address` and |
| 370 | :data:`~django.core.validators.validate_ipv6_address` |
| 371 | |
| 372 | Updated default project layout and ``manage.py`` |
| 373 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 374 | |
| 375 | Django 1.4 ships with an updated default project layout and ``manage.py`` file |
| 376 | for the :djadmin:`startproject` management command. These fix some issues with |
| 377 | the previous ``manage.py`` handling of Python import paths that caused double |
| 378 | imports, trouble moving from development to deployment, and other |
| 379 | difficult-to-debug path issues. |
| 380 | |
| 381 | The previous ``manage.py`` called functions that are now deprecated, and thus |
| 382 | projects upgrading to Django 1.4 should update their ``manage.py``. (The |
| 383 | old-style ``manage.py`` will continue to work as before until Django 1.6; in |
| 384 | 1.5 it will raise ``DeprecationWarning``). |
| 385 | |
| 386 | The new recommended ``manage.py`` file should look like this:: |
| 387 | |
| 388 | #!/usr/bin/env python |
| 389 | import os, sys |
| 390 | |
| 391 | if __name__ == "__main__": |
| 392 | os.environ.setdefault("DJANGO_SETTINGS_MODULE", "{{ project_name }}.settings") |
| 393 | |
| 394 | from django.core.management import execute_from_command_line |
| 395 | |
| 396 | execute_from_command_line(sys.argv) |
| 397 | |
| 398 | ``{{ project_name }}`` should be replaced with the Python package name of the |
| 399 | actual project. |
| 400 | |
| 401 | If settings, URLconfs, and apps within the project are imported or referenced |
| 402 | using the project name prefix (e.g. ``myproject.settings``, ``ROOT_URLCONF = |
| 403 | "myproject.urls"``, etc), the new ``manage.py`` will need to be moved one |
| 404 | directory up, so it is outside the project package rather than adjacent to |
| 405 | ``settings.py`` and ``urls.py``. |
| 406 | |
| 407 | For instance, with the following layout:: |
| 408 | |
| 409 | manage.py |
| 410 | mysite/ |
| 411 | __init__.py |
| 412 | settings.py |
| 413 | urls.py |
| 414 | myapp/ |
| 415 | __init__.py |
| 416 | models.py |
| 417 | |
| 418 | You could import ``mysite.settings``, ``mysite.urls``, and ``mysite.myapp``, |
| 419 | but not ``settings``, ``urls``, or ``myapp`` as top-level modules. |
| 420 | |
| 421 | Anything imported as a top-level module can be placed adjacent to the new |
| 422 | ``manage.py``. For instance, to decouple "myapp" from the project module and |
| 423 | import it as just ``myapp``, place it outside the ``mysite/`` directory:: |
| 424 | |
| 425 | manage.py |
| 426 | myapp/ |
| 427 | __init__.py |
| 428 | models.py |
| 429 | mysite/ |
| 430 | __init__.py |
| 431 | settings.py |
| 432 | urls.py |
| 433 | |
| 434 | If the same code is imported inconsistently (some places with the project |
| 435 | prefix, some places without it), the imports will need to be cleaned up when |
| 436 | switching to the new ``manage.py``. |
| 437 | |
| 438 | Improved WSGI support |
| 439 | ~~~~~~~~~~~~~~~~~~~~~ |
| 440 | |
| 441 | The :djadmin:`startproject` management command now adds a :file:`wsgi.py` |
| 442 | module to the initial project layout, containing a simple WSGI application that |
| 443 | can be used for :doc:`deploying with WSGI app |
| 444 | servers</howto/deployment/wsgi/index>`. |
| 445 | |
| 446 | The :djadmin:`built-in development server<runserver>` now supports using an |
| 447 | externally-defined WSGI callable, so as to make it possible to run runserver |
| 448 | with the same WSGI configuration that is used for deployment. A new |
| 449 | :setting:`WSGI_APPLICATION` setting is available to configure which WSGI |
| 450 | callable :djadmin:`runserver` uses. |
| 451 | |
| 452 | (The :djadmin:`runfcgi` management command also internally wraps the WSGI |
| 453 | callable configured via :setting:`WSGI_APPLICATION`.) |
| 454 | |
| 455 | Custom project and app templates |
| 456 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 457 | |
| 458 | The :djadmin:`startapp` and :djadmin:`startproject` management commands |
| 459 | got a ``--template`` option for specifying a path or URL to a custom app or |
| 460 | project template. |
| 461 | |
| 462 | For example, Django will use the ``/path/to/my_project_template`` directory |
| 463 | when running the following command:: |
| 464 | |
| 465 | django-admin.py startproject --template=/path/to/my_project_template myproject |
| 466 | |
| 467 | You can also now provide a destination directory as the second |
| 468 | argument to both :djadmin:`startapp` and :djadmin:`startproject`:: |
| 469 | |
| 470 | django-admin.py startapp myapp /path/to/new/app |
| 471 | django-admin.py startproject myproject /path/to/new/project |
| 472 | |
| 473 | For more information, see the :djadmin:`startapp` and :djadmin:`startproject` |
| 474 | documentation. |
| 475 | |
| 476 | Support for time zones |
| 477 | ~~~~~~~~~~~~~~~~~~~~~~ |
| 478 | |
| 479 | Django 1.4 adds :ref:`support for time zones <time-zones>`. When it's enabled, |
| 480 | Django stores date and time information in UTC in the database, uses time |
| 481 | zone-aware datetime objects internally, and translates them to the end user's |
| 482 | time zone in templates and forms. |
| 483 | |
| 484 | Reasons for using this feature include: |
| 485 | |
| 486 | - Customizing date and time display for users around the world. |
| 487 | - Storing datetimes in UTC for database portability and interoperability. |
| 488 | (This argument doesn't apply to PostgreSQL, because it already stores |
| 489 | timestamps with time zone information in Django 1.3.) |
| 490 | - Avoiding data corruption problems around DST transitions. |
| 491 | |
| 492 | Time zone support is enabled by default in new projects created with |
| 493 | :djadmin:`startproject`. If you want to use this feature in an existing |
| 494 | project, there is a :ref:`migration guide <time-zones-migration-guide>`. |
| 495 | |
| 496 | Minor features |
| 497 | ~~~~~~~~~~~~~~ |
| 498 | |
| 499 | Django 1.4 also includes several smaller improvements worth noting: |
| 500 | |
| 501 | * A more usable stacktrace in the technical 500 page: frames in the |
| 502 | stack trace which reference Django's code are dimmed out, while |
| 503 | frames in user code are slightly emphasized. This change makes it |
| 504 | easier to scan a stacktrace for issues in user code. |
| 505 | |
| 506 | * :doc:`Tablespace support </topics/db/tablespaces>` in PostgreSQL. |
| 507 | |
| 508 | * Customizable names for :meth:`~django.template.Library.simple_tag`. |
| 509 | |
| 510 | * In the documentation, a helpful :doc:`security overview </topics/security>` |
| 511 | page. |
| 512 | |
| 513 | * The :func:`django.contrib.auth.models.check_password` function has been moved |
| 514 | to the :mod:`django.contrib.auth.utils` module. Importing it from the old |
| 515 | location will still work, but you should update your imports. |
| 516 | |
| 517 | * The :djadmin:`collectstatic` management command gained a ``--clear`` option |
| 518 | to delete all files at the destination before copying or linking the static |
| 519 | files. |
| 520 | |
| 521 | * It is now possible to load fixtures containing forward references when using |
| 522 | MySQL with the InnoDB database engine. |
| 523 | |
| 524 | * A new 403 response handler has been added as |
| 525 | ``'django.views.defaults.permission_denied'``. You can set your own handler by |
| 526 | setting the value of :data:`django.conf.urls.handler403`. See the |
| 527 | documentation about :ref:`the 403 (HTTP Forbidden) view<http_forbidden_view>` |
| 528 | for more information. |
| 529 | |
| 530 | * The :ttag:`trans` template tag now takes an optional ``as`` argument to |
| 531 | be able to retrieve a translation string without displaying it but setting |
| 532 | a template context variable instead. |
| 533 | |
| 534 | * The :ttag:`if` template tag now supports ``{% elif %}`` clauses. |
| 535 | |
| 536 | * A new plain text version of the HTTP 500 status code internal error page |
| 537 | served when :setting:`DEBUG` is ``True`` is now sent to the client when |
| 538 | Django detects that the request has originated in JavaScript code |
| 539 | (:meth:`~django.http.HttpRequest.is_ajax` is used for this). |
| 540 | |
| 541 | Similarly to its HTML counterpart, it contains a collection of different |
| 542 | pieces of information about the state of the web application. |
| 543 | |
| 544 | This should make it easier to read when debugging interaction with |
| 545 | client-side Javascript code. |
| 546 | |
| 547 | * Added the :djadminopt:`--no-location` option to the :djadmin:`makemessages` |
| 548 | command. |
| 549 | |
| 550 | * Changed the ``locmem`` cache backend to use |
| 551 | ``pickle.HIGHEST_PROTOCOL`` for better compatibility with the other |
| 552 | cache backends. |
| 553 | |
| 554 | * Added support in the ORM for generating ``SELECT`` queries containing |
| 555 | ``DISTINCT ON``. |
| 556 | |
| 557 | The ``distinct()`` ``QuerySet`` method now accepts an optional list of model |
| 558 | field names. If specified, then the ``DISTINCT`` statement is limited to these |
| 559 | fields. This is only supported in PostgreSQL. |
| 560 | |
| 561 | For more details, see the documentation for |
| 562 | :meth:`~django.db.models.query.QuerySet.distinct`. |
| 563 | |
| 564 | Backwards incompatible changes in 1.4 |
| 565 | ===================================== |
| 566 | |
| 567 | django.contrib.admin |
| 568 | ~~~~~~~~~~~~~~~~~~~~ |
| 569 | |
| 570 | The included administration app ``django.contrib.admin`` has for a long time |
| 571 | shipped with a default set of static files such as JavaScript, images and |
| 572 | stylesheets. Django 1.3 added a new contrib app ``django.contrib.staticfiles`` |
| 573 | to handle such files in a generic way and defined conventions for static |
| 574 | files included in apps. |
| 575 | |
| 576 | Starting in Django 1.4 the admin's static files also follow this |
| 577 | convention to make it easier to deploy the included files. In previous |
| 578 | versions of Django, it was also common to define an ``ADMIN_MEDIA_PREFIX`` |
| 579 | setting to point to the URL where the admin's static files are served by a |
| 580 | web server. This setting has now been deprecated and replaced by the more |
| 581 | general setting :setting:`STATIC_URL`. Django will now expect to find the |
| 582 | admin static files under the URL ``<STATIC_URL>/admin/``. |
| 583 | |
| 584 | If you've previously used a URL path for ``ADMIN_MEDIA_PREFIX`` (e.g. |
| 585 | ``/media/``) simply make sure :setting:`STATIC_URL` and :setting:`STATIC_ROOT` |
| 586 | are configured and your web server serves the files correctly. The development |
| 587 | server continues to serve the admin files just like before. Don't hesitate to |
| 588 | consult the :doc:`static files howto </howto/static-files>` for further |
| 589 | details. |
| 590 | |
| 591 | In case your ``ADMIN_MEDIA_PREFIX`` is set to an specific domain (e.g. |
| 592 | ``http://media.example.com/admin/``) make sure to also set your |
| 593 | :setting:`STATIC_URL` setting to the correct URL, for example |
| 594 | ``http://media.example.com/``. |
| 595 | |
| 596 | .. warning:: |
| 597 | |
| 598 | If you're implicitely relying on the path of the admin static files on |
| 599 | your server's file system when you deploy your site, you have to update |
| 600 | that path. The files were moved from :file:`django/contrib/admin/media/` |
| 601 | to :file:`django/contrib/admin/static/admin/`. |
| 602 | |
| 603 | Supported browsers for the admin |
| 604 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 605 | |
| 606 | Django hasn't had a clear policy on which browsers are supported for using the |
| 607 | admin app. Django's new policy formalizes existing practices: `YUI's A-grade`_ |
| 608 | browsers should provide a fully-functional admin experience, with the notable |
| 609 | exception of IE6, which is no longer supported. |
| 610 | |
| 611 | Released over ten years ago, IE6 imposes many limitations on modern web |
| 612 | development. The practical implications of this policy are that contributors |
| 613 | are free to improve the admin without consideration for these limitations. |
| 614 | |
| 615 | This new policy **has no impact** on development outside of the admin. Users of |
| 616 | Django are free to develop webapps compatible with any range of browsers. |
| 617 | |
| 618 | .. _YUI's A-grade: http://yuilibrary.com/yui/docs/tutorials/gbs/ |
| 619 | |
| 620 | Removed admin icons |
| 621 | ~~~~~~~~~~~~~~~~~~~ |
| 622 | |
| 623 | As part of an effort to improve the performance and usability of the admin's |
| 624 | changelist sorting interface and of the admin's :attr:`horizontal |
| 625 | <django.contrib.admin.ModelAdmin.filter_horizontal>` and :attr:`vertical |
| 626 | <django.contrib.admin.ModelAdmin.filter_vertical>` "filter" widgets, some icon |
| 627 | files were removed and grouped into two sprite files. |
| 628 | |
| 629 | Specifically: ``selector-add.gif``, ``selector-addall.gif``, |
| 630 | ``selector-remove.gif``, ``selector-removeall.gif``, |
| 631 | ``selector_stacked-add.gif`` and ``selector_stacked-remove.gif`` were |
| 632 | combined into ``selector-icons.gif``; and ``arrow-up.gif`` and |
| 633 | ``arrow-down.gif`` were combined into ``sorting-icons.gif``. |
| 634 | |
| 635 | If you used those icons to customize the admin then you will want to replace |
| 636 | them with your own icons or retrieve them from a previous release. |
| 637 | |
| 638 | CSS class names in admin forms |
| 639 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 640 | |
| 641 | To avoid conflicts with other common CSS class names (e.g. "button"), a prefix |
| 642 | "field-" has been added to all CSS class names automatically generated from the |
| 643 | form field names in the main admin forms, stacked inline forms and tabular |
| 644 | inline cells. You will need to take that prefix into account in your custom |
| 645 | style sheets or javascript files if you previously used plain field names as |
| 646 | selectors for custom styles or javascript transformations. |
| 647 | |
| 648 | Compatibility with old signed data |
| 649 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 650 | |
| 651 | Django 1.3 changed the cryptographic signing mechanisms used in a number of |
| 652 | places in Django. While Django 1.3 kept fallbacks that would accept hashes |
| 653 | produced by the previous methods, these fallbacks are removed in Django 1.4. |
| 654 | |
| 655 | So, if you upgrade to Django 1.4 directly from 1.2 or earlier, you may |
| 656 | lose/invalidate certain pieces of data that have been cryptographically signed |
| 657 | using an old method. To avoid this, use Django 1.3 first for a period of time |
| 658 | to allow the signed data to expire naturally. The affected parts are detailed |
| 659 | below, with 1) the consequences of ignoring this advice and 2) the amount of |
| 660 | time you need to run Django 1.3 for the data to expire or become irrelevant. |
| 661 | |
| 662 | * ``contrib.sessions`` data integrity check |
| 663 | |
| 664 | * consequences: the user will be logged out, and session data will be lost. |
| 665 | |
| 666 | * time period: defined by :setting:`SESSION_COOKIE_AGE`. |
| 667 | |
| 668 | * ``contrib.auth`` password reset hash |
| 669 | |
| 670 | * consequences: password reset links from before the upgrade will not work. |
| 671 | |
| 672 | * time period: defined by :setting:`PASSWORD_RESET_TIMEOUT_DAYS`. |
| 673 | |
| 674 | Form-related hashes — these are much shorter lifetime, and are relevant only for |
| 675 | the short window where a user might fill in a form generated by the pre-upgrade |
| 676 | Django instance, and try to submit it to the upgraded Django instance: |
| 677 | |
| 678 | * ``contrib.comments`` form security hash |
| 679 | |
| 680 | * consequences: the user will see a validation error "Security hash failed". |
| 681 | |
| 682 | * time period: the amount of time you expect users to take filling out comment |
| 683 | forms. |
| 684 | |
| 685 | * ``FormWizard`` security hash |
| 686 | |
| 687 | * consequences: the user will see an error about the form having expired, |
| 688 | and will be sent back to the first page of the wizard, losing the data |
| 689 | they have entered so far. |
| 690 | |
| 691 | * time period: the amount of time you expect users to take filling out the |
| 692 | affected forms. |
| 693 | |
| 694 | * CSRF check |
| 695 | |
| 696 | * Note: This is actually a Django 1.1 fallback, not Django 1.2, |
| 697 | and applies only if you are upgrading from 1.1. |
| 698 | |
| 699 | * consequences: the user will see a 403 error with any CSRF protected POST |
| 700 | form. |
| 701 | |
| 702 | * time period: the amount of time you expect user to take filling out |
| 703 | such forms. |
| 704 | |
| 705 | django.contrib.flatpages |
| 706 | ~~~~~~~~~~~~~~~~~~~~~~~~ |
| 707 | |
| 708 | Starting in the 1.4 release the |
| 709 | :class:`~django.contrib.flatpages.middleware.FlatpageFallbackMiddleware` only |
| 710 | adds a trailing slash and redirects if the resulting URL refers to an existing |
| 711 | flatpage. For example, requesting ``/notaflatpageoravalidurl`` in a previous |
| 712 | version would redirect to ``/notaflatpageoravalidurl/``, which would |
| 713 | subsequently raise a 404. Requesting ``/notaflatpageoravalidurl`` now will |
| 714 | immediately raise a 404. Additionally redirects returned by flatpages are now |
| 715 | permanent (301 status code) to match the behavior of the |
| 716 | :class:`~django.middleware.common.CommonMiddleware`. |
| 717 | |
| 718 | Serialization of :class:`~datetime.datetime` and :class:`~datetime.time` |
| 719 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 720 | |
| 721 | As a consequence of time zone support, and according to the ECMA-262 |
| 722 | specification, some changes were made to the JSON serializer: |
| 723 | |
| 724 | - It includes the time zone for aware datetime objects. It raises an exception |
| 725 | for aware time objects. |
| 726 | - It includes milliseconds for datetime and time objects. There is still |
| 727 | some precision loss, because Python stores microseconds (6 digits) and JSON |
| 728 | only supports milliseconds (3 digits). However, it's better than discarding |
| 729 | microseconds entirely. |
| 730 | |
| 731 | The XML serializer was also changed to use the ISO8601 format for datetimes. |
| 732 | The letter ``T`` is used to separate the date part from the time part, instead |
| 733 | of a space. Time zone information is included in the ``[+-]HH:MM`` format. |
| 734 | |
| 735 | The serializers will dump datetimes in fixtures with these new formats. They |
| 736 | can still load fixtures that use the old format. |
| 737 | |
| 738 | ``supports_timezone`` changed to ``False`` for SQLite |
| 739 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 740 | |
| 741 | The database feature ``supports_timezone`` used to be ``True`` for SQLite. |
| 742 | Indeed, if you saved an aware datetime object, SQLite stored a string that |
| 743 | included an UTC offset. However, this offset was ignored when loading the value |
| 744 | back from the database, which could corrupt the data. |
| 745 | |
| 746 | In the context of time zone support, this flag was changed to ``False``, and |
| 747 | datetimes are now stored without time zone information in SQLite. When |
| 748 | :setting:`USE_TZ` is ``False``, if you attempt to save an aware datetime |
| 749 | object, Django raises an exception. |
| 750 | |
| 751 | Database connection's thread-locality |
| 752 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 753 | |
| 754 | ``DatabaseWrapper`` objects (i.e. the connection objects referenced by |
| 755 | ``django.db.connection`` and ``django.db.connections["some_alias"]``) used to |
| 756 | be thread-local. They are now global objects in order to be potentially shared |
| 757 | between multiple threads. While the individual connection objects are now |
| 758 | global, the ``django.db.connections`` dictionary referencing those objects is |
| 759 | still thread-local. Therefore if you just use the ORM or |
| 760 | ``DatabaseWrapper.cursor()`` then the behavior is still the same as before. |
| 761 | Note, however, that ``django.db.connection`` does not directly reference the |
| 762 | default ``DatabaseWrapper`` object anymore and is now a proxy to access that |
| 763 | object's attributes. If you need to access the actual ``DatabaseWrapper`` |
| 764 | object, use ``django.db.connections[DEFAULT_DB_ALIAS]`` instead. |
| 765 | |
| 766 | As part of this change, all underlying SQLite connections are now enabled for |
| 767 | potential thread-sharing (by passing the ``check_same_thread=False`` attribute |
| 768 | to pysqlite). ``DatabaseWrapper`` however preserves the previous behavior by |
| 769 | disabling thread-sharing by default, so this does not affect any existing |
| 770 | code that purely relies on the ORM or on ``DatabaseWrapper.cursor()``. |
| 771 | |
| 772 | Finally, while it is now possible to pass connections between threads, Django |
| 773 | does not make any effort to synchronize access to the underlying backend. |
| 774 | Concurrency behavior is defined by the underlying backend implementation. |
| 775 | Check their documentation for details. |
| 776 | |
| 777 | `COMMENTS_BANNED_USERS_GROUP` setting |
| 778 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 779 | |
| 780 | Django's :doc:`comments app </ref/contrib/comments/index>` has historically |
| 781 | supported excluding the comments of a special user group, but we've never |
| 782 | documented the feature properly and didn't enforce the exclusion in other parts |
| 783 | of the app such as the template tags. To fix this problem, we removed the code |
| 784 | from the feed class. |
| 785 | |
| 786 | If you rely on the feature and want to restore the old behavior, simply use |
| 787 | a custom comment model manager to exclude the user group, like this:: |
| 788 | |
| 789 | from django.conf import settings |
| 790 | from django.contrib.comments.managers import CommentManager |
| 791 | |
| 792 | class BanningCommentManager(CommentManager): |
| 793 | def get_query_set(self): |
| 794 | qs = super(BanningCommentManager, self).get_query_set() |
| 795 | if getattr(settings, 'COMMENTS_BANNED_USERS_GROUP', None): |
| 796 | where = ['user_id NOT IN (SELECT user_id FROM auth_user_groups WHERE group_id = %s)'] |
| 797 | params = [settings.COMMENTS_BANNED_USERS_GROUP] |
| 798 | qs = qs.extra(where=where, params=params) |
| 799 | return qs |
| 800 | |
| 801 | Save this model manager in your custom comment app (e.g. in |
| 802 | ``my_comments_app/managers.py``) and add it your |
| 803 | :ref:`custom comment app model <custom-comment-app-api>`:: |
| 804 | |
| 805 | from django.db import models |
| 806 | from django.contrib.comments.models import Comment |
| 807 | |
| 808 | from my_comments_app.managers import BanningCommentManager |
| 809 | |
| 810 | class CommentWithTitle(Comment): |
| 811 | title = models.CharField(max_length=300) |
| 812 | |
| 813 | objects = BanningCommentManager() |
| 814 | |
| 815 | For more details, see the documentation about |
| 816 | :doc:`customizing the comments framework </ref/contrib/comments/custom>`. |
| 817 | |
| 818 | `IGNORABLE_404_STARTS` and `IGNORABLE_404_ENDS` settings |
| 819 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 820 | |
| 821 | Until Django 1.3, it was possible to exclude some URLs from Django's |
| 822 | :doc:`404 error reporting</howto/error-reporting>` by adding prefixes to |
| 823 | :setting:`IGNORABLE_404_STARTS` and suffixes to :setting:`IGNORABLE_404_ENDS`. |
| 824 | |
| 825 | In Django 1.4, these two settings are superseded by |
| 826 | :setting:`IGNORABLE_404_URLS`, which is a list of compiled regular expressions. |
| 827 | Django won't send an email for 404 errors on URLs that match any of them. |
| 828 | |
| 829 | Furthermore, the previous settings had some rather arbitrary default values:: |
| 830 | |
| 831 | IGNORABLE_404_STARTS = ('/cgi-bin/', '/_vti_bin', '/_vti_inf') |
| 832 | IGNORABLE_404_ENDS = ('mail.pl', 'mailform.pl', 'mail.cgi', 'mailform.cgi', |
| 833 | 'favicon.ico', '.php') |
| 834 | |
| 835 | It's not Django's role to decide if your website has a legacy ``/cgi-bin/`` |
| 836 | section or a ``favicon.ico``. As a consequence, the default values of |
| 837 | :setting:`IGNORABLE_404_URLS`, :setting:`IGNORABLE_404_STARTS` and |
| 838 | :setting:`IGNORABLE_404_ENDS` are all now empty. |
| 839 | |
| 840 | If you have customized :setting:`IGNORABLE_404_STARTS` or |
| 841 | :setting:`IGNORABLE_404_ENDS`, or if you want to keep the old default value, |
| 842 | you should add the following lines in your settings file:: |
| 843 | |
| 844 | import re |
| 845 | IGNORABLE_404_URLS = ( |
| 846 | # for each <prefix> in IGNORABLE_404_STARTS |
| 847 | re.compile(r'^<prefix>'), |
| 848 | # for each <suffix> in IGNORABLE_404_ENDS |
| 849 | re.compile(r'<suffix>$'), |
| 850 | ) |
| 851 | |
| 852 | Don't forget to escape characters that have a special meaning in a regular |
| 853 | expression. |
| 854 | |
| 855 | CSRF protection extended to PUT and DELETE |
| 856 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 857 | |
| 858 | Previously, Django's :doc:`CSRF protection </ref/contrib/csrf/>` provided |
| 859 | protection against only POST requests. Since use of PUT and DELETE methods in |
| 860 | AJAX applications is becoming more common, we now protect all methods not |
| 861 | defined as safe by :rfc:`2616` i.e. we exempt GET, HEAD, OPTIONS and TRACE, and |
| 862 | enforce protection on everything else. |
| 863 | |
| 864 | If you are using PUT or DELETE methods in AJAX applications, please see the |
| 865 | :ref:`instructions about using AJAX and CSRF <csrf-ajax>`. |
| 866 | |
| 867 | ``django.core.template_loaders`` |
| 868 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 869 | |
| 870 | This was an alias to ``django.template.loader`` since 2005, it has been removed |
| 871 | without emitting a warning due to the length of the deprecation. If your code |
| 872 | still referenced this please use ``django.template.loader`` instead. |
| 873 | |
| 874 | ``django.db.models.fields.URLField.verify_exists`` |
| 875 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 876 | |
| 877 | This functionality has been removed due to intractable performance and |
| 878 | security issues. Any existing usage of ``verify_exists`` should be |
| 879 | removed. |
| 880 | |
| 881 | ``django.core.files.storage.Storage.open`` |
| 882 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 883 | |
| 884 | The ``open`` method of the base Storage class took an obscure parameter |
| 885 | ``mixin`` which allowed you to dynamically change the base classes of the |
| 886 | returned file object. This has been removed. In the rare case you relied on the |
| 887 | `mixin` parameter, you can easily achieve the same by overriding the `open` |
| 888 | method, e.g.:: |
| 889 | |
| 890 | from django.core.files import File |
| 891 | from django.core.files.storage import FileSystemStorage |
| 892 | |
| 893 | class Spam(File): |
| 894 | """ |
| 895 | Spam, spam, spam, spam and spam. |
| 896 | """ |
| 897 | def ham(self): |
| 898 | return 'eggs' |
| 899 | |
| 900 | class SpamStorage(FileSystemStorage): |
| 901 | """ |
| 902 | A custom file storage backend. |
| 903 | """ |
| 904 | def open(self, name, mode='rb'): |
| 905 | return Spam(open(self.path(name), mode)) |
| 906 | |
| 907 | YAML deserializer now uses ``yaml.safe_load`` |
| 908 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 909 | |
| 910 | ``yaml.load`` is able to construct any Python object, which may trigger |
| 911 | arbitrary code execution if you process a YAML document that comes from an |
| 912 | untrusted source. This feature isn't necessary for Django's YAML deserializer, |
| 913 | whose primary use is to load fixtures consisting of simple objects. Even though |
| 914 | fixtures are trusted data, for additional security, the YAML deserializer now |
| 915 | uses ``yaml.safe_load``. |
| 916 | |
| 917 | Features deprecated in 1.4 |
| 918 | ========================== |
| 919 | |
| 920 | Old styles of calling ``cache_page`` decorator |
| 921 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 922 | |
| 923 | Some legacy ways of calling :func:`~django.views.decorators.cache.cache_page` |
| 924 | have been deprecated, please see the docs for the correct way to use this |
| 925 | decorator. |
| 926 | |
| 927 | Support for PostgreSQL versions older than 8.2 |
| 928 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 929 | |
| 930 | Django 1.3 dropped support for PostgreSQL versions older than 8.0 and the |
| 931 | relevant documents suggested to use a recent version because of performance |
| 932 | reasons but more importantly because end of the upstream support periods for |
| 933 | releases 8.0 and 8.1 was near (November 2010). |
| 934 | |
| 935 | Django 1.4 takes that policy further and sets 8.2 as the minimum PostgreSQL |
| 936 | version it officially supports. |
| 937 | |
| 938 | Request exceptions are now always logged |
| 939 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 940 | |
| 941 | When :doc:`logging support </topics/logging/>` was added to Django in 1.3, the |
| 942 | admin error email support was moved into the |
| 943 | :class:`django.utils.log.AdminEmailHandler`, attached to the |
| 944 | ``'django.request'`` logger. In order to maintain the established behavior of |
| 945 | error emails, the ``'django.request'`` logger was called only when |
| 946 | :setting:`DEBUG` was ``False``. |
| 947 | |
| 948 | To increase the flexibility of error logging for requests, the |
| 949 | ``'django.request'`` logger is now called regardless of the value of |
| 950 | :setting:`DEBUG`, and the default settings file for new projects now includes a |
| 951 | separate filter attached to :class:`django.utils.log.AdminEmailHandler` to |
| 952 | prevent admin error emails in ``DEBUG`` mode:: |
| 953 | |
| 954 | 'filters': { |
| 955 | 'require_debug_false': { |
| 956 | '()': 'django.utils.log.RequireDebugFalse' |
| 957 | } |
| 958 | }, |
| 959 | 'handlers': { |
| 960 | 'mail_admins': { |
| 961 | 'level': 'ERROR', |
| 962 | 'filters': ['require_debug_false'], |
| 963 | 'class': 'django.utils.log.AdminEmailHandler' |
| 964 | } |
| 965 | }, |
| 966 | |
| 967 | If your project was created prior to this change, your :setting:`LOGGING` |
| 968 | setting will not include this new filter. In order to maintain |
| 969 | backwards-compatibility, Django will detect that your ``'mail_admins'`` handler |
| 970 | configuration includes no ``'filters'`` section, and will automatically add |
| 971 | this filter for you and issue a pending-deprecation warning. This will become a |
| 972 | deprecation warning in Django 1.5, and in Django 1.6 the |
| 973 | backwards-compatibility shim will be removed entirely. |
| 974 | |
| 975 | The existence of any ``'filters'`` key under the ``'mail_admins'`` handler will |
| 976 | disable this backward-compatibility shim and deprecation warning. |
| 977 | |
| 978 | ``django.conf.urls.defaults`` |
| 979 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 980 | |
| 981 | Until Django 1.3 the functions :func:`~django.conf.urls.include`, |
| 982 | :func:`~django.conf.urls.patterns` and :func:`~django.conf.urls.url` plus |
| 983 | :data:`~django.conf.urls.handler404`, :data:`~django.conf.urls.handler500` |
| 984 | were located in a ``django.conf.urls.defaults`` module. |
| 985 | |
| 986 | Starting with Django 1.4 they are now available in :mod:`django.conf.urls`. |
| 987 | |
| 988 | ``django.contrib.databrowse`` |
| 989 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 990 | |
| 991 | Databrowse has not seen active development for some time, and this does not show |
| 992 | any sign of changing. There had been a suggestion for a `GSOC project`_ to |
| 993 | integrate the functionality of databrowse into the admin, but no progress was |
| 994 | made. While Databrowse has been deprecated, an enhancement of |
| 995 | ``django.contrib.admin`` providing a similar feature set is still possible. |
| 996 | |
| 997 | .. _GSOC project: https://code.djangoproject.com/wiki/SummerOfCode2011#Integratedatabrowseintotheadmin |
| 998 | |
| 999 | The code that powers Databrowse is licensed under the same terms as Django |
| 1000 | itself, and so is available to be adopted by an individual or group as |
| 1001 | a third-party project. |
| 1002 | |
| 1003 | ``django.core.management.setup_environ`` |
| 1004 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 1005 | |
| 1006 | This function temporarily modified ``sys.path`` in order to make the parent |
| 1007 | "project" directory importable under the old flat :djadmin:`startproject` |
| 1008 | layout. This function is now deprecated, as its path workarounds are no longer |
| 1009 | needed with the new ``manage.py`` and default project layout. |
| 1010 | |
| 1011 | This function was never documented or part of the public API, but was widely |
| 1012 | recommended for use in setting up a "Django environment" for a user script. |
| 1013 | These uses should be replaced by setting the ``DJANGO_SETTINGS_MODULE`` |
| 1014 | environment variable or using :func:`django.conf.settings.configure`. |
| 1015 | |
| 1016 | ``django.core.management.execute_manager`` |
| 1017 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 1018 | |
| 1019 | This function was previously used by ``manage.py`` to execute a management |
| 1020 | command. It is identical to |
| 1021 | ``django.core.management.execute_from_command_line``, except that it first |
| 1022 | calls ``setup_environ``, which is now deprecated. As such, ``execute_manager`` |
| 1023 | is also deprecated; ``execute_from_command_line`` can be used instead. Neither |
| 1024 | of these functions is documented as part of the public API, but a deprecation |
| 1025 | path is needed due to use in existing ``manage.py`` files. |
| 1026 | |
| 1027 | ``is_safe`` and ``needs_autoescape`` attributes of template filters |
| 1028 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 1029 | |
| 1030 | Two flags, ``is_safe`` and ``needs_autoescape``, define how each template filter |
| 1031 | interacts with Django's auto-escaping behavior. They used to be attributes of |
| 1032 | the filter function:: |
| 1033 | |
| 1034 | @register.filter |
| 1035 | def noop(value): |
| 1036 | return value |
| 1037 | noop.is_safe = True |
| 1038 | |
| 1039 | However, this technique caused some problems in combination with decorators, |
| 1040 | especially :func:`@stringfilter <django.template.defaultfilters.stringfilter>`. |
| 1041 | Now, the flags are keyword arguments of :meth:`@register.filter |
| 1042 | <django.template.Library.filter>`:: |
| 1043 | |
| 1044 | @register.filter(is_safe=True) |
| 1045 | def noop(value): |
| 1046 | return value |
| 1047 | |
| 1048 | See :ref:`filters and auto-escaping <filters-auto-escaping>` for more information. |
| 1049 | |
| 1050 | Session cookies now have the ``httponly`` flag by default |
| 1051 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 1052 | |
| 1053 | Session cookies now include the ``httponly`` attribute by default to |
| 1054 | help reduce the impact of potential XSS attacks. For strict backwards |
| 1055 | compatibility, use ``SESSION_COOKIE_HTTPONLY = False`` in your settings file. |
| 1056 | |
| 1057 | Wildcard expansion of application names in `INSTALLED_APPS` |
| 1058 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 1059 | |
| 1060 | Until Django 1.3, :setting:`INSTALLED_APPS` accepted wildcards in application |
| 1061 | names, like ``django.contrib.*``. The expansion was performed by a |
| 1062 | filesystem-based implementation of ``from <package> import *``. Unfortunately, |
| 1063 | `this can't be done reliably`_. |
| 1064 | |
| 1065 | This behavior was never documented. Since it is un-pythonic and not obviously |
| 1066 | useful, it was removed in Django 1.4. If you relied on it, you must edit your |
| 1067 | settings file to list all your applications explicitly. |
| 1068 | |
| 1069 | .. _this can't be done reliably: http://docs.python.org/tutorial/modules.html#importing-from-a-package |
| 1070 | |
| 1071 | ``HttpRequest.raw_post_data`` renamed to ``HttpRequest.body`` |
| 1072 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 1073 | |
| 1074 | This attribute was confusingly named ``HttpRequest.raw_post_data``, but it |
| 1075 | actually provided the body of the HTTP request. It's been renamed to |
| 1076 | ``HttpRequest.body``, and ``HttpRequest.raw_post_data`` has been deprecated. |
| 1077 | |
| 1078 | |
| 1079 | The Django 1.4 roadmap |
| 1080 | ====================== |
| 1081 | |
| 1082 | Before the final Django 1.4 release, several other preview/development releases |
| 1083 | will be made available. The current schedule consists of at least the following: |
| 1084 | |
| 1085 | * Week of **January 30, 2012**: First Django 1.4 beta release; final |
| 1086 | feature freeze for Django 1.4. |
| 1087 | |
| 1088 | * Week of **February 27, 2012**: First Django 1.4 release |
| 1089 | candidate; string freeze for translations. |
| 1090 | |
| 1091 | * Week of **March 5, 2012**: Django 1.4 final release. |
| 1092 | |
| 1093 | If necessary, additional alpha, beta or release-candidate packages |
| 1094 | will be issued prior to the final 1.4 release. Django 1.4 will be |
| 1095 | released approximately one week after the final release candidate. |
| 1096 | |
| 1097 | What you can do to help |
| 1098 | ======================= |
| 1099 | |
| 1100 | In order to provide a high-quality 1.4 release, we need your help. Although this |
| 1101 | beta release is, again, *not* intended for production use, you can help the |
| 1102 | Django team by trying out the beta codebase in a safe test environment and |
| 1103 | reporting any bugs or issues you encounter. The Django ticket tracker is the |
| 1104 | central place to search for open issues: |
| 1105 | |
| 1106 | * http://code.djangoproject.com/timeline |
| 1107 | |
| 1108 | Please open new tickets if no existing ticket corresponds to a problem you're |
| 1109 | running into. |
| 1110 | |
| 1111 | Additionally, discussion of Django development, including progress toward the |
| 1112 | 1.3 release, takes place daily on the django-developers mailing list: |
| 1113 | |
| 1114 | * http://groups.google.com/group/django-developers |
| 1115 | |
| 1116 | ... and in the ``#django-dev`` IRC channel on ``irc.freenode.net``. If you're |
| 1117 | interested in helping out with Django's development, feel free to join the |
| 1118 | discussions there. |
| 1119 | |
| 1120 | Django's online documentation also includes pointers on how to contribute to |
| 1121 | Django: |
| 1122 | |
| 1123 | * :doc:`How to contribute to Django </internals/contributing/index>` |
| 1124 | |
| 1125 | Contributions on any level -- developing code, writing documentation or simply |
| 1126 | triaging tickets and helping to test proposed bugfixes -- are always welcome and |
| 1127 | appreciated. |
| 1128 | |
| 1129 | Several development sprints will also be taking place before the 1.4 |
| 1130 | release; these will typically be announced in advance on the |
| 1131 | django-developers mailing list, and anyone who wants to help is |
| 1132 | welcome to join in. |