From ec5e2f0ccc1d1d5e6a744e2be77deae68c66fcf8 Mon Sep 17 00:00:00 2001
From: Jannis Leidel <jannis@leidel.info>
Date: Thu, 9 Feb 2012 18:58:45 +0000
Subject: [PATCH] Fixed #17460 -- Extended the HIDDEN_SETTINGS constant in 
 with a few more sensible names of settings to hide in the debug view. Many
 thanks to chomik, lpiatek and tomaszrybak.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@17481 bcc190cf-cafb-0310-a4f2-bffc1f526a37
---
 django/views/debug.py        |    2 +-
 docs/ref/settings.txt        |   25 +-
 docs/releases/1.4-beta-1.txt | 1134 ++++++++++++++++++++++++++++++++++
 docs/releases/index.txt      |    1 +
 4 files changed, 1153 insertions(+), 9 deletions(-)
 create mode 100644 docs/releases/1.4-beta-1.txt

diff --git a/django/views/debug.py b/django/views/debug.py
index 61817bb6b7..b5499595a7 100644
--- a/django/views/debug.py
+++ b/django/views/debug.py
@@ -14,7 +14,7 @@ from django.utils.html import escape
 from django.utils.importlib import import_module
 from django.utils.encoding import smart_unicode, smart_str
 
-HIDDEN_SETTINGS = re.compile('SECRET|PASSWORD|PROFANITIES_LIST|SIGNATURE')
+HIDDEN_SETTINGS = re.compile('API|TOKEN|KEY|SECRET|PASS|PROFANITIES_LIST|SIGNATURE')
 
 CLEANSED_SUBSTITUTE = u'********************'
 
diff --git a/docs/ref/settings.txt b/docs/ref/settings.txt
index d8260b0fa2..c394c34045 100644
--- a/docs/ref/settings.txt
+++ b/docs/ref/settings.txt
@@ -756,15 +756,24 @@ Default: ``False``
 
 A boolean that turns on/off debug mode.
 
-If you define custom settings, `django/views/debug.py`_ has a ``HIDDEN_SETTINGS``
-regular expression which will hide from the DEBUG view anything that contains
-``'SECRET'``, ``'PASSWORD'``, ``'PROFANITIES'``, or ``'SIGNATURE'``. This allows
-untrusted users to be able to give backtraces without seeing sensitive (or
-offensive) settings.
+If you define custom settings, `django/views/debug.py`_ has a
+``HIDDEN_SETTINGS`` regular expression which will hide from the DEBUG view
+anything that contains ``'API'``, ``'TOKEN'``, ``'KEY'``, ``'SECRET'``,
+``'PASS'``, ``'PROFANITIES_LIST'``, or ``'SIGNATURE'``. This allows untrusted
+users to be able to give backtraces without seeing sensitive (or offensive)
+settings.
 
-Still, note that there are always going to be sections of your debug output that
-are inappropriate for public consumption. File paths, configuration options, and
-the like all give attackers extra information about your server.
+.. versionchanged:: 1.4
+
+    ``'PASSWORD'`` changed to ``'PASS'``. ``'API'``, ``'TOKEN'``, ``'KEY'`` 
+    were added.
+
+Note that due to how regular expression matching works ``'PASS'`` will also
+match PASSWORD, just as ``'TOKEN'`` will also match TOKENIZED and so on.
+
+Still, note that there are always going to be sections of your debug output
+that are inappropriate for public consumption. File paths, configuration
+options, and the like all give attackers extra information about your server.
 
 It is also important to remember that when running with :setting:`DEBUG`
 turned on, Django will remember every SQL query it executes. This is useful
