| | 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. |