Code

Ticket #15124: 15124ticket.diff

File 15124ticket.diff, 51.2 KB (added by ethlinn, 2 years ago)

Fix with tests and docs with realease notes for 1.4-beta-1 instead of 1.4

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