diff --git a/docs/releases/1.4-beta-1.txt b/docs/releases/1.4-beta-1.txt
new file mode 100644
index 0000000000..77bfc69017
--- /dev/null
+++ b/docs/releases/1.4-beta-1.txt
@@ -0,0 +1,1134 @@
+==============================
+Django 1.4 beta release notes
+==============================
+
+December 22, 2011.
+
+Welcome to Django 1.4 beta!
+
+This is the first in a series of preview/development releases leading up to
+the eventual release of Django 1.4, scheduled for March 2012. This release is
+primarily targeted at developers who are interested in trying out new features
+and testing the Django codebase to help identify and resolve bugs prior to the
+final 1.4 release.
+
+As such, this release is *not* intended for production use, and any such use
+is discouraged.
+
+Django 1.4 beta includes various `new features`_ and some minor `backwards
+incompatible changes`_. There are also some features that have been dropped,
+which are detailed in :doc:`our deprecation plan </internals/deprecation>`,
+and we've `begun the deprecation process for some features`_.
+
+.. _new features: `What's new in Django 1.4`_
+.. _backwards incompatible changes: `Backwards incompatible changes in 1.4`_
+.. _begun the deprecation process for some features: `Features deprecated in 1.4`_
+
+Python compatibility
+====================
+
+While not a new feature, it's important to note that Django 1.4 introduces the
+second shift in our Python compatibility policy since Django's initial public
+debut. Django 1.2 dropped support for Python 2.3; now Django 1.4 drops support
+for Python 2.4. As such, the minimum Python version required for Django is now
+2.5, and Django is tested and supported on Python 2.5, 2.6 and 2.7.
+
+This change should affect only a small number of Django users, as most
+operating-system vendors today are shipping Python 2.5 or newer as their default
+version. If you're still using Python 2.4, however, you'll need to stick to
+Django 1.3 until you can upgrade; per :doc:`our support policy
+</internals/release-process>`, Django 1.3 will continue to receive security
+support until the release of Django 1.5.
+
+Django does not support Python 3.x at this time. A document outlining our full
+timeline for deprecating Python 2.x and moving to Python 3.x will be published
+before the release of Django 1.4.
+
+What's new in Django 1.4
+========================
+
+Support for in-browser testing frameworks
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Django 1.4 now supports integration with in-browser testing frameworks such
+as Selenium_ or Windmill_ thanks to the :class:`django.test.LiveServerTestCase`
+base class, allowing you to test the interactions between your site's front and
+back ends more comprehensively. See the
+:class:`documentation<django.test.LiveServerTestCase>` for more details and
+concrete examples.
+
+.. _Windmill: http://www.getwindmill.com/
+.. _Selenium: http://seleniumhq.org/
+
+``SELECT FOR UPDATE`` support
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Django 1.4 now includes a :meth:`QuerySet.select_for_update()
+<django.db.models.query.QuerySet.select_for_update>` method which generates a
+``SELECT ... FOR UPDATE`` SQL query. This will lock rows until the end of the
+transaction, meaning that other transactions cannot modify or delete rows
+matched by a ``FOR UPDATE`` query.
+
+For more details, see the documentation for
+:meth:`~django.db.models.query.QuerySet.select_for_update`.
+
+``Model.objects.bulk_create`` in the ORM
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This method allows for more efficient creation of multiple objects in the ORM.
+It can provide significant performance increases if you have many objects.
+Django makes use of this internally, meaning some operations (such as database
+setup for test suites) have seen a performance benefit as a result.
+
+See the :meth:`~django.db.models.query.QuerySet.bulk_create` docs for more
+information.
+
+``QuerySet.prefetch_related``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Similar to :meth:`~django.db.models.query.QuerySet.select_related` but with a
+different strategy and broader scope,
+:meth:`~django.db.models.query.QuerySet.prefetch_related` has been added to
+:class:`~django.db.models.query.QuerySet`. This method returns a new
+``QuerySet`` that will prefetch each of the specified related lookups in a
+single batch as soon as the query begins to be evaluated. Unlike
+``select_related``, it does the joins in Python, not in the database, and
+supports many-to-many relationships,
+:class:`~django.contrib.contenttypes.generic.GenericForeignKey` and more. This
+allows you to fix a very common performance problem in which your code ends up
+doing O(n) database queries (or worse) if objects on your primary ``QuerySet``
+each have many related objects that you also need.
+
+Improved password hashing
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Django's auth system (``django.contrib.auth``) stores passwords using a one-way
+algorithm. Django 1.3 uses the SHA1_ algorithm, but increasing processor speeds
+and theoretical attacks have revealed that SHA1 isn't as secure as we'd like.
+Thus, Django 1.4 introduces a new password storage system: by default Django now
+uses the PBKDF2_ algorithm (as recommended by NIST_). You can also easily choose
+a different algorithm (including the popular bcrypt_ algorithm). For more
+details, see :ref:`auth_password_storage`.
+
+.. _sha1: http://en.wikipedia.org/wiki/SHA1
+.. _pbkdf2: http://en.wikipedia.org/wiki/PBKDF2
+.. _nist: http://csrc.nist.gov/publications/nistpubs/800-132/nist-sp800-132.pdf
+.. _bcrypt: http://en.wikipedia.org/wiki/Bcrypt
+
+
+HTML5 Doctype
+~~~~~~~~~~~~~
+
+We've switched the admin and other bundled templates to use the HTML5
+doctype. While Django will be careful to maintain compatibility with older
+browsers, this change means that you can use any HTML5 features you need in
+admin pages without having to lose HTML validity or override the provided
+templates to change the doctype.
+
+List filters in admin interface
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Prior to Django 1.4, the :mod:`~django.contrib.admin` app allowed you to specify
+change list filters by specifying a field lookup, but didn't allow you to create
+custom filters. This has been rectified with a simple API (previously used
+internally and known as "FilterSpec"). For more details, see the documentation
+for :attr:`~django.contrib.admin.ModelAdmin.list_filter`.
+
+Multiple sort in admin interface
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The admin change list now supports sorting on multiple columns. It respects all
+elements of the :attr:`~django.contrib.admin.ModelAdmin.ordering` attribute, and
+sorting on multiple columns by clicking on headers is designed to mimic the
+behavior of desktop GUIs. The
+:meth:`~django.contrib.admin.ModelAdmin.get_ordering` method for specifying the
+ordering dynamically (e.g. depending on the request) has also been added.
+
+New ``ModelAdmin`` methods
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+A new :meth:`~django.contrib.admin.ModelAdmin.save_related` method was added to
+:mod:`~django.contrib.admin.ModelAdmin` to ease customization of how
+related objects are saved in the admin.
+
+Two other new methods,
+:meth:`~django.contrib.admin.ModelAdmin.get_list_display` and
+:meth:`~django.contrib.admin.ModelAdmin.get_list_display_links`
+were added to :class:`~django.contrib.admin.ModelAdmin` to enable the dynamic
+customization of fields and links displayed on the admin change list.
+
+Admin inlines respect user permissions
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Admin inlines will now only allow those actions for which the user has
+permission. For ``ManyToMany`` relationships with an auto-created intermediate
+model (which does not have its own permissions), the change permission for the
+related model determines if the user has the permission to add, change or
+delete relationships.
+
+Tools for cryptographic signing
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Django 1.4 adds both a low-level API for signing values and a high-level API
+for setting and reading signed cookies, one of the most common uses of
+signing in Web applications.
+
+See the :doc:`cryptographic signing </topics/signing>` docs for more
+information.
+
+Cookie-based session backend
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Django 1.4 introduces a new cookie-based backend for the session framework
+which uses the tools for :doc:`cryptographic signing </topics/signing>` to
+store the session data in the client's browser.
+
+See the :ref:`cookie-based session backend <cookie-session-backend>` docs for
+more information.
+
+New form wizard
+~~~~~~~~~~~~~~~
+
+The previous ``FormWizard`` from the formtools contrib app has been
+replaced with a new implementation based on the class-based views
+introduced in Django 1.3. It features a pluggable storage API and doesn't
+require the wizard to pass around hidden fields for every previous step.
+
+Django 1.4 ships with a session-based storage backend and a cookie-based
+storage backend. The latter uses the tools for
+:doc:`cryptographic signing </topics/signing>` also introduced in
+Django 1.4 to store the wizard's state in the user's cookies.
+
+See the :doc:`form wizard </ref/contrib/formtools/form-wizard>` docs for
+more information.
+
+``reverse_lazy``
+~~~~~~~~~~~~~~~~
+
+A lazily evaluated version of :func:`django.core.urlresolvers.reverse` was
+added to allow using URL reversals before the project's URLConf gets loaded.
+
+Translating URL patterns
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Django 1.4 gained the ability to look for a language prefix in the URL pattern
+when using the new :func:`~django.conf.urls.i18n.i18n_patterns` helper function.
+Additionally, it's now possible to define translatable URL patterns using
+:func:`~django.utils.translation.ugettext_lazy`. See
+:ref:`url-internationalization` for more information about the language prefix
+and how to internationalize URL patterns.
+
+Contextual translation support for ``{% trans %}`` and ``{% blocktrans %}``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The :ref:`contextual translation<contextual-markers>` support introduced in
+Django 1.3 via the ``pgettext`` function has been extended to the
+:ttag:`trans` and :ttag:`blocktrans` template tags using the new ``context``
+keyword.
+
+Customizable ``SingleObjectMixin`` URLConf kwargs
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Two new attributes,
+:attr:`pk_url_kwarg<django.views.generic.detail.SingleObjectMixin.pk_url_kwarg>`
+and
+:attr:`slug_url_kwarg<django.views.generic.detail.SingleObjectMixin.slug_url_kwarg>`,
+have been added to :class:`~django.views.generic.detail.SingleObjectMixin` to
+enable the customization of URLConf keyword arguments used for single
+object generic views.
+
+Assignment template tags
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+A new :ref:`assignment_tag<howto-custom-template-tags-assignment-tags>` helper
+function was added to ``template.Library`` to ease the creation of template
+tags that store data in a specified context variable.
+
+``*args`` and ``**kwargs`` support for template tag helper functions
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The :ref:`simple_tag<howto-custom-template-tags-simple-tags>`,
+:ref:`inclusion_tag <howto-custom-template-tags-inclusion-tags>` and
+newly introduced
+:ref:`assignment_tag<howto-custom-template-tags-assignment-tags>` template
+helper functions may now accept any number of positional or keyword arguments.
+For example:
+
+.. code-block:: python
+
+    @register.simple_tag
+    def my_tag(a, b, *args, **kwargs):
+        warning = kwargs['warning']
+        profile = kwargs['profile']
+        ...
+        return ...
+
+Then in the template any number of arguments may be passed to the template tag.
+For example:
+
+.. code-block:: html+django
+
+    {% my_tag 123 "abcd" book.title warning=message|lower profile=user.profile %}
+
+No wrapping of exceptions in ``TEMPLATE_DEBUG`` mode
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+In previous versions of Django, whenever the :setting:`TEMPLATE_DEBUG` setting
+was ``True``, any exception raised during template rendering (even exceptions
+unrelated to template syntax) were wrapped in ``TemplateSyntaxError`` and
+re-raised. This was done in order to provide detailed template source location
+information in the debug 500 page.
+
+In Django 1.4, exceptions are no longer wrapped. Instead, the original
+exception is annotated with the source information. This means that catching
+exceptions from template rendering is now consistent regardless of the value of
+:setting:`TEMPLATE_DEBUG`, and there's no need to catch and unwrap
+``TemplateSyntaxError`` in order to catch other errors.
+
+``truncatechars`` template filter
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Added a filter which truncates a string to be no longer than the specified
+number of characters. Truncated strings end with a translatable ellipsis
+sequence ("..."). See the documentation for :tfilter:`truncatechars` for
+more details.
+
+``static`` template tag
+~~~~~~~~~~~~~~~~~~~~~~~
+
+The :mod:`staticfiles<django.contrib.staticfiles>` contrib app has a new
+:ttag:`static<staticfiles-static>` template tag to refer to files saved with
+the :setting:`STATICFILES_STORAGE` storage backend. It uses the storage
+backend's ``url`` method and therefore supports advanced features such as
+:ref:`serving files from a cloud service<staticfiles-from-cdn>`.
+
+``CachedStaticFilesStorage`` storage backend
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+In addition to the `static template tag`_, the
+:mod:`staticfiles<django.contrib.staticfiles>` contrib app now has a
+:class:`~django.contrib.staticfiles.storage.CachedStaticFilesStorage` backend
+which caches the files it saves (when running the :djadmin:`collectstatic`
+management command) by appending the MD5 hash of the file's content to the
+filename. For example, the file ``css/styles.css`` would also be saved as
+``css/styles.55e7cbb9ba48.css``
+
+See the :class:`~django.contrib.staticfiles.storage.CachedStaticFilesStorage`
+docs for more information.
+
+Simple clickjacking protection
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+We've added a middleware to provide easy protection against `clickjacking
+<http://en.wikipedia.org/wiki/Clickjacking>`_ using the ``X-Frame-Options``
+header. It's not enabled by default for backwards compatibility reasons, but
+you'll almost certainly want to :doc:`enable it </ref/clickjacking/>` to help
+plug that security hole for browsers that support the header.
+
+CSRF improvements
+~~~~~~~~~~~~~~~~~
+
+We've made various improvements to our CSRF features, including the
+:func:`~django.views.decorators.csrf.ensure_csrf_cookie` decorator which can
+help with AJAX heavy sites, protection for PUT and DELETE requests, and the
+:setting:`CSRF_COOKIE_SECURE` and :setting:`CSRF_COOKIE_PATH` settings which can
+improve the security and usefulness of the CSRF protection. See the :doc:`CSRF
+docs </ref/contrib/csrf>` for more information.
+
+Error report filtering
+~~~~~~~~~~~~~~~~~~~~~~
+
+Two new function decorators, :func:`sensitive_variables` and
+:func:`sensitive_post_parameters`, were added to allow designating the
+local variables and POST parameters which may contain sensitive
+information and should be filtered out of error reports.
+
+All POST parameters are now systematically filtered out of error reports for
+certain views (``login``, ``password_reset_confirm``, ``password_change``, and
+``add_view`` in :mod:`django.contrib.auth.views`, as well as
+``user_change_password`` in the admin app) to prevent the leaking of sensitive
+information such as user passwords.
+
+You may override or customize the default filtering by writing a :ref:`custom
+filter<custom-error-reports>`. For more information see the docs on
+:ref:`Filtering error reports<filtering-error-reports>`.
+
+Extended IPv6 support
+~~~~~~~~~~~~~~~~~~~~~
+
+The previously added support for IPv6 addresses when using the runserver
+management command in Django 1.3 has now been further extended by adding
+a :class:`~django.db.models.fields.GenericIPAddressField` model field,
+a :class:`~django.forms.fields.GenericIPAddressField` form field and
+the validators :data:`~django.core.validators.validate_ipv46_address` and
+:data:`~django.core.validators.validate_ipv6_address`
+
+Updated default project layout and ``manage.py``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Django 1.4 ships with an updated default project layout and ``manage.py`` file
+for the :djadmin:`startproject` management command. These fix some issues with
+the previous ``manage.py`` handling of Python import paths that caused double
+imports, trouble moving from development to deployment, and other
+difficult-to-debug path issues.
+
+The previous ``manage.py`` called functions that are now deprecated, and thus
+projects upgrading to Django 1.4 should update their ``manage.py``. (The
+old-style ``manage.py`` will continue to work as before until Django 1.6; in
+1.5 it will raise ``DeprecationWarning``).
+
+The new recommended ``manage.py`` file should look like this::
+
+    #!/usr/bin/env python
+    import os, sys
+
+    if __name__ == "__main__":
+        os.environ.setdefault("DJANGO_SETTINGS_MODULE", "{{ project_name }}.settings")
+
+        from django.core.management import execute_from_command_line
+
+        execute_from_command_line(sys.argv)
+
+``{{ project_name }}`` should be replaced with the Python package name of the
+actual project.
+
+If settings, URLconfs, and apps within the project are imported or referenced
+using the project name prefix (e.g. ``myproject.settings``, ``ROOT_URLCONF =
+"myproject.urls"``, etc), the new ``manage.py`` will need to be moved one
+directory up, so it is outside the project package rather than adjacent to
+``settings.py`` and ``urls.py``.
+
+For instance, with the following layout::
+
+    manage.py
+    mysite/
+        __init__.py
+        settings.py
+        urls.py
+        myapp/
+            __init__.py
+            models.py
+
+You could import ``mysite.settings``, ``mysite.urls``, and ``mysite.myapp``,
+but not ``settings``, ``urls``, or ``myapp`` as top-level modules.
+
+Anything imported as a top-level module can be placed adjacent to the new
+``manage.py``. For instance, to decouple "myapp" from the project module and
+import it as just ``myapp``, place it outside the ``mysite/`` directory::
+
+    manage.py
+    myapp/
+        __init__.py
+        models.py
+    mysite/
+        __init__.py
+        settings.py
+        urls.py
+
+If the same code is imported inconsistently (some places with the project
+prefix, some places without it), the imports will need to be cleaned up when
+switching to the new ``manage.py``.
+
+Improved WSGI support
+~~~~~~~~~~~~~~~~~~~~~
+
+The :djadmin:`startproject` management command now adds a :file:`wsgi.py`
+module to the initial project layout, containing a simple WSGI application that
+can be used for :doc:`deploying with WSGI app
+servers</howto/deployment/wsgi/index>`.
+
+The :djadmin:`built-in development server<runserver>` now supports using an
+externally-defined WSGI callable, so as to make it possible to run runserver
+with the same WSGI configuration that is used for deployment. A new
+:setting:`WSGI_APPLICATION` setting is available to configure which WSGI
+callable :djadmin:`runserver` uses.
+
+(The :djadmin:`runfcgi` management command also internally wraps the WSGI
+callable configured via :setting:`WSGI_APPLICATION`.)
+
+Custom project and app templates
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The :djadmin:`startapp` and :djadmin:`startproject` management commands
+got a ``--template`` option for specifying a path or URL to a custom app or
+project template.
+
+For example, Django will use the ``/path/to/my_project_template`` directory
+when running the following command::
+
+    django-admin.py startproject --template=/path/to/my_project_template myproject
+
+You can also now provide a destination directory as the second
+argument to both :djadmin:`startapp` and :djadmin:`startproject`::
+
+    django-admin.py startapp myapp /path/to/new/app
+    django-admin.py startproject myproject /path/to/new/project
+
+For more information, see the :djadmin:`startapp` and :djadmin:`startproject`
+documentation.
+
+Support for time zones
+~~~~~~~~~~~~~~~~~~~~~~
+
+Django 1.4 adds :ref:`support for time zones <time-zones>`. When it's enabled,
+Django stores date and time information in UTC in the database, uses time
+zone-aware datetime objects internally, and translates them to the end user's
+time zone in templates and forms.
+
+Reasons for using this feature include:
+
+- Customizing date and time display for users around the world.
+- Storing datetimes in UTC for database portability and interoperability.
+  (This argument doesn't apply to PostgreSQL, because it already stores
+  timestamps with time zone information in Django 1.3.)
+- Avoiding data corruption problems around DST transitions.
+
+Time zone support is enabled by default in new projects created with
+:djadmin:`startproject`. If you want to use this feature in an existing
+project, there is a :ref:`migration guide <time-zones-migration-guide>`.
+
+Minor features
+~~~~~~~~~~~~~~
+
+Django 1.4 also includes several smaller improvements worth noting:
+
+* A more usable stacktrace in the technical 500 page: frames in the
+  stack trace which reference Django's code are dimmed out, while
+  frames in user code are slightly emphasized. This change makes it
+  easier to scan a stacktrace for issues in user code.
+
+* :doc:`Tablespace support </topics/db/tablespaces>` in PostgreSQL.
+
+* Customizable names for :meth:`~django.template.Library.simple_tag`.
+
+* In the documentation, a helpful :doc:`security overview </topics/security>`
+  page.
+
+* The :func:`django.contrib.auth.models.check_password` function has been moved
+  to the :mod:`django.contrib.auth.utils` module. Importing it from the old
+  location will still work, but you should update your imports.
+
+* The :djadmin:`collectstatic` management command gained a ``--clear`` option
+  to delete all files at the destination before copying or linking the static
+  files.
+
+* It is now possible to load fixtures containing forward references when using
+  MySQL with the InnoDB database engine.
+
+* A new 403 response handler has been added as
+  ``'django.views.defaults.permission_denied'``. You can set your own handler by
+  setting the value of :data:`django.conf.urls.handler403`. See the
+  documentation about :ref:`the 403 (HTTP Forbidden) view<http_forbidden_view>`
+  for more information.
+
+* The :ttag:`trans` template tag now takes an optional ``as`` argument to
+  be able to retrieve a translation string without displaying it but setting
+  a template context variable instead.
+
+* The :ttag:`if` template tag now supports ``{% elif %}`` clauses.
+
+* A new plain text version of the HTTP 500 status code internal error page
+  served when :setting:`DEBUG` is ``True`` is now sent to the client when
+  Django detects that the request has originated in JavaScript code
+  (:meth:`~django.http.HttpRequest.is_ajax` is used for this).
+
+  Similarly to its HTML counterpart, it contains a collection of different
+  pieces of information about the state of the web application.
+
+  This should make it easier to read when debugging interaction with
+  client-side Javascript code.
+
+* Added the :djadminopt:`--no-location` option to the :djadmin:`makemessages`
+  command.
+
+* Changed the ``locmem`` cache backend to use
+  ``pickle.HIGHEST_PROTOCOL`` for better compatibility with the other
+  cache backends.
+
+* Added support in the ORM for generating ``SELECT`` queries containing
+  ``DISTINCT ON``.
+
+  The ``distinct()`` ``QuerySet`` method now accepts an optional list of model
+  field names. If specified, then the ``DISTINCT`` statement is limited to these
+  fields. This is only supported in PostgreSQL.
+
+  For more details, see the documentation for
+  :meth:`~django.db.models.query.QuerySet.distinct`.
+
+* New phrases added to ``HIDDEN_SETTINGS`` regex in `django/views/debug.py`_.
+
+  ``'API'``, ``'TOKEN'``, ``'KEY'`` were added, ``'PASSWORD'`` was changed to 
+  ``'PASS'``.
+
+.. _django/views/debug.py: http://code.djangoproject.com/browser/django/trunk/django/views/debug.py
+
+
+Backwards incompatible changes in 1.4
+=====================================
+
+django.contrib.admin
+~~~~~~~~~~~~~~~~~~~~
+
+The included administration app ``django.contrib.admin`` has for a long time
+shipped with a default set of static files such as JavaScript, images and
+stylesheets. Django 1.3 added a new contrib app ``django.contrib.staticfiles``
+to handle such files in a generic way and defined conventions for static
+files included in apps.
+
+Starting in Django 1.4 the admin's static files also follow this
+convention to make it easier to deploy the included files. In previous
+versions of Django, it was also common to define an ``ADMIN_MEDIA_PREFIX``
+setting to point to the URL where the admin's static files are served by a
+web server. This setting has now been deprecated and replaced by the more
+general setting :setting:`STATIC_URL`. Django will now expect to find the
+admin static files under the URL ``<STATIC_URL>/admin/``.
+
+If you've previously used a URL path for ``ADMIN_MEDIA_PREFIX`` (e.g.
+``/media/``) simply make sure :setting:`STATIC_URL` and :setting:`STATIC_ROOT`
+are configured and your web server serves the files correctly. The development
+server continues to serve the admin files just like before. Don't hesitate to
+consult the :doc:`static files howto </howto/static-files>` for further
+details.
+
+In case your ``ADMIN_MEDIA_PREFIX`` is set to an specific domain (e.g.
+``http://media.example.com/admin/``) make sure to also set your
+:setting:`STATIC_URL` setting to the correct URL, for example
+``http://media.example.com/``.
+
+.. warning::
+
+    If you're implicitely relying on the path of the admin static files on
+    your server's file system when you deploy your site, you have to update
+    that path. The files were moved from :file:`django/contrib/admin/media/`
+    to :file:`django/contrib/admin/static/admin/`.
+
+Supported browsers for the admin
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Django hasn't had a clear policy on which browsers are supported for using the
+admin app. Django's new policy formalizes existing practices: `YUI's A-grade`_
+browsers should provide a fully-functional admin experience, with the notable
+exception of IE6, which is no longer supported.
+
+Released over ten years ago, IE6 imposes many limitations on modern web
+development. The practical implications of this policy are that contributors
+are free to improve the admin without consideration for these limitations.
+
+This new policy **has no impact** on development outside of the admin. Users of
+Django are free to develop webapps compatible with any range of browsers.
+
+.. _YUI's A-grade: http://yuilibrary.com/yui/docs/tutorials/gbs/
+
+Removed admin icons
+~~~~~~~~~~~~~~~~~~~
+
+As part of an effort to improve the performance and usability of the admin's
+changelist sorting interface and of the admin's :attr:`horizontal
+<django.contrib.admin.ModelAdmin.filter_horizontal>` and :attr:`vertical
+<django.contrib.admin.ModelAdmin.filter_vertical>` "filter" widgets, some icon
+files were removed and grouped into two sprite files.
+
+Specifically: ``selector-add.gif``, ``selector-addall.gif``,
+``selector-remove.gif``, ``selector-removeall.gif``,
+``selector_stacked-add.gif`` and ``selector_stacked-remove.gif`` were
+combined into ``selector-icons.gif``; and ``arrow-up.gif`` and
+``arrow-down.gif`` were combined into ``sorting-icons.gif``.
+
+If you used those icons to customize the admin then you will want to replace
+them with your own icons or retrieve them from a previous release.
+
+CSS class names in admin forms
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+To avoid conflicts with other common CSS class names (e.g. "button"), a prefix
+"field-" has been added to all CSS class names automatically generated from the
+form field names in the main admin forms, stacked inline forms and tabular
+inline cells. You will need to take that prefix into account in your custom
+style sheets or javascript files if you previously used plain field names as
+selectors for custom styles or javascript transformations.
+
+Compatibility with old signed data
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Django 1.3 changed the cryptographic signing mechanisms used in a number of
+places in Django. While Django 1.3 kept fallbacks that would accept hashes
+produced by the previous methods, these fallbacks are removed in Django 1.4.
+
+So, if you upgrade to Django 1.4 directly from 1.2 or earlier, you may
+lose/invalidate certain pieces of data that have been cryptographically signed
+using an old method. To avoid this, use Django 1.3 first for a period of time
+to allow the signed data to expire naturally. The affected parts are detailed
+below, with 1) the consequences of ignoring this advice and 2) the amount of
+time you need to run Django 1.3 for the data to expire or become irrelevant.
+
+* ``contrib.sessions`` data integrity check
+
+  * consequences: the user will be logged out, and session data will be lost.
+
+  * time period: defined by :setting:`SESSION_COOKIE_AGE`.
+
+* ``contrib.auth`` password reset hash
+
+  * consequences: password reset links from before the upgrade will not work.
+
+  * time period: defined by :setting:`PASSWORD_RESET_TIMEOUT_DAYS`.
+
+Form-related hashes — these are much shorter lifetime, and are relevant only for
+the short window where a user might fill in a form generated by the pre-upgrade
+Django instance, and try to submit it to the upgraded Django instance:
+
+* ``contrib.comments`` form security hash
+
+  * consequences: the user will see a validation error "Security hash failed".
+
+  * time period: the amount of time you expect users to take filling out comment
+    forms.
+
+* ``FormWizard`` security hash
+
+  * consequences: the user will see an error about the form having expired,
+    and will be sent back to the first page of the wizard, losing the data
+    they have entered so far.
+
+  * time period: the amount of time you expect users to take filling out the
+    affected forms.
+
+* CSRF check
+
+  * Note: This is actually a Django 1.1 fallback, not Django 1.2,
+    and applies only if you are upgrading from 1.1.
+
+  * consequences: the user will see a 403 error with any CSRF protected POST
+    form.
+
+  * time period: the amount of time you expect user to take filling out
+    such forms.
+
+django.contrib.flatpages
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Starting in the 1.4 release the
+:class:`~django.contrib.flatpages.middleware.FlatpageFallbackMiddleware` only
+adds a trailing slash and redirects if the resulting URL refers to an existing
+flatpage. For example, requesting ``/notaflatpageoravalidurl`` in a previous
+version would redirect to ``/notaflatpageoravalidurl/``, which would
+subsequently raise a 404. Requesting ``/notaflatpageoravalidurl`` now will
+immediately raise a 404. Additionally redirects returned by flatpages are now
+permanent (301 status code) to match the behavior of the
+:class:`~django.middleware.common.CommonMiddleware`.
+
+Serialization of :class:`~datetime.datetime` and :class:`~datetime.time`
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+As a consequence of time zone support, and according to the ECMA-262
+specification, some changes were made to the JSON serializer:
+
+- It includes the time zone for aware datetime objects. It raises an exception
+  for aware time objects.
+- It includes milliseconds for datetime and time objects. There is still
+  some precision loss, because Python stores microseconds (6 digits) and JSON
+  only supports milliseconds (3 digits). However, it's better than discarding
+  microseconds entirely.
+
+The XML serializer was also changed to use the ISO8601 format for datetimes.
+The letter ``T`` is used to separate the date part from the time part, instead
+of a space. Time zone information is included in the ``[+-]HH:MM`` format.
+
+The serializers will dump datetimes in fixtures with these new formats. They
+can still load fixtures that use the old format.
+
+``supports_timezone`` changed to ``False`` for SQLite
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The database feature ``supports_timezone`` used to be ``True`` for SQLite.
+Indeed, if you saved an aware datetime object, SQLite stored a string that
+included an UTC offset. However, this offset was ignored when loading the value
+back from the database, which could corrupt the data.
+
+In the context of time zone support, this flag was changed to ``False``, and
+datetimes are now stored without time zone information in SQLite. When
+:setting:`USE_TZ` is ``False``, if you attempt to save an aware datetime
+object, Django raises an exception.
+
+Database connection's thread-locality
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+``DatabaseWrapper`` objects (i.e. the connection objects referenced by
+``django.db.connection`` and ``django.db.connections["some_alias"]``) used to
+be thread-local. They are now global objects in order to be potentially shared
+between multiple threads. While the individual connection objects are now
+global, the ``django.db.connections`` dictionary referencing those objects is
+still thread-local. Therefore if you just use the ORM or
+``DatabaseWrapper.cursor()`` then the behavior is still the same as before.
+Note, however, that ``django.db.connection`` does not directly reference the
+default ``DatabaseWrapper`` object anymore and is now a proxy to access that
+object's attributes. If you need to access the actual ``DatabaseWrapper``
+object, use ``django.db.connections[DEFAULT_DB_ALIAS]`` instead.
+
+As part of this change, all underlying SQLite connections are now enabled for
+potential thread-sharing (by passing the ``check_same_thread=False`` attribute
+to pysqlite). ``DatabaseWrapper`` however preserves the previous behavior by
+disabling thread-sharing by default, so this does not affect any existing
+code that purely relies on the ORM or on ``DatabaseWrapper.cursor()``.
+
+Finally, while it is now possible to pass connections between threads, Django
+does not make any effort to synchronize access to the underlying backend.
+Concurrency behavior is defined by the underlying backend implementation.
+Check their documentation for details.
+
+`COMMENTS_BANNED_USERS_GROUP` setting
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Django's :doc:`comments app </ref/contrib/comments/index>` has historically
+supported excluding the comments of a special user group, but we've never
+documented the feature properly and didn't enforce the exclusion in other parts
+of the app such as the template tags. To fix this problem, we removed the code
+from the feed class.
+
+If you rely on the feature and want to restore the old behavior, simply use
+a custom comment model manager to exclude the user group, like this::
+
+    from django.conf import settings
+    from django.contrib.comments.managers import CommentManager
+
+    class BanningCommentManager(CommentManager):
+        def get_query_set(self):
+            qs = super(BanningCommentManager, self).get_query_set()
+            if getattr(settings, 'COMMENTS_BANNED_USERS_GROUP', None):
+                where = ['user_id NOT IN (SELECT user_id FROM auth_user_groups WHERE group_id = %s)']
+                params = [settings.COMMENTS_BANNED_USERS_GROUP]
+                qs = qs.extra(where=where, params=params)
+            return qs
+
+Save this model manager in your custom comment app (e.g. in
+``my_comments_app/managers.py``) and add it your
+:ref:`custom comment app model <custom-comment-app-api>`::
+
+    from django.db import models
+    from django.contrib.comments.models import Comment
+
+    from my_comments_app.managers import BanningCommentManager
+
+    class CommentWithTitle(Comment):
+        title = models.CharField(max_length=300)
+
+        objects = BanningCommentManager()
+
+For more details, see the documentation about
+:doc:`customizing the comments framework </ref/contrib/comments/custom>`.
+
+`IGNORABLE_404_STARTS` and `IGNORABLE_404_ENDS` settings
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Until Django 1.3, it was possible to exclude some URLs from Django's
+:doc:`404 error reporting</howto/error-reporting>` by adding prefixes to
+:setting:`IGNORABLE_404_STARTS` and suffixes to :setting:`IGNORABLE_404_ENDS`.
+
+In Django 1.4, these two settings are superseded by
+:setting:`IGNORABLE_404_URLS`, which is a list of compiled regular expressions.
+Django won't send an email for 404 errors on URLs that match any of them.
+
+Furthermore, the previous settings had some rather arbitrary default values::
+
+    IGNORABLE_404_STARTS = ('/cgi-bin/', '/_vti_bin', '/_vti_inf')
+    IGNORABLE_404_ENDS = ('mail.pl', 'mailform.pl', 'mail.cgi', 'mailform.cgi',
+                          'favicon.ico', '.php')
+
+It's not Django's role to decide if your website has a legacy ``/cgi-bin/``
+section or a ``favicon.ico``. As a consequence, the default values of
+:setting:`IGNORABLE_404_URLS`, :setting:`IGNORABLE_404_STARTS` and
+:setting:`IGNORABLE_404_ENDS` are all now empty.
+
+If you have customized :setting:`IGNORABLE_404_STARTS` or
+:setting:`IGNORABLE_404_ENDS`, or if you want to keep the old default value,
+you should add the following lines in your settings file::
+
+    import re
+    IGNORABLE_404_URLS = (
+        # for each <prefix> in IGNORABLE_404_STARTS
+        re.compile(r'^<prefix>'),
+        # for each <suffix> in IGNORABLE_404_ENDS
+        re.compile(r'<suffix>$'),
+    )
+
+Don't forget to escape characters that have a special meaning in a regular
+expression.
+
+CSRF protection extended to PUT and DELETE
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Previously, Django's :doc:`CSRF protection </ref/contrib/csrf/>` provided
+protection against only POST requests. Since use of PUT and DELETE methods in
+AJAX applications is becoming more common, we now protect all methods not
+defined as safe by :rfc:`2616` i.e. we exempt GET, HEAD, OPTIONS and TRACE, and
+enforce protection on everything else.
+
+If you are using PUT or DELETE methods in AJAX applications, please see the
+:ref:`instructions about using AJAX and CSRF <csrf-ajax>`.
+
+``django.core.template_loaders``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This was an alias to ``django.template.loader`` since 2005, it has been removed
+without emitting a warning due to the length of the deprecation. If your code
+still referenced this please use ``django.template.loader`` instead.
+
+``django.db.models.fields.URLField.verify_exists``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This functionality has been removed due to intractable performance and
+security issues. Any existing usage of ``verify_exists`` should be
+removed.
+
+``django.core.files.storage.Storage.open``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The ``open`` method of the base Storage class took an obscure parameter
+``mixin`` which allowed you to dynamically change the base classes of the
+returned file object. This has been removed. In the rare case you relied on the
+`mixin` parameter, you can easily achieve the same by overriding the `open`
+method, e.g.::
+
+    from django.core.files import File
+    from django.core.files.storage import FileSystemStorage
+
+    class Spam(File):
+        """
+        Spam, spam, spam, spam and spam.
+        """
+        def ham(self):
+            return 'eggs'
+
+    class SpamStorage(FileSystemStorage):
+        """
+        A custom file storage backend.
+        """
+        def open(self, name, mode='rb'):
+            return Spam(open(self.path(name), mode))
+
+YAML deserializer now uses ``yaml.safe_load``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+``yaml.load`` is able to construct any Python object, which may trigger
+arbitrary code execution if you process a YAML document that comes from an
+untrusted source. This feature isn't necessary for Django's YAML deserializer,
+whose primary use is to load fixtures consisting of simple objects. Even though
+fixtures are trusted data, for additional security, the YAML deserializer now
+uses ``yaml.safe_load``.
+
+Features deprecated in 1.4
+==========================
+
+Old styles of calling ``cache_page`` decorator
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Some legacy ways of calling :func:`~django.views.decorators.cache.cache_page`
+have been deprecated, please see the docs for the correct way to use this
+decorator.
+
+Support for PostgreSQL versions older than 8.2
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Django 1.3 dropped support for PostgreSQL versions older than 8.0 and the
+relevant documents suggested to use a recent version because of performance
+reasons but more importantly because end of the upstream support periods for
+releases 8.0 and 8.1 was near (November 2010).
+
+Django 1.4 takes that policy further and sets 8.2 as the minimum PostgreSQL
+version it officially supports.
+
+Request exceptions are now always logged
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+When :doc:`logging support </topics/logging/>` was added to Django in 1.3, the
+admin error email support was moved into the
+:class:`django.utils.log.AdminEmailHandler`, attached to the
+``'django.request'`` logger. In order to maintain the established behavior of
+error emails, the ``'django.request'`` logger was called only when
+:setting:`DEBUG` was ``False``.
+
+To increase the flexibility of error logging for requests, the
+``'django.request'`` logger is now called regardless of the value of
+:setting:`DEBUG`, and the default settings file for new projects now includes a
+separate filter attached to :class:`django.utils.log.AdminEmailHandler` to
+prevent admin error emails in ``DEBUG`` mode::
+
+   'filters': {
+        'require_debug_false': {
+            '()': 'django.utils.log.RequireDebugFalse'
+        }
+    },
+    'handlers': {
+        'mail_admins': {
+            'level': 'ERROR',
+            'filters': ['require_debug_false'],
+            'class': 'django.utils.log.AdminEmailHandler'
+        }
+    },
+
+If your project was created prior to this change, your :setting:`LOGGING`
+setting will not include this new filter. In order to maintain
+backwards-compatibility, Django will detect that your ``'mail_admins'`` handler
+configuration includes no ``'filters'`` section, and will automatically add
+this filter for you and issue a pending-deprecation warning. This will become a
+deprecation warning in Django 1.5, and in Django 1.6 the
+backwards-compatibility shim will be removed entirely.
+
+The existence of any ``'filters'`` key under the ``'mail_admins'`` handler will
+disable this backward-compatibility shim and deprecation warning.
+
+``django.conf.urls.defaults``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Until Django 1.3 the functions :func:`~django.conf.urls.include`,
+:func:`~django.conf.urls.patterns` and :func:`~django.conf.urls.url` plus
+:data:`~django.conf.urls.handler404`, :data:`~django.conf.urls.handler500`
+were located in a ``django.conf.urls.defaults`` module.
+
+Starting with Django 1.4 they are now available in :mod:`django.conf.urls`.
+
+``django.contrib.databrowse``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Databrowse has not seen active development for some time, and this does not show
+any sign of changing. There had been a suggestion for a `GSOC project`_ to
+integrate the functionality of databrowse into the admin, but no progress was
+made. While Databrowse has been deprecated, an enhancement of
+``django.contrib.admin`` providing a similar feature set is still possible.
+
+.. _GSOC project: https://code.djangoproject.com/wiki/SummerOfCode2011#Integratedatabrowseintotheadmin
+
+The code that powers Databrowse is licensed under the same terms as Django
+itself, and so is available to be adopted by an individual or group as
+a third-party project.
+
+``django.core.management.setup_environ``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This function temporarily modified ``sys.path`` in order to make the parent
+"project" directory importable under the old flat :djadmin:`startproject`
+layout. This function is now deprecated, as its path workarounds are no longer
+needed with the new ``manage.py`` and default project layout.
+
+This function was never documented or part of the public API, but was widely
+recommended for use in setting up a "Django environment" for a user script.
+These uses should be replaced by setting the ``DJANGO_SETTINGS_MODULE``
+environment variable or using :func:`django.conf.settings.configure`.
+
+``django.core.management.execute_manager``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This function was previously used by ``manage.py`` to execute a management
+command. It is identical to
+``django.core.management.execute_from_command_line``, except that it first
+calls ``setup_environ``, which is now deprecated. As such, ``execute_manager``
+is also deprecated; ``execute_from_command_line`` can be used instead. Neither
+of these functions is documented as part of the public API, but a deprecation
+path is needed due to use in existing ``manage.py`` files.
+
+``is_safe`` and ``needs_autoescape`` attributes of template filters
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Two flags, ``is_safe`` and ``needs_autoescape``, define how each template filter
+interacts with Django's auto-escaping behavior. They used to be attributes of
+the filter function::
+
+    @register.filter
+    def noop(value):
+        return value
+    noop.is_safe = True
+
+However, this technique caused some problems in combination with decorators,
+especially :func:`@stringfilter <django.template.defaultfilters.stringfilter>`.
+Now, the flags are keyword arguments of :meth:`@register.filter
+<django.template.Library.filter>`::
+
+    @register.filter(is_safe=True)
+    def noop(value):
+        return value
+
+See :ref:`filters and auto-escaping <filters-auto-escaping>` for more information.
+
+Session cookies now have the ``httponly`` flag by default
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Session cookies now include the ``httponly`` attribute by default to
+help reduce the impact of potential XSS attacks. For strict backwards
+compatibility, use ``SESSION_COOKIE_HTTPONLY = False`` in your settings file.
+
+Wildcard expansion of application names in `INSTALLED_APPS`
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Until Django 1.3, :setting:`INSTALLED_APPS` accepted wildcards in application
+names, like ``django.contrib.*``. The expansion was performed by a
+filesystem-based implementation of ``from <package> import *``. Unfortunately,
+`this can't be done reliably`_.
+
+This behavior was never documented. Since it is un-pythonic and not obviously
+useful, it was removed in Django 1.4. If you relied on it, you must edit your
+settings file to list all your applications explicitly.
+
+.. _this can't be done reliably: http://docs.python.org/tutorial/modules.html#importing-from-a-package
+
+``HttpRequest.raw_post_data`` renamed to ``HttpRequest.body``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This attribute was confusingly named ``HttpRequest.raw_post_data``, but it
+actually provided the body of the HTTP request. It's been renamed to
+``HttpRequest.body``, and ``HttpRequest.raw_post_data`` has been deprecated.
+
+
+The Django 1.4 roadmap
+======================
+
+Before the final Django 1.4 release, several other preview/development releases
+will be made available. The current schedule consists of at least the following:
+
+* Week of **January 30, 2012**: First Django 1.4 beta release; final
+  feature freeze for Django 1.4.
+
+* Week of **February 27, 2012**: First Django 1.4 release
+  candidate; string freeze for translations.
+
+* Week of **March 5, 2012**: Django 1.4 final release.
+
+If necessary, additional alpha, beta or release-candidate packages
+will be issued prior to the final 1.4 release. Django 1.4 will be
+released approximately one week after the final release candidate.
+
+What you can do to help
+=======================
+
+In order to provide a high-quality 1.4 release, we need your help. Although this
+beta release is, again, *not* intended for production use, you can help the
+Django team by trying out the beta codebase in a safe test environment and
+reporting any bugs or issues you encounter. The Django ticket tracker is the
+central place to search for open issues:
+
+* http://code.djangoproject.com/timeline
+
+Please open new tickets if no existing ticket corresponds to a problem you're
+running into.
+
+Additionally, discussion of Django development, including progress toward the
+1.3 release, takes place daily on the django-developers mailing list:
+
+* http://groups.google.com/group/django-developers
+
+... and in the ``#django-dev`` IRC channel on ``irc.freenode.net``. If you're
+interested in helping out with Django's development, feel free to join the
+discussions there.
+
+Django's online documentation also includes pointers on how to contribute to
+Django:
+
+* :doc:`How to contribute to Django </internals/contributing/index>`
+
+Contributions on any level -- developing code, writing documentation or simply
+triaging tickets and helping to test proposed bugfixes -- are always welcome and
+appreciated.
+
+Several development sprints will also be taking place before the 1.4
+release; these will typically be announced in advance on the
+django-developers mailing list, and anyone who wants to help is
+welcome to join in.
diff --git a/docs/releases/index.txt b/docs/releases/index.txt
index f7b04d4f47..72b6d8bafc 100644
--- a/docs/releases/index.txt
+++ b/docs/releases/index.txt
@@ -81,6 +81,7 @@ notes.
 .. toctree::
    :maxdepth: 1
 
+   1.4-beta-1
    1.4-alpha-1
    1.3-beta-1
    1.3-alpha-1