{"title":"Django 1.2 release notes","version":"dev","locale":"en","docname":"releases/1.2","url":"/en/dev/releases/1.2/","canonical":"https://djangodocs.dev/en/dev/releases/1.2/","summary":"Welcome to Django 1.2! Nearly a year in the making, Django 1.2 packs an impressive list of new features and lots of bug fixes.","html":"<h1>Django 1.2 release notes<a class=\"heading-anchor\" href=\"#django-1-2-release-notes\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h1>\n<p><em>May 17, 2010.</em></p>\n<p>Welcome to Django 1.2!</p>\n<p>Nearly a year in the making, Django 1.2 packs an impressive list of <a class=\"reference internal\" href=\"#whats-new-1-2\"><span class=\"std std-ref\">new\nfeatures</span></a> and lots of bug fixes. These release notes cover\nthe new features, as well as important changes you’ll want to be aware of when\nupgrading from Django 1.1 or older versions.</p>\n<section id=\"overview\">\n<h2>Overview<a class=\"heading-anchor\" href=\"#overview\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Django 1.2 introduces several large, important new features, including:</p>\n<ul class=\"simple\">\n<li><p>Support for <a class=\"reference internal\" href=\"#support-for-multiple-databases\"><span class=\"std std-ref\">multiple database connections</span></a> in a single Django instance.</p></li>\n<li><p><a class=\"reference internal\" href=\"#model-validation\">Model validation</a> inspired by Django’s form validation.</p></li>\n<li><p>Vastly <a class=\"reference internal\" href=\"#improved-csrf-protection\"><span class=\"std std-ref\">improved protection against Cross-Site Request Forgery</span></a> (CSRF).</p></li>\n<li><p>A new <a class=\"reference internal\" href=\"#messages-framework\"><span class=\"std std-ref\">user “messages” framework</span></a> with support for\ncookie- and session-based message for both anonymous and authenticated users.</p></li>\n<li><p>Hooks for <a class=\"reference internal\" href=\"#object-level-permissions\">object-level permissions</a>, <a class=\"reference internal\" href=\"#permissions-for-anonymous-users\">permissions for anonymous users</a>,\nand <a class=\"reference internal\" href=\"#relaxed-requirements-for-usernames\"><span class=\"std std-ref\">more flexible username requirements</span></a>.</p></li>\n<li><p>Customization of email sending via <a class=\"reference internal\" href=\"#email-backends\">email backends</a>.</p></li>\n<li><p>New <a class=\"reference internal\" href=\"#new-in-1-2-smart-if\"><span class=\"std std-ref\">“smart” if template tag</span></a> which supports\ncomparison operators.</p></li>\n</ul>\n<p>These are just the highlights; full details and a complete list of features\n<a class=\"reference internal\" href=\"#whats-new-1-2\"><span class=\"std std-ref\">may be found below</span></a>.</p>\n<aside class=\"admonition admonition-seealso\" role=\"note\">\n<p class=\"admonition-title\">See also</p>\n<p><a class=\"reference external\" href=\"https://github.com/djangoadvent/djangoadvent-articles\">Django Advent</a> covered the release of Django 1.2 with a series of\narticles and tutorials that cover some of the new features in depth.</p>\n</aside>\n<p>Wherever possible these features have been introduced in a backwards-compatible\nmanner per <a class=\"reference internal\" href=\"/en/dev/misc/api-stability/\"><span class=\"doc\">our API stability policy</span></a> policy.</p>\n<p>However, a handful of features <em>have</em> changed in ways that, for some users,\nwill be backwards-incompatible. The big changes are:</p>\n<ul>\n<li><p>Support for Python 2.3 has been dropped. See the full notes\nbelow.</p></li>\n<li><p>The new CSRF protection framework is not backwards-compatible with\nthe old system. Users of the old system will not be affected until\nthe old system is removed in Django 1.4.</p>\n<p>However, upgrading to the new CSRF protection framework requires a few\nimportant backwards-incompatible changes, detailed in <a class=\"reference internal\" href=\"#csrf-protection\">CSRF Protection</a>,\nbelow.</p>\n</li>\n<li><p>Authors of custom <a class=\"reference internal\" href=\"/en/dev/ref/models/fields/#django.db.models.Field\" title=\"django.db.models.Field\"><code class=\"xref py py-class docutils literal notranslate\">Field</code></a> subclasses should be\naware that a number of methods have had a change in prototype, detailed\nunder <a class=\"reference internal\" href=\"#get-db-prep-methods-on-field\">get_db_prep_*() methods on Field</a>, below.</p></li>\n<li><p>The internals of template tags have changed somewhat; authors of custom\ntemplate tags that need to store state (e.g. custom control flow tags)\nshould ensure that their code follows the new rules for <a class=\"reference internal\" href=\"#stateful-template-tags\">stateful template\ntags</a></p></li>\n<li><p>The <a class=\"reference internal\" href=\"/en/dev/topics/auth/default/#django.contrib.auth.decorators.user_passes_test\" title=\"django.contrib.auth.decorators.user_passes_test\"><code class=\"xref py py-func docutils literal notranslate\">user_passes_test()</code></a>,\n<a class=\"reference internal\" href=\"/en/dev/topics/auth/default/#django.contrib.auth.decorators.login_required\" title=\"django.contrib.auth.decorators.login_required\"><code class=\"xref py py-func docutils literal notranslate\">login_required()</code></a>, and\n<a class=\"reference internal\" href=\"/en/dev/topics/auth/default/#django.contrib.auth.decorators.permission_required\" title=\"django.contrib.auth.decorators.permission_required\"><code class=\"xref py py-func docutils literal notranslate\">permission_required()</code></a>, decorators\nfrom <a class=\"reference internal\" href=\"/en/dev/topics/auth/#module-django.contrib.auth\" title=\"django.contrib.auth: Django's authentication framework.\"><code class=\"xref py py-mod docutils literal notranslate\">django.contrib.auth</code></a> only apply to functions and no longer\nwork on methods. There’s a simple one-line fix <a class=\"reference internal\" href=\"#user-passes-test-login-required-permission-required\"><span class=\"std std-ref\">detailed below</span></a>.</p></li>\n</ul>\n<p>Again, these are just the big features that will affect the most users. Users\nupgrading from previous versions of Django are heavily encouraged to consult\nthe complete list of <a class=\"reference internal\" href=\"#backwards-incompatible-changes-1-2\"><span class=\"std std-ref\">backwards-incompatible changes</span></a> and the list of <a class=\"reference internal\" href=\"#deprecated-features-1-2\"><span class=\"std std-ref\">deprecated\nfeatures</span></a>.</p>\n</section>\n<section id=\"python-compatibility\">\n<h2>Python compatibility<a class=\"heading-anchor\" href=\"#python-compatibility\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>While not a new feature, it’s important to note that Django 1.2\nintroduces the first shift in our Python compatibility policy since\nDjango’s initial public debut. Previous Django releases were tested\nand supported on 2.x Python versions from 2.3 up; Django 1.2, however,\ndrops official support for Python 2.3. As such, the minimum Python\nversion required for Django is now 2.4, and Django is tested and\nsupported on Python 2.4, 2.5 and 2.6, and will be supported on the\nas-yet-unreleased Python 2.7.</p>\n<p>This change should affect only a small number of Django users, as most\noperating-system vendors today are shipping Python 2.4 or newer as\ntheir default version. If you’re still using Python 2.3, however,\nyou’ll need to stick to Django 1.1 until you can upgrade; per\n<a class=\"reference internal\" href=\"/en/dev/internals/release-process/\"><span class=\"doc\">our support policy</span></a>, Django 1.1 will\ncontinue to receive security support until the release of Django 1.3.</p>\n<p>A roadmap for Django’s overall 2.x Python support, and eventual\ntransition to Python 3.x, is currently being developed, and will be\nannounced prior to the release of Django 1.3.</p>\n</section>\n<section id=\"what-s-new-in-django-1-2\">\n<span id=\"whats-new-1-2\"></span><h2>What’s new in Django 1.2<a class=\"heading-anchor\" href=\"#what-s-new-in-django-1-2\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<section id=\"support-for-multiple-databases\">\n<span id=\"id1\"></span><h3>Support for multiple databases<a class=\"heading-anchor\" href=\"#support-for-multiple-databases\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Django 1.2 adds the ability to use <a class=\"reference internal\" href=\"/en/dev/topics/db/multi-db/\"><span class=\"doc\">more than one database</span></a> in your Django project. Queries can be issued at a\nspecific database with the <code class=\"docutils literal notranslate\">using()</code> method on <code class=\"docutils literal notranslate\">QuerySet</code> objects.\nIndividual objects can be saved to a specific database by providing a <code class=\"docutils literal notranslate\">using</code>\nargument when you call <code class=\"docutils literal notranslate\">save()</code>.</p>\n</section>\n<section id=\"model-validation\">\n<h3>Model validation<a class=\"heading-anchor\" href=\"#model-validation\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Model instances now have support for <a class=\"reference internal\" href=\"/en/dev/ref/models/instances/#validating-objects\"><span class=\"std std-ref\">validating their own data</span></a>, and both model and form fields now accept configurable\nlists of <a class=\"reference internal\" href=\"/en/dev/ref/validators/\"><span class=\"doc\">validators</span></a> specifying reusable, encapsulated\nvalidation behavior. Note, however, that validation must still be performed\nexplicitly. Simply invoking a model instance’s <code class=\"docutils literal notranslate\">save()</code> method will not\nperform any validation of the instance’s data.</p>\n</section>\n<section id=\"improved-csrf-protection\">\n<span id=\"id2\"></span><h3>Improved CSRF protection<a class=\"heading-anchor\" href=\"#improved-csrf-protection\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Django now has much improved protection against <a class=\"reference internal\" href=\"/en/dev/ref/csrf/\"><span class=\"doc\">Cross-Site Request\nForgery (CSRF) attacks</span></a>. This type of attack occurs when a malicious\nwebsite contains a link, a form button or some JavaScript that is intended to\nperform some action on your website, using the credentials of a logged-in user\nwho visits the malicious site in their browser. A related type of attack,\n“login CSRF,” where an attacking site tricks a user’s browser into logging into\na site with someone else’s credentials, is also covered.</p>\n</section>\n<section id=\"messages-framework\">\n<span id=\"id3\"></span><h3>Messages framework<a class=\"heading-anchor\" href=\"#messages-framework\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Django now includes a robust and configurable <a class=\"reference internal\" href=\"/en/dev/ref/contrib/messages/\"><span class=\"doc\">messages framework</span></a> with built-in support for cookie- and session-based\nmessaging, for both anonymous and authenticated clients. The messages framework\nreplaces the deprecated user message API and allows you to temporarily store\nmessages in one request and retrieve them for display in a subsequent request\n(usually the next one).</p>\n</section>\n<section id=\"object-level-permissions\">\n<h3>Object-level permissions<a class=\"heading-anchor\" href=\"#object-level-permissions\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>A foundation for specifying permissions at the per-object level has been added.\nAlthough there is no implementation of this in core, a custom authentication\nbackend can provide this implementation and it will be used by\n<a class=\"reference internal\" href=\"/en/dev/ref/contrib/auth/#django.contrib.auth.models.User\" title=\"django.contrib.auth.models.User\"><code class=\"xref py py-class docutils literal notranslate\">django.contrib.auth.models.User</code></a>. See the <a class=\"reference internal\" href=\"/en/dev/topics/auth/\"><span class=\"doc\">authentication docs</span></a> for more information.</p>\n</section>\n<section id=\"permissions-for-anonymous-users\">\n<h3>Permissions for anonymous users<a class=\"heading-anchor\" href=\"#permissions-for-anonymous-users\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>If you provide a custom auth backend with <code class=\"docutils literal notranslate\">supports_anonymous_user</code> set to\n<code class=\"docutils literal notranslate\">True</code>, AnonymousUser will check the backend for permissions, just like\nUser already did. This is useful for centralizing permission handling - apps\ncan always delegate the question of whether something is allowed or not to\nthe authorization/authentication backend. See the <a class=\"reference internal\" href=\"/en/dev/topics/auth/\"><span class=\"doc\">authentication\ndocs</span></a> for more details.</p>\n</section>\n<section id=\"relaxed-requirements-for-usernames\">\n<span id=\"id4\"></span><h3>Relaxed requirements for usernames<a class=\"heading-anchor\" href=\"#relaxed-requirements-for-usernames\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>The built-in <a class=\"reference internal\" href=\"/en/dev/ref/contrib/auth/#django.contrib.auth.models.User\" title=\"django.contrib.auth.models.User\"><code class=\"xref py py-class docutils literal notranslate\">User</code></a> model’s\n<a class=\"reference internal\" href=\"/en/dev/ref/contrib/auth/#django.contrib.auth.models.User.username\" title=\"django.contrib.auth.models.User.username\"><code class=\"xref py py-attr docutils literal notranslate\">username</code></a> field now allows a wider\nrange of characters, including <code class=\"docutils literal notranslate\">&#64;</code>, <code class=\"docutils literal notranslate\">+</code>, <code class=\"docutils literal notranslate\">.</code> and <code class=\"docutils literal notranslate\">-</code> characters.</p>\n</section>\n<section id=\"email-backends\">\n<h3>Email backends<a class=\"heading-anchor\" href=\"#email-backends\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>You can now <a class=\"reference internal\" href=\"/en/dev/topics/email/#topic-email-backends\"><span class=\"std std-ref\">configure the way that Django sends email</span></a>. Instead of using SMTP to send all email, you\ncan now choose a configurable email backend to send messages. If your\nhosting provider uses a sandbox or some other non-SMTP technique for\nsending mail, you can now construct an email backend that will allow\nDjango’s standard <a class=\"reference internal\" href=\"/en/dev/topics/email/\"><span class=\"doc\">mail sending methods</span></a> to use\nthose facilities.</p>\n<p>This also makes it easier to debug mail sending. Django ships with\nbackend implementations that allow you to send email to a\n<a class=\"reference internal\" href=\"/en/dev/topics/email/#topic-email-file-backend\"><span class=\"std std-ref\">file</span></a>, to the\n<a class=\"reference internal\" href=\"/en/dev/topics/email/#topic-email-console-backend\"><span class=\"std std-ref\">console</span></a>, or to\n<a class=\"reference internal\" href=\"/en/dev/topics/email/#topic-email-memory-backend\"><span class=\"std std-ref\">memory</span></a>. You can even configure all\nemail to be <a class=\"reference internal\" href=\"/en/dev/topics/email/#topic-email-dummy-backend\"><span class=\"std std-ref\">thrown away</span></a>.</p>\n</section>\n<section id=\"smart-if-tag\">\n<span id=\"new-in-1-2-smart-if\"></span><h3>“Smart” <a class=\"reference internal\" href=\"/en/dev/ref/templates/builtins/#std-templatetag-if\"><code class=\"xref std std-ttag docutils literal notranslate\">if</code></a> tag<a class=\"heading-anchor\" href=\"#smart-if-tag\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>The <a class=\"reference internal\" href=\"/en/dev/ref/templates/builtins/#std-templatetag-if\"><code class=\"xref std std-ttag docutils literal notranslate\">if</code></a> tag has been upgraded to be much more powerful. First, we’ve\nadded support for comparison operators. No longer will you have to type:</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Django template code\"><code><span class=\"cp\">{%</span> <span class=\"k\">ifnotequal</span> <span class=\"nv\">a</span> <span class=\"nv\">b</span> <span class=\"cp\">%}</span>\n ...\n<span class=\"cp\">{%</span> <span class=\"k\">endifnotequal</span> <span class=\"cp\">%}</span>\n</code></pre></div>\n<p>You can now do this:</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Django template code\"><code><span class=\"cp\">{%</span> <span class=\"k\">if</span> <span class=\"nv\">a</span> <span class=\"o\">!=</span> <span class=\"nv\">b</span> <span class=\"cp\">%}</span>\n ...\n<span class=\"cp\">{%</span> <span class=\"k\">endif</span> <span class=\"cp\">%}</span>\n</code></pre></div>\n<p>There’s really no reason to use <code class=\"docutils literal notranslate\">{% ifequal %}</code> or <code class=\"docutils literal notranslate\">{% ifnotequal %}</code>\nanymore, unless you’re the nostalgic type.</p>\n<p>The operators supported are <code class=\"docutils literal notranslate\">==</code>, <code class=\"docutils literal notranslate\">!=</code>, <code class=\"docutils literal notranslate\">&lt;</code>, <code class=\"docutils literal notranslate\">&gt;</code>, <code class=\"docutils literal notranslate\">&lt;=</code>, <code class=\"docutils literal notranslate\">&gt;=</code>,\n<code class=\"docutils literal notranslate\">in</code> and <code class=\"docutils literal notranslate\">not in</code>, all of which work like the Python operators, in addition\nto <code class=\"docutils literal notranslate\">and</code>, <code class=\"docutils literal notranslate\">or</code> and <code class=\"docutils literal notranslate\">not</code>, which were already supported.</p>\n<p>Also, filters may now be used in the <code class=\"docutils literal notranslate\">if</code> expression. For example:</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Django template code\"><code><span class=\"p\">&lt;</span><span class=\"nt\">div</span>\n  <span class=\"cp\">{%</span> <span class=\"k\">if</span> <span class=\"nv\">user.email</span><span class=\"o\">|</span><span class=\"nf\">lower</span> <span class=\"o\">==</span> <span class=\"nv\">message.recipient</span><span class=\"o\">|</span><span class=\"nf\">lower</span> <span class=\"cp\">%}</span>\n    <span class=\"na\">class</span><span class=\"o\">=</span><span class=\"s\">&quot;highlight&quot;</span>\n  <span class=\"cp\">{%</span> <span class=\"k\">endif</span> <span class=\"cp\">%}</span>\n<span class=\"p\">&gt;</span><span class=\"cp\">{{</span> <span class=\"nv\">message</span> <span class=\"cp\">}}</span><span class=\"p\">&lt;/</span><span class=\"nt\">div</span><span class=\"p\">&gt;</span>\n</code></pre></div>\n</section>\n<section id=\"template-caching\">\n<h3>Template caching<a class=\"heading-anchor\" href=\"#template-caching\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>In previous versions of Django, every time you rendered a template, it\nwould be reloaded from disk. In Django 1.2, you can use a <a class=\"reference internal\" href=\"/en/dev/ref/templates/api/#template-loaders\"><span class=\"std std-ref\">cached\ntemplate loader</span></a> to load templates once, then\ncache the result for every subsequent render. This can lead to a\nsignificant performance improvement if your templates are broken into\nlots of smaller subtemplates (using the <code class=\"docutils literal notranslate\">{% extends %}</code> or <code class=\"docutils literal notranslate\">{%\ninclude %}</code> tags).</p>\n<p>As a side effect, it is now much easier to support non-Django template\nlanguages.</p>\n</section>\n<section id=\"class-based-template-loaders\">\n<h3>Class-based template loaders<a class=\"heading-anchor\" href=\"#class-based-template-loaders\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>As part of the changes made to introduce <a class=\"reference internal\" href=\"#template-caching\">Template caching</a>  and following\na general trend in Django, the template loaders API has been modified\nto use template loading mechanisms that are encapsulated in Python classes as\nopposed to functions, the only method available until Django 1.1.</p>\n<p>All the template loaders <a class=\"reference internal\" href=\"/en/dev/ref/templates/api/#template-loaders\"><span class=\"std std-ref\">shipped with Django</span></a> have\nbeen ported to the new API but they still implement the function-based API and\nthe template core machinery still accepts function-based loaders (builtin or\nthird party) so there is no immediate need to modify your <code class=\"docutils literal notranslate\">TEMPLATE_LOADERS</code>\nsetting in existing projects, things will keep working if you leave it\nuntouched up to and including the Django 1.3 release.</p>\n<p>If you have developed your own custom template loaders we suggest to consider\nporting them to a class-based implementation because the code for backwards\ncompatibility with function-based loaders starts its deprecation process in\nDjango 1.2 and will be removed in Django 1.4. There is a description of the\nAPI these loader classes must implement in the template API reference and you\ncan also examine the source code of the loaders shipped with Django.</p>\n</section>\n<section id=\"natural-keys-in-fixtures\">\n<h3>Natural keys in fixtures<a class=\"heading-anchor\" href=\"#natural-keys-in-fixtures\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Fixtures can now refer to remote objects using\n<a class=\"reference internal\" href=\"/en/dev/topics/serialization/#topics-serialization-natural-keys\"><span class=\"std std-ref\">Natural keys</span></a>. This lookup scheme is an\nalternative to the normal primary-key based object references in a\nfixture, improving readability and resolving problems referring to\nobjects whose primary key value may not be predictable or known.</p>\n</section>\n<section id=\"fast-failure-for-tests\">\n<h3>Fast failure for tests<a class=\"heading-anchor\" href=\"#fast-failure-for-tests\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Both the <a class=\"reference internal\" href=\"/en/dev/ref/django-admin/#django-admin-test\"><code class=\"xref std std-djadmin docutils literal notranslate\">test</code></a> subcommand of <code class=\"docutils literal notranslate\">django-admin.py</code> and the\n<code class=\"docutils literal notranslate\">runtests.py</code> script used to run Django’s own test suite now support a\n<code class=\"docutils literal notranslate\">--failfast</code> option. When specified, this option causes the test runner to\nexit after encountering a failure instead of continuing with the test run. In\naddition, the handling of <code class=\"docutils literal notranslate\">Ctrl-C</code> during a test run has been improved to\ntrigger a graceful exit from the test run that reports details of the tests\nthat were run before the interruption.</p>\n</section>\n<section id=\"bigintegerfield\">\n<h3><code class=\"docutils literal notranslate\">BigIntegerField</code><a class=\"heading-anchor\" href=\"#bigintegerfield\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Models can now use a 64-bit <a class=\"reference internal\" href=\"/en/dev/ref/models/fields/#django.db.models.BigIntegerField\" title=\"django.db.models.BigIntegerField\"><code class=\"xref py py-class docutils literal notranslate\">BigIntegerField</code></a> type.</p>\n</section>\n<section id=\"improved-localization\">\n<h3>Improved localization<a class=\"heading-anchor\" href=\"#improved-localization\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Django’s <a class=\"reference internal\" href=\"/en/dev/topics/i18n/\"><span class=\"doc\">internationalization framework</span></a> has been\nexpanded with locale-aware formatting and form processing. That means, if\nenabled, dates and numbers on templates will be displayed using the format\nspecified for the current locale. Django will also use localized formats when\nparsing data in forms. See <a class=\"reference internal\" href=\"/en/dev/topics/i18n/formatting/\"><span class=\"doc\">Format localization</span></a> for more details.</p>\n</section>\n<section id=\"readonly-fields-in-modeladmin\">\n<h3><code class=\"docutils literal notranslate\">readonly_fields</code> in <code class=\"docutils literal notranslate\">ModelAdmin</code><a class=\"heading-anchor\" href=\"#readonly-fields-in-modeladmin\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p><a class=\"reference internal\" href=\"/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.readonly_fields\" title=\"django.contrib.admin.ModelAdmin.readonly_fields\"><code class=\"xref py py-attr docutils literal notranslate\">django.contrib.admin.ModelAdmin.readonly_fields</code></a> has been added to\nenable non-editable fields in add/change pages for models and inlines. Field\nand calculated values can be displayed alongside editable fields.</p>\n</section>\n<section id=\"customizable-syntax-highlighting\">\n<h3>Customizable syntax highlighting<a class=\"heading-anchor\" href=\"#customizable-syntax-highlighting\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>You can now use a <span class=\"target\" id=\"index-0\"></span><a class=\"reference internal\" href=\"/en/dev/ref/django-admin/#envvar-DJANGO_COLORS\"><code class=\"xref std std-envvar docutils literal notranslate\">DJANGO_COLORS</code></a> environment variable to modify or\ndisable the colors used by <code class=\"docutils literal notranslate\">django-admin.py</code> to provide <a class=\"reference internal\" href=\"/en/dev/ref/django-admin/#syntax-coloring\"><span class=\"std std-ref\">syntax\nhighlighting</span></a>.</p>\n</section>\n<section id=\"syndication-feeds-as-views\">\n<h3>Syndication feeds as views<a class=\"heading-anchor\" href=\"#syndication-feeds-as-views\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p><a class=\"reference internal\" href=\"/en/dev/ref/contrib/syndication/\"><span class=\"doc\">Syndication feeds</span></a> can now be used directly as\nviews in your <a class=\"reference internal\" href=\"/en/dev/topics/http/urls/\"><span class=\"doc\">URLconf</span></a>. This means that you can\nmaintain complete control over the URL structure of your feeds. Like any other\nview, feeds views are passed a <code class=\"docutils literal notranslate\">request</code> object, so you can do anything you\nwould normally do with a view, like user based access control, or making a feed\na named URL.</p>\n</section>\n<section id=\"geodjango\">\n<h3>GeoDjango<a class=\"heading-anchor\" href=\"#geodjango\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>The most significant new feature for <a class=\"reference internal\" href=\"/en/dev/ref/contrib/gis/\"><span class=\"doc\">GeoDjango</span></a>\nin 1.2 is support for multiple spatial databases. As a result,\nthe following <a class=\"reference internal\" href=\"/en/dev/ref/contrib/gis/db-api/#spatial-backends\"><span class=\"std std-ref\">spatial database backends</span></a>\nare now included:</p>\n<ul class=\"simple\">\n<li><p><code class=\"docutils literal notranslate\">django.contrib.gis.db.backends.postgis</code></p></li>\n<li><p><code class=\"docutils literal notranslate\">django.contrib.gis.db.backends.mysql</code></p></li>\n<li><p><code class=\"docutils literal notranslate\">django.contrib.gis.db.backends.oracle</code></p></li>\n<li><p><code class=\"docutils literal notranslate\">django.contrib.gis.db.backends.spatialite</code></p></li>\n</ul>\n<p>GeoDjango now supports the rich capabilities added in the PostGIS 1.5 release.\nNew features include support for the <a class=\"reference internal\" href=\"/en/dev/ref/contrib/gis/model-api/#geography-type\"><span class=\"std std-ref\">geography type</span></a>\nand enabling of <a class=\"reference internal\" href=\"/en/dev/ref/contrib/gis/db-api/#distance-queries\"><span class=\"std std-ref\">distance queries</span></a>\nwith non-point geometries on geographic coordinate systems.</p>\n<p>Support for 3D geometry fields was added, and may be enabled\nby setting the <a class=\"reference internal\" href=\"/en/dev/ref/contrib/gis/model-api/#django.contrib.gis.db.models.GeometryField.dim\" title=\"django.contrib.gis.db.models.GeometryField.dim\"><code class=\"xref py py-attr docutils literal notranslate\">dim</code></a>\nkeyword to 3 in your <a class=\"reference internal\" href=\"/en/dev/ref/contrib/gis/model-api/#django.contrib.gis.db.models.GeometryField\" title=\"django.contrib.gis.db.models.GeometryField\"><code class=\"xref py py-class docutils literal notranslate\">GeometryField</code></a>.\nThe <a class=\"reference internal\" href=\"/en/dev/ref/contrib/gis/geoquerysets/#django.contrib.gis.db.models.Extent3D\" title=\"django.contrib.gis.db.models.Extent3D\"><code class=\"xref py py-class docutils literal notranslate\">Extent3D</code></a> aggregate\nand <code class=\"docutils literal notranslate\">extent3d()</code> <code class=\"docutils literal notranslate\">GeoQuerySet</code> method were added as a part of this feature.</p>\n<p>The <code class=\"docutils literal notranslate\">force_rhr()</code>, <code class=\"docutils literal notranslate\">reverse_geom()</code>, and <code class=\"docutils literal notranslate\">geohash()</code> <code class=\"docutils literal notranslate\">GeoQuerySet</code>\nmethods are new.</p>\n<p>The GEOS interface was updated to use thread-safe C library functions when\navailable on the platform.</p>\n<p>The GDAL interface now allows the user to set a\n<a class=\"reference internal\" href=\"/en/dev/ref/contrib/gis/gdal/#django.contrib.gis.gdal.Layer.spatial_filter\" title=\"django.contrib.gis.gdal.Layer.spatial_filter\"><code class=\"xref py py-attr docutils literal notranslate\">spatial_filter</code></a> on the features returned\nwhen iterating over a <a class=\"reference internal\" href=\"/en/dev/ref/contrib/gis/gdal/#django.contrib.gis.gdal.Layer\" title=\"django.contrib.gis.gdal.Layer\"><code class=\"xref py py-class docutils literal notranslate\">Layer</code></a>.</p>\n<p>Finally, <a class=\"reference internal\" href=\"/en/dev/ref/contrib/gis/\"><span class=\"doc\">GeoDjango’s documentation</span></a> is now\nincluded with Django’s and is no longer hosted separately at <code class=\"docutils literal notranslate\">geodjango.org</code>.</p>\n</section>\n<section id=\"javascript-assisted-handling-of-inline-related-objects-in-the-admin\">\n<span id=\"js-assisted-inlines\"></span><h3>JavaScript-assisted handling of inline related objects in the admin<a class=\"heading-anchor\" href=\"#javascript-assisted-handling-of-inline-related-objects-in-the-admin\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>If a user has JavaScript enabled in their browser, the interface for\ninline objects in the admin now allows inline objects to be\ndynamically added and removed. Users without JavaScript-enabled\nbrowsers will see no change in the behavior of inline objects.</p>\n</section>\n<section id=\"new-now-template-tag-format-specifier-characters-c-and-u\">\n<h3>New <code class=\"docutils literal notranslate\">now</code> template tag format specifier characters: <code class=\"docutils literal notranslate\">c</code> and <code class=\"docutils literal notranslate\">u</code><a class=\"heading-anchor\" href=\"#new-now-template-tag-format-specifier-characters-c-and-u\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>The argument to the <a class=\"reference internal\" href=\"/en/dev/ref/templates/builtins/#std-templatetag-now\"><code class=\"xref std std-ttag docutils literal notranslate\">now</code></a> has gained two new format characters:\n<code class=\"docutils literal notranslate\">c</code> to specify that a datetime value should be formatted in ISO 8601\nformat, and <code class=\"docutils literal notranslate\">u</code> that allows output of the microseconds part of a\ndatetime or time value.</p>\n<p>These are also available in others parts like the <a class=\"reference internal\" href=\"/en/dev/ref/templates/builtins/#std-templatefilter-date\"><code class=\"xref std std-tfilter docutils literal notranslate\">date</code></a> and\n<a class=\"reference internal\" href=\"/en/dev/ref/templates/builtins/#std-templatefilter-time\"><code class=\"xref std std-tfilter docutils literal notranslate\">time</code></a> template filters, the <code class=\"docutils literal notranslate\">humanize</code> template tag library\nand the new <a class=\"reference internal\" href=\"#improved-localization\">format localization</a> framework.</p>\n</section>\n</section>\n<section id=\"backwards-incompatible-changes-in-1-2\">\n<span id=\"backwards-incompatible-changes-1-2\"></span><h2>Backwards-incompatible changes in 1.2<a class=\"heading-anchor\" href=\"#backwards-incompatible-changes-in-1-2\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Wherever possible the new features above have been introduced in a\nbackwards-compatible manner per <a class=\"reference internal\" href=\"/en/dev/misc/api-stability/\"><span class=\"doc\">our API stability policy</span></a> policy. This means that practically all existing\ncode which worked with Django 1.1 will continue to work with Django\n1.2; such code will, however, begin issuing warnings (see below for\ndetails).</p>\n<p>However, a handful of features <em>have</em> changed in ways that, for some\nusers, will be immediately backwards-incompatible. Those changes are\ndetailed below.</p>\n<section id=\"csrf-protection\">\n<h3>CSRF Protection<a class=\"heading-anchor\" href=\"#csrf-protection\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>We’ve made large changes to the way CSRF protection works, detailed in\n<a class=\"reference internal\" href=\"/en/dev/ref/csrf/\"><span class=\"doc\">the CSRF documentation</span></a>. Here are the major changes you\nshould be aware of:</p>\n<ul>\n<li><p><code class=\"docutils literal notranslate\">CsrfResponseMiddleware</code> and <code class=\"docutils literal notranslate\">CsrfMiddleware</code> have been deprecated and\nwill be removed completely in Django 1.4, in favor of a template tag that\nshould be inserted into forms.</p></li>\n<li><p>All contrib apps use a <code class=\"docutils literal notranslate\">csrf_protect</code> decorator to protect the view. This\nrequires the use of the <code class=\"docutils literal notranslate\">csrf_token</code> template tag in the template. If you\nhave used custom templates for contrib views, you MUST READ THE UPGRADE\nINSTRUCTIONS to fix those templates.</p>\n<aside class=\"admonition-documentation-removed admonition\" role=\"note\">\n<p class=\"admonition-title\">Documentation removed</p>\n<p>The upgrade notes have been removed in current Django docs. Please refer\nto the docs for Django 1.3 or older to find these instructions.</p>\n</aside>\n</li>\n<li><p><code class=\"docutils literal notranslate\">CsrfViewMiddleware</code> is included in <code class=\"docutils literal notranslate\">MIDDLEWARE_CLASSES</code> by\ndefault. This turns on CSRF protection by default, so views that accept\nPOST requests need to be written to work with the middleware. Instructions\non how to do this are found in the CSRF docs.</p></li>\n<li><p>All of the CSRF has moved from contrib to core (with backwards\ncompatible imports in the old locations, which are deprecated and\nwill cease to be supported in Django 1.4).</p></li>\n</ul>\n</section>\n<section id=\"get-db-prep-methods-on-field\">\n<h3><code class=\"docutils literal notranslate\">get_db_prep_*()</code> methods on <code class=\"docutils literal notranslate\">Field</code><a class=\"heading-anchor\" href=\"#get-db-prep-methods-on-field\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Prior to Django 1.2, a custom <code class=\"docutils literal notranslate\">Field</code> had the option of defining\nseveral functions to support conversion of Python values into\ndatabase-compatible values. A custom field might look something like:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">class</span> <span class=\"nc\">CustomModelField</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Field<span class=\"p\">):</span>\n    <span class=\"o\">...</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">db_type</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span> <span class=\"o\">...</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">get_db_prep_save</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> value<span class=\"p\">):</span> <span class=\"o\">...</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">get_db_prep_value</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> value<span class=\"p\">):</span> <span class=\"o\">...</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">get_db_prep_lookup</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> lookup_type<span class=\"p\">,</span> value<span class=\"p\">):</span> <span class=\"o\">...</span>\n</code></pre></div>\n<p>In 1.2, these three methods have undergone a change in prototype, and\ntwo extra methods have been introduced:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">class</span> <span class=\"nc\">CustomModelField</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Field<span class=\"p\">):</span>\n    <span class=\"o\">...</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">db_type</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> connection<span class=\"p\">):</span> <span class=\"o\">...</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">get_prep_value</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> value<span class=\"p\">):</span> <span class=\"o\">...</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">get_prep_lookup</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> lookup_type<span class=\"p\">,</span> value<span class=\"p\">):</span> <span class=\"o\">...</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">get_db_prep_save</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> value<span class=\"p\">,</span> connection<span class=\"p\">):</span> <span class=\"o\">...</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">get_db_prep_value</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> value<span class=\"p\">,</span> connection<span class=\"p\">,</span> prepared<span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">):</span> <span class=\"o\">...</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">get_db_prep_lookup</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> lookup_type<span class=\"p\">,</span> value<span class=\"p\">,</span> connection<span class=\"p\">,</span> prepared<span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">):</span> <span class=\"o\">...</span>\n</code></pre></div>\n<p>These changes are required to support multiple databases –\n<code class=\"docutils literal notranslate\">db_type</code> and <code class=\"docutils literal notranslate\">get_db_prep_*</code> can no longer make any assumptions\nregarding the database for which it is preparing. The <code class=\"docutils literal notranslate\">connection</code>\nargument now provides the preparation methods with the specific\nconnection for which the value is being prepared.</p>\n<p>The two new methods exist to differentiate general data-preparation\nrequirements from requirements that are database-specific. The\n<code class=\"docutils literal notranslate\">prepared</code> argument is used to indicate to the database-preparation\nmethods whether generic value preparation has been performed. If\nan unprepared (i.e., <code class=\"docutils literal notranslate\">prepared=False</code>) value is provided to the\n<code class=\"docutils literal notranslate\">get_db_prep_*()</code> calls, they should invoke the corresponding\n<code class=\"docutils literal notranslate\">get_prep_*()</code> calls to perform generic data preparation.</p>\n<p>We’ve provided conversion functions that will transparently\nconvert functions adhering to the old prototype into functions\ncompatible with the new prototype. However, these conversion functions\nwill be removed in Django 1.4, so you should upgrade your <code class=\"docutils literal notranslate\">Field</code>\ndefinitions to use the new prototype as soon as possible.</p>\n<p>If your <code class=\"docutils literal notranslate\">get_db_prep_*()</code> methods made no use of the database\nconnection, you should be able to upgrade by renaming\n<code class=\"docutils literal notranslate\">get_db_prep_value()</code> to <code class=\"docutils literal notranslate\">get_prep_value()</code> and\n<code class=\"docutils literal notranslate\">get_db_prep_lookup()</code> to <code class=\"docutils literal notranslate\">get_prep_lookup()</code>. If you require\ndatabase specific conversions, then you will need to provide an\nimplementation <code class=\"docutils literal notranslate\">get_db_prep_*</code> that uses the <code class=\"docutils literal notranslate\">connection</code>\nargument to resolve database-specific values.</p>\n</section>\n<section id=\"stateful-template-tags\">\n<h3>Stateful template tags<a class=\"heading-anchor\" href=\"#stateful-template-tags\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Template tags that store rendering state on their <code class=\"docutils literal notranslate\">Node</code> subclass\nhave always been vulnerable to thread-safety and other issues; as of\nDjango 1.2, however, they may also cause problems when used with the\nnew <a class=\"reference internal\" href=\"/en/dev/ref/templates/api/#template-loaders\"><span class=\"std std-ref\">cached template loader</span></a>.</p>\n<p>All of the built-in Django template tags are safe to use with the cached\nloader, but if you’re using custom template tags that come from third\nparty packages, or from your own code, you should ensure that the\n<code class=\"docutils literal notranslate\">Node</code> implementation for each tag is thread-safe. For more\ninformation, see\n<a class=\"reference internal\" href=\"/en/dev/howto/custom-template-tags/#template-tag-thread-safety\"><span class=\"std std-ref\">template tag thread safety considerations</span></a>.</p>\n<p>You may also need to update your templates if you were relying on the\nimplementation of Django’s template tags <em>not</em> being thread safe. The\n<a class=\"reference internal\" href=\"/en/dev/ref/templates/builtins/#std-templatetag-cycle\"><code class=\"xref std std-ttag docutils literal notranslate\">cycle</code></a> tag is the most likely to be affected in this way,\nespecially when used in conjunction with the <a class=\"reference internal\" href=\"/en/dev/ref/templates/builtins/#std-templatetag-include\"><code class=\"xref std std-ttag docutils literal notranslate\">include</code></a> tag.\nConsider the following template fragment:</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Django template code\"><code><span class=\"cp\">{%</span> <span class=\"k\">for</span> <span class=\"nv\">object</span> <span class=\"k\">in</span> <span class=\"nv\">object_list</span> <span class=\"cp\">%}</span>\n    <span class=\"cp\">{%</span> <span class=\"k\">include</span> <span class=\"s2\">&quot;subtemplate.html&quot;</span> <span class=\"cp\">%}</span>\n<span class=\"cp\">{%</span> <span class=\"k\">endfor</span> <span class=\"cp\">%}</span>\n</code></pre></div>\n<p>with a <code class=\"docutils literal notranslate\">subtemplate.html</code> that reads:</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Django template code\"><code><span class=\"cp\">{%</span> <span class=\"k\">cycle</span> <span class=\"s1\">&#39;even&#39;</span> <span class=\"s1\">&#39;odd&#39;</span> <span class=\"cp\">%}</span>\n</code></pre></div>\n<p>Using the non-thread-safe, pre-Django 1.2 renderer, this would output:</p>\n<div class=\"code-block\" data-language=\"text\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Text</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Text code\"><code>even odd even odd ...\n</code></pre></div>\n<p>Using the thread-safe Django 1.2 renderer, you will instead get:</p>\n<div class=\"code-block\" data-language=\"text\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Text</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Text code\"><code>even even even even ...\n</code></pre></div>\n<p>This is because each rendering of the <a class=\"reference internal\" href=\"/en/dev/ref/templates/builtins/#std-templatetag-include\"><code class=\"xref std std-ttag docutils literal notranslate\">include</code></a> tag is an\nindependent rendering. When the <a class=\"reference internal\" href=\"/en/dev/ref/templates/builtins/#std-templatetag-cycle\"><code class=\"xref std std-ttag docutils literal notranslate\">cycle</code></a> tag was not thread safe,\nthe state of the <a class=\"reference internal\" href=\"/en/dev/ref/templates/builtins/#std-templatetag-cycle\"><code class=\"xref std std-ttag docutils literal notranslate\">cycle</code></a> tag would leak between multiple\nrenderings of the same <a class=\"reference internal\" href=\"/en/dev/ref/templates/builtins/#std-templatetag-include\"><code class=\"xref std std-ttag docutils literal notranslate\">include</code></a>. Now that the <a class=\"reference internal\" href=\"/en/dev/ref/templates/builtins/#std-templatetag-cycle\"><code class=\"xref std std-ttag docutils literal notranslate\">cycle</code></a> tag\nis thread safe, this leakage no longer occurs.</p>\n</section>\n<section id=\"user-passes-test-login-required-and-permission-required\">\n<span id=\"user-passes-test-login-required-permission-required\"></span><h3><code class=\"docutils literal notranslate\">user_passes_test</code>, <code class=\"docutils literal notranslate\">login_required</code> and <code class=\"docutils literal notranslate\">permission_required</code><a class=\"heading-anchor\" href=\"#user-passes-test-login-required-and-permission-required\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p><code class=\"docutils literal notranslate\">django.contrib.auth.decorators</code> provides the decorators\n<code class=\"docutils literal notranslate\">login_required</code>, <code class=\"docutils literal notranslate\">permission_required</code> and\n<code class=\"docutils literal notranslate\">user_passes_test</code>. Previously it was possible to use these\ndecorators both on functions (where the first argument is ‘request’)\nand on methods (where the first argument is ‘self’, and the second\nargument is ‘request’). Unfortunately, flaws were discovered in the\ncode supporting this: it only works in limited circumstances, and\nproduces errors that are very difficult to debug when it does not\nwork.</p>\n<p>For this reason, the ‘auto adapt’ behavior has been removed, and if\nyou are using these decorators on methods, you will need to manually\napply <a class=\"reference internal\" href=\"/en/dev/ref/utils/#django.utils.decorators.method_decorator\" title=\"django.utils.decorators.method_decorator\"><code class=\"xref py py-func docutils literal notranslate\">django.utils.decorators.method_decorator()</code></a> to convert the\ndecorator to one that works with methods. For example, you would\nchange code from this:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">class</span> <span class=\"nc\">MyClass</span><span class=\"p\">(</span><span class=\"nb\">object</span><span class=\"p\">):</span>\n    <span class=\"nd\">@login_required</span>\n    <span class=\"k\">def</span> <span class=\"nf\">my_view</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> request<span class=\"p\">):</span>\n        <span class=\"k\">pass</span>\n</code></pre></div>\n<p>to this:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span> <span class=\"nn\">django.utils.decorators</span> <span class=\"kn\">import</span> method_decorator\n\n\n<span class=\"k\">class</span> <span class=\"nc\">MyClass</span><span class=\"p\">(</span><span class=\"nb\">object</span><span class=\"p\">):</span>\n    <span class=\"nd\">@method_decorator</span><span class=\"p\">(</span>login_required<span class=\"p\">)</span>\n    <span class=\"k\">def</span> <span class=\"nf\">my_view</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> request<span class=\"p\">):</span>\n        <span class=\"k\">pass</span>\n</code></pre></div>\n<p>or:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span> <span class=\"nn\">django.utils.decorators</span> <span class=\"kn\">import</span> method_decorator\n\nlogin_required_m <span class=\"o\">=</span> method_decorator<span class=\"p\">(</span>login_required<span class=\"p\">)</span>\n\n\n<span class=\"k\">class</span> <span class=\"nc\">MyClass</span><span class=\"p\">(</span><span class=\"nb\">object</span><span class=\"p\">):</span>\n    <span class=\"nd\">@login_required_m</span>\n    <span class=\"k\">def</span> <span class=\"nf\">my_view</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> request<span class=\"p\">):</span>\n        <span class=\"k\">pass</span>\n</code></pre></div>\n<p>For those of you who’ve been following the development trunk, this\nchange also applies to other decorators introduced since 1.1,\nincluding <code class=\"docutils literal notranslate\">csrf_protect</code>, <code class=\"docutils literal notranslate\">cache_control</code> and anything created\nusing <code class=\"docutils literal notranslate\">decorator_from_middleware</code>.</p>\n</section>\n<section id=\"if-tag-changes\">\n<h3><a class=\"reference internal\" href=\"/en/dev/ref/templates/builtins/#std-templatetag-if\"><code class=\"xref std std-ttag docutils literal notranslate\">if</code></a> tag changes<a class=\"heading-anchor\" href=\"#if-tag-changes\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Due to new features in the <a class=\"reference internal\" href=\"/en/dev/ref/templates/builtins/#std-templatetag-if\"><code class=\"xref std std-ttag docutils literal notranslate\">if</code></a> template tag, it no longer\naccepts ‘and’, ‘or’ and ‘not’ as valid <strong>variable</strong> names. Previously,\nthese strings could be used as variable names. Now, the keyword status\nis always enforced, and template code such as <code class=\"docutils literal notranslate\">{% if not %}</code> or <code class=\"docutils literal notranslate\">{%\nif and %}</code> will throw a <code class=\"docutils literal notranslate\">TemplateSyntaxError</code>. Also, <code class=\"docutils literal notranslate\">in</code> is a\nnew keyword and so is not a valid variable name in this tag.</p>\n</section>\n<section id=\"lazyobject\">\n<h3><code class=\"docutils literal notranslate\">LazyObject</code><a class=\"heading-anchor\" href=\"#lazyobject\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p><code class=\"docutils literal notranslate\">LazyObject</code> is an undocumented-but-often-used utility class used for lazily\nwrapping other objects of unknown type.</p>\n<p>In Django 1.1 and earlier, it handled introspection in a non-standard way,\ndepending on wrapped objects implementing a public method named\n<code class=\"docutils literal notranslate\">get_all_members()</code>. Since this could easily lead to name clashes, it has\nbeen changed to use the standard Python introspection method, involving\n<code class=\"docutils literal notranslate\">__members__</code> and <code class=\"docutils literal notranslate\">__dir__()</code>.</p>\n<p>If you used <code class=\"docutils literal notranslate\">LazyObject</code> in your own code\nand implemented the <code class=\"docutils literal notranslate\">get_all_members()</code> method for wrapped objects, you’ll\nneed to make a couple of changes:</p>\n<p>First, if your class does not have special requirements for introspection\n(i.e., you have not implemented <code class=\"docutils literal notranslate\">__getattr__()</code> or other methods that allow\nfor attributes not discoverable by normal mechanisms), you can simply remove\nthe <code class=\"docutils literal notranslate\">get_all_members()</code> method. The default implementation on <code class=\"docutils literal notranslate\">LazyObject</code>\nwill do the right thing.</p>\n<p>If you have more complex requirements for introspection, first rename the\n<code class=\"docutils literal notranslate\">get_all_members()</code> method to <code class=\"docutils literal notranslate\">__dir__()</code>. This is the standard\nintrospection method for Python 2.6 and above. If you require support for\nPython versions earlier than 2.6, add the following code to the class:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>__members__ <span class=\"o\">=</span> <span class=\"nb\">property</span><span class=\"p\">(</span><span class=\"k\">lambda</span> <span class=\"bp\">self</span><span class=\"p\">:</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"fm\">__dir__</span><span class=\"p\">())</span>\n</code></pre></div>\n</section>\n<section id=\"dict-on-model-instances\">\n<h3><code class=\"docutils literal notranslate\">__dict__</code> on model instances<a class=\"heading-anchor\" href=\"#dict-on-model-instances\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Historically, the <code class=\"docutils literal notranslate\">__dict__</code> attribute of a model instance has only contained\nattributes corresponding to the fields on a model.</p>\n<p>In order to support multiple database configurations, Django 1.2 has\nadded a <code class=\"docutils literal notranslate\">_state</code> attribute to object instances. This attribute will\nappear in <code class=\"docutils literal notranslate\">__dict__</code> for a model instance. If your code relies on\niterating over <code class=\"docutils literal notranslate\">__dict__</code> to obtain a list of fields, you must now\nbe prepared to handle or filter out the <code class=\"docutils literal notranslate\">_state</code> attribute.</p>\n</section>\n<section id=\"test-runner-exit-status-code\">\n<h3>Test runner exit status code<a class=\"heading-anchor\" href=\"#test-runner-exit-status-code\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>The exit status code of the test runners (<code class=\"docutils literal notranslate\">tests/runtests.py</code> and <code class=\"docutils literal notranslate\">python\nmanage.py test</code>) no longer represents the number of failed tests, because a\nfailure of 256 or more tests resulted in a wrong exit status code. The exit\nstatus code for the test runner is now 0 for success (no failing tests) and 1\nfor any number of test failures. If needed, the number of test failures can be\nfound at the end of the test runner’s output.</p>\n</section>\n<section id=\"cookie-encoding\">\n<h3>Cookie encoding<a class=\"heading-anchor\" href=\"#cookie-encoding\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>To fix bugs with cookies in Internet Explorer, Safari, and possibly\nother browsers, our encoding of cookie values was changed so that the\ncomma and semicolon are treated as non-safe characters, and are\ntherefore encoded as <code class=\"docutils literal notranslate\">\\054</code> and <code class=\"docutils literal notranslate\">\\073</code> respectively. This could\nproduce backwards incompatibilities, especially if you are storing\ncomma or semi-colon in cookies and have JavaScript code that parses\nand manipulates cookie values client-side.</p>\n</section>\n<section id=\"modelform-is-valid-and-modelform-errors\">\n<h3><code class=\"docutils literal notranslate\">ModelForm.is_valid()</code> and <code class=\"docutils literal notranslate\">ModelForm.errors</code><a class=\"heading-anchor\" href=\"#modelform-is-valid-and-modelform-errors\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Much of the validation work for ModelForms has been moved down to the model\nlevel. As a result, the first time you call <code class=\"docutils literal notranslate\">ModelForm.is_valid()</code>, access\n<code class=\"docutils literal notranslate\">ModelForm.errors</code> or otherwise trigger form validation, your model will be\ncleaned in-place. This conversion used to happen when the model was saved. If\nyou need an unmodified instance of your model, you should pass a copy to the\n<code class=\"docutils literal notranslate\">ModelForm</code> constructor.</p>\n</section>\n<section id=\"booleanfield-on-mysql\">\n<h3><code class=\"docutils literal notranslate\">BooleanField</code> on MySQL<a class=\"heading-anchor\" href=\"#booleanfield-on-mysql\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>In previous versions of Django, a model’s <code class=\"docutils literal notranslate\">BooleanField</code> under MySQL\nwould return its value as either <code class=\"docutils literal notranslate\">1</code> or <code class=\"docutils literal notranslate\">0</code>, instead of <code class=\"docutils literal notranslate\">True</code>\nor <code class=\"docutils literal notranslate\">False</code>; for most people this wasn’t a problem because <code class=\"docutils literal notranslate\">bool</code>\nis a subclass of <code class=\"docutils literal notranslate\">int</code> in Python. In Django 1.2, however,\n<code class=\"docutils literal notranslate\">BooleanField</code> on MySQL correctly returns a real <code class=\"docutils literal notranslate\">bool</code>. The only\ntime this should ever be an issue is if you were expecting the\n<code class=\"docutils literal notranslate\">repr</code> of a <code class=\"docutils literal notranslate\">BooleanField</code> to print <code class=\"docutils literal notranslate\">1</code> or <code class=\"docutils literal notranslate\">0</code>.</p>\n</section>\n<section id=\"changes-to-the-interpretation-of-max-num-in-formsets\">\n<h3>Changes to the interpretation of <code class=\"docutils literal notranslate\">max_num</code> in FormSets<a class=\"heading-anchor\" href=\"#changes-to-the-interpretation-of-max-num-in-formsets\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>As part of enhancements made to the handling of FormSets, the default\nvalue and interpretation of the <code class=\"docutils literal notranslate\">max_num</code> parameter to the\n<a class=\"reference internal\" href=\"/en/dev/topics/forms/formsets/#formsets-max-num\"><span class=\"std std-ref\">django.forms.formsets.formset_factory()</span></a> and\n<a class=\"reference internal\" href=\"/en/dev/topics/forms/modelforms/#model-formsets-max-num\"><span class=\"std std-ref\">django.forms.models.modelformset_factory()</span></a> functions has changed slightly. This\nchange also affects the way the\n<a class=\"reference internal\" href=\"/en/dev/ref/contrib/admin/#django.contrib.admin.InlineModelAdmin.max_num\" title=\"django.contrib.admin.InlineModelAdmin.max_num\"><code class=\"xref py py-attr docutils literal notranslate\">max_num</code></a> argument is used for\ninline admin objects.</p>\n<p>Previously, the default value for <code class=\"docutils literal notranslate\">max_num</code> was <code class=\"docutils literal notranslate\">0</code> (zero).\nFormSets then used the boolean value of <code class=\"docutils literal notranslate\">max_num</code> to determine if a\nlimit was to be imposed on the number of generated forms. The default\nvalue of <code class=\"docutils literal notranslate\">0</code> meant that there was no default limit on the number of\nforms in a FormSet.</p>\n<p>Starting with 1.2, the default value for <code class=\"docutils literal notranslate\">max_num</code> has been changed\nto <code class=\"docutils literal notranslate\">None</code>, and FormSets will differentiate between a value of\n<code class=\"docutils literal notranslate\">None</code> and a value of <code class=\"docutils literal notranslate\">0</code>. A value of <code class=\"docutils literal notranslate\">None</code> indicates that no\nlimit on the number of forms is to be imposed; a value of <code class=\"docutils literal notranslate\">0</code>\nindicates that a maximum of 0 forms should be imposed. This doesn’t\nnecessarily mean that no forms will be displayed – see the\n<a class=\"reference internal\" href=\"/en/dev/topics/forms/modelforms/#model-formsets-max-num\"><span class=\"std std-ref\">ModelFormSet documentation</span></a> for more\ndetails.</p>\n<p>If you were manually specifying a value of <code class=\"docutils literal notranslate\">0</code> for <code class=\"docutils literal notranslate\">max_num</code>, you\nwill need to update your FormSet and/or admin definitions.</p>\n<aside class=\"admonition admonition-seealso\" role=\"note\">\n<p class=\"admonition-title\">See also</p>\n<p><a class=\"reference internal\" href=\"#js-assisted-inlines\"><span class=\"std std-ref\">JavaScript-assisted handling of inline related objects in the admin</span></a></p>\n</aside>\n</section>\n<section id=\"email-re\">\n<h3><code class=\"docutils literal notranslate\">email_re</code><a class=\"heading-anchor\" href=\"#email-re\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>An undocumented regular expression for validating email addresses has been\nmoved from <code class=\"docutils literal notranslate\">django.form.fields</code> to <code class=\"docutils literal notranslate\">django.core.validators</code>. You will need\nto update your imports if you are using it.</p>\n</section>\n</section>\n<section id=\"features-deprecated-in-1-2\">\n<span id=\"deprecated-features-1-2\"></span><h2>Features deprecated in 1.2<a class=\"heading-anchor\" href=\"#features-deprecated-in-1-2\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Finally, Django 1.2 deprecates some features from earlier releases.\nThese features are still supported, but will be gradually phased out\nover the next few release cycles.</p>\n<p>Code taking advantage of any of the features below will raise a\n<code class=\"docutils literal notranslate\">PendingDeprecationWarning</code> in Django 1.2. This warning will be\nsilent by default, but may be turned on using Python’s <a class=\"reference external\" href=\"https://docs.python.org/3/library/warnings.html#module-warnings\" title=\"(in Python v3.14)\"><code class=\"xref py py-mod docutils literal notranslate\">warnings</code></a>\nmodule, or by running Python with a <code class=\"docutils literal notranslate\">-Wd</code> or <code class=\"docutils literal notranslate\">-Wall</code> flag.</p>\n<p>In Django 1.3, these warnings will become a <code class=\"docutils literal notranslate\">DeprecationWarning</code>,\nwhich is <em>not</em> silent. In Django 1.4 support for these features will\nbe removed entirely.</p>\n<aside class=\"admonition admonition-seealso\" role=\"note\">\n<p class=\"admonition-title\">See also</p>\n<p>For more details, see the documentation <a class=\"reference internal\" href=\"/en/dev/internals/release-process/\"><span class=\"doc\">Django’s release process</span></a> and our <a class=\"reference internal\" href=\"/en/dev/internals/deprecation/\"><span class=\"doc\">deprecation timeline</span></a>.`</p>\n</aside>\n<section id=\"specifying-databases\">\n<span id=\"id5\"></span><h3>Specifying databases<a class=\"heading-anchor\" href=\"#specifying-databases\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Prior to Django 1.2, Django used a number of settings to control\naccess to a single database. Django 1.2 introduces support for\nmultiple databases, and as a result the way you define database\nsettings has changed.</p>\n<p>Any existing Django settings file will continue to work as expected\nuntil Django 1.4. Until then, old-style database settings will be\nautomatically translated to the new-style format.</p>\n<p>In the old-style (pre 1.2) format, you had a number of <code class=\"docutils literal notranslate\">DATABASE_</code>\nsettings in your settings file. For example:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>DATABASE_NAME <span class=\"o\">=</span> <span class=\"s2\">&quot;test_db&quot;</span>\nDATABASE_ENGINE <span class=\"o\">=</span> <span class=\"s2\">&quot;postgresql_psycopg2&quot;</span>\nDATABASE_USER <span class=\"o\">=</span> <span class=\"s2\">&quot;myusername&quot;</span>\nDATABASE_PASSWORD <span class=\"o\">=</span> <span class=\"s2\">&quot;s3krit&quot;</span>\n</code></pre></div>\n<p>These settings are now in a dictionary named\n<a class=\"reference internal\" href=\"/en/dev/ref/settings/#std-setting-DATABASES\"><code class=\"xref std std-setting docutils literal notranslate\">DATABASES</code></a>. Each item in the dictionary corresponds to a\nsingle database connection, with the name <code class=\"docutils literal notranslate\">'default'</code> describing the\ndefault database connection. The setting names have also been\nshortened. The previous sample settings would now look like this:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>DATABASES <span class=\"o\">=</span> <span class=\"p\">{</span>\n    <span class=\"s2\">&quot;default&quot;</span><span class=\"p\">:</span> <span class=\"p\">{</span>\n        <span class=\"s2\">&quot;NAME&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;test_db&quot;</span><span class=\"p\">,</span>\n        <span class=\"s2\">&quot;ENGINE&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;django.db.backends.postgresql_psycopg2&quot;</span><span class=\"p\">,</span>\n        <span class=\"s2\">&quot;USER&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;myusername&quot;</span><span class=\"p\">,</span>\n        <span class=\"s2\">&quot;PASSWORD&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;s3krit&quot;</span><span class=\"p\">,</span>\n    <span class=\"p\">}</span>\n<span class=\"p\">}</span>\n</code></pre></div>\n<p>This affects the following settings:</p>\n<div class=\"table-scroll\" role=\"region\" tabindex=\"0\" aria-label=\"Table\"><table class=\"docutils align-default\">\n<thead>\n<tr class=\"row-odd\"><th class=\"head\"><p>Old setting</p></th>\n<th class=\"head\"><p>New Setting</p></th>\n</tr>\n</thead>\n<tbody>\n<tr class=\"row-even\"><td><p><code class=\"docutils literal notranslate\">DATABASE_ENGINE</code></p></td>\n<td><p><a class=\"reference internal\" href=\"/en/dev/ref/settings/#std-setting-DATABASE-ENGINE\"><code class=\"xref std std-setting docutils literal notranslate\">ENGINE</code></a></p></td>\n</tr>\n<tr class=\"row-odd\"><td><p><code class=\"docutils literal notranslate\">DATABASE_HOST</code></p></td>\n<td><p><a class=\"reference internal\" href=\"/en/dev/ref/settings/#std-setting-HOST\"><code class=\"xref std std-setting docutils literal notranslate\">HOST</code></a></p></td>\n</tr>\n<tr class=\"row-even\"><td><p><code class=\"docutils literal notranslate\">DATABASE_NAME</code></p></td>\n<td><p><a class=\"reference internal\" href=\"/en/dev/ref/settings/#std-setting-NAME\"><code class=\"xref std std-setting docutils literal notranslate\">NAME</code></a></p></td>\n</tr>\n<tr class=\"row-odd\"><td><p><code class=\"docutils literal notranslate\">DATABASE_OPTIONS</code></p></td>\n<td><p><a class=\"reference internal\" href=\"/en/dev/ref/settings/#std-setting-OPTIONS\"><code class=\"xref std std-setting docutils literal notranslate\">OPTIONS</code></a></p></td>\n</tr>\n<tr class=\"row-even\"><td><p><code class=\"docutils literal notranslate\">DATABASE_PASSWORD</code></p></td>\n<td><p><a class=\"reference internal\" href=\"/en/dev/ref/settings/#std-setting-PASSWORD\"><code class=\"xref std std-setting docutils literal notranslate\">PASSWORD</code></a></p></td>\n</tr>\n<tr class=\"row-odd\"><td><p><code class=\"docutils literal notranslate\">DATABASE_PORT</code></p></td>\n<td><p><a class=\"reference internal\" href=\"/en/dev/ref/settings/#std-setting-PORT\"><code class=\"xref std std-setting docutils literal notranslate\">PORT</code></a></p></td>\n</tr>\n<tr class=\"row-even\"><td><p><code class=\"docutils literal notranslate\">DATABASE_USER</code></p></td>\n<td><p><a class=\"reference internal\" href=\"/en/dev/ref/settings/#std-setting-USER\"><code class=\"xref std std-setting docutils literal notranslate\">USER</code></a></p></td>\n</tr>\n<tr class=\"row-odd\"><td><p><code class=\"docutils literal notranslate\">TEST_DATABASE_CHARSET</code></p></td>\n<td><p><a class=\"reference internal\" href=\"/en/dev/ref/settings/#std-setting-TEST_CHARSET\"><code class=\"xref std std-setting docutils literal notranslate\">TEST_CHARSET</code></a></p></td>\n</tr>\n<tr class=\"row-even\"><td><p><code class=\"docutils literal notranslate\">TEST_DATABASE_COLLATION</code></p></td>\n<td><p><a class=\"reference internal\" href=\"/en/dev/ref/settings/#std-setting-TEST_COLLATION\"><code class=\"xref std std-setting docutils literal notranslate\">TEST_COLLATION</code></a></p></td>\n</tr>\n<tr class=\"row-odd\"><td><p><code class=\"docutils literal notranslate\">TEST_DATABASE_NAME</code></p></td>\n<td><p><a class=\"reference internal\" href=\"/en/dev/ref/settings/#std-setting-TEST_NAME\"><code class=\"xref std std-setting docutils literal notranslate\">TEST_NAME</code></a></p></td>\n</tr>\n</tbody>\n</table>\n</div>\n<p>These changes are also required if you have manually created a database\nconnection using <code class=\"docutils literal notranslate\">DatabaseWrapper()</code> from your database backend of choice.</p>\n<p>In addition to the change in structure, Django 1.2 removes the special\nhandling for the built-in database backends. All database backends\nmust now be specified by a fully qualified module name (i.e.,\n<code class=\"docutils literal notranslate\">django.db.backends.postgresql_psycopg2</code>, rather than just\n<code class=\"docutils literal notranslate\">postgresql_psycopg2</code>).</p>\n</section>\n<section id=\"postgresql-database-backend\">\n<h3><code class=\"docutils literal notranslate\">postgresql</code> database backend<a class=\"heading-anchor\" href=\"#postgresql-database-backend\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>The <code class=\"docutils literal notranslate\">psycopg1</code> library has not been updated since October 2005. As a\nresult, the <code class=\"docutils literal notranslate\">postgresql</code> database backend, which uses this library,\nhas been deprecated.</p>\n<p>If you are currently using the <code class=\"docutils literal notranslate\">postgresql</code> backend, you should\nmigrate to using the <code class=\"docutils literal notranslate\">postgresql_psycopg2</code> backend. To update your\ncode, install the <code class=\"docutils literal notranslate\">psycopg2</code> library and change the\n<a class=\"reference internal\" href=\"/en/dev/ref/settings/#std-setting-DATABASE-ENGINE\"><code class=\"xref std std-setting docutils literal notranslate\">ENGINE</code></a> setting to use\n<code class=\"docutils literal notranslate\">django.db.backends.postgresql_psycopg2</code>.</p>\n</section>\n<section id=\"csrf-response-rewriting-middleware\">\n<h3>CSRF response-rewriting middleware<a class=\"heading-anchor\" href=\"#csrf-response-rewriting-middleware\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p><code class=\"docutils literal notranslate\">CsrfResponseMiddleware</code>, the middleware that automatically inserted\nCSRF tokens into <code class=\"docutils literal notranslate\">POST</code> forms in outgoing pages, has been deprecated\nin favor of a template tag method (see above), and will be removed\ncompletely in Django 1.4. <code class=\"docutils literal notranslate\">CsrfMiddleware</code>, which includes the\nfunctionality of <code class=\"docutils literal notranslate\">CsrfResponseMiddleware</code> and\n<code class=\"docutils literal notranslate\">CsrfViewMiddleware</code>, has likewise been deprecated.</p>\n<p>Also, the CSRF module has moved from contrib to core, and the old\nimports are deprecated, as described in the upgrading notes.</p>\n<aside class=\"admonition-documentation-removed admonition\" role=\"note\">\n<p class=\"admonition-title\">Documentation removed</p>\n<p>The upgrade notes have been removed in current Django docs. Please refer\nto the docs for Django 1.3 or older to find these instructions.</p>\n</aside>\n</section>\n<section id=\"smtpconnection\">\n<h3><code class=\"docutils literal notranslate\">SMTPConnection</code><a class=\"heading-anchor\" href=\"#smtpconnection\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>The <code class=\"docutils literal notranslate\">SMTPConnection</code> class has been deprecated in favor of a generic\nemail backend API. Old code that explicitly instantiated an instance\nof an SMTPConnection:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span> <span class=\"nn\">django.core.mail</span> <span class=\"kn\">import</span> SMTPConnection\n\nconnection <span class=\"o\">=</span> SMTPConnection<span class=\"p\">()</span>\nmessages <span class=\"o\">=</span> get_notification_email<span class=\"p\">()</span>\nconnection<span class=\"o\">.</span>send_messages<span class=\"p\">(</span>messages<span class=\"p\">)</span>\n</code></pre></div>\n<p>…should now call <a class=\"reference internal\" href=\"/en/dev/topics/email/#django.core.mail.get_connection\" title=\"django.core.mail.get_connection\"><code class=\"xref py py-func docutils literal notranslate\">get_connection()</code></a> to\ninstantiate a generic email connection:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span> <span class=\"nn\">django.core.mail</span> <span class=\"kn\">import</span> get_connection\n\nconnection <span class=\"o\">=</span> get_connection<span class=\"p\">()</span>\nmessages <span class=\"o\">=</span> get_notification_email<span class=\"p\">()</span>\nconnection<span class=\"o\">.</span>send_messages<span class=\"p\">(</span>messages<span class=\"p\">)</span>\n</code></pre></div>\n<p>Depending on the value of the <a class=\"reference internal\" href=\"/en/dev/ref/settings/#std-setting-EMAIL_BACKEND\"><code class=\"xref std std-setting docutils literal notranslate\">EMAIL_BACKEND</code></a> setting, this\nmay not return an SMTP connection. If you explicitly require an SMTP\nconnection with which to send email, you can explicitly request an\nSMTP connection:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span> <span class=\"nn\">django.core.mail</span> <span class=\"kn\">import</span> get_connection\n\nconnection <span class=\"o\">=</span> get_connection<span class=\"p\">(</span><span class=\"s2\">&quot;django.core.mail.backends.smtp.EmailBackend&quot;</span><span class=\"p\">)</span>\nmessages <span class=\"o\">=</span> get_notification_email<span class=\"p\">()</span>\nconnection<span class=\"o\">.</span>send_messages<span class=\"p\">(</span>messages<span class=\"p\">)</span>\n</code></pre></div>\n<p>If your call to construct an instance of <code class=\"docutils literal notranslate\">SMTPConnection</code> required\nadditional arguments, those arguments can be passed to the\n<a class=\"reference internal\" href=\"/en/dev/topics/email/#django.core.mail.get_connection\" title=\"django.core.mail.get_connection\"><code class=\"xref py py-func docutils literal notranslate\">get_connection()</code></a> call:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>connection <span class=\"o\">=</span> get_connection<span class=\"p\">(</span>\n    <span class=\"s2\">&quot;django.core.mail.backends.smtp.EmailBackend&quot;</span><span class=\"p\">,</span> hostname<span class=\"o\">=</span><span class=\"s2\">&quot;localhost&quot;</span><span class=\"p\">,</span> port<span class=\"o\">=</span><span class=\"mi\">1234</span>\n<span class=\"p\">)</span>\n</code></pre></div>\n</section>\n<section id=\"user-messages-api\">\n<h3>User Messages API<a class=\"heading-anchor\" href=\"#user-messages-api\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>The API for storing messages in the user <code class=\"docutils literal notranslate\">Message</code> model (via\n<code class=\"docutils literal notranslate\">user.message_set.create</code>) is now deprecated and will be removed in Django\n1.4 according to the standard\n<a class=\"reference internal\" href=\"/en/dev/internals/release-process/\"><span class=\"doc\">release process</span></a>.</p>\n<p>To upgrade your code, you need to replace any instances of this:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>user<span class=\"o\">.</span>message_set<span class=\"o\">.</span>create<span class=\"p\">(</span><span class=\"s2\">&quot;a message&quot;</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>…with the following:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span> <span class=\"nn\">django.contrib</span> <span class=\"kn\">import</span> messages\n\nmessages<span class=\"o\">.</span>add_message<span class=\"p\">(</span>request<span class=\"p\">,</span> messages<span class=\"o\">.</span>INFO<span class=\"p\">,</span> <span class=\"s2\">&quot;a message&quot;</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Additionally, if you make use of the method, you need to replace the\nfollowing:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">for</span> message <span class=\"ow\">in</span> user<span class=\"o\">.</span>get_and_delete_messages<span class=\"p\">():</span>\n    <span class=\"o\">...</span>\n</code></pre></div>\n<p>…with:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span> <span class=\"nn\">django.contrib</span> <span class=\"kn\">import</span> messages\n\n<span class=\"k\">for</span> message <span class=\"ow\">in</span> messages<span class=\"o\">.</span>get_messages<span class=\"p\">(</span>request<span class=\"p\">):</span>\n    <span class=\"o\">...</span>\n</code></pre></div>\n<p>For more information, see the full\n<a class=\"reference internal\" href=\"/en/dev/ref/contrib/messages/\"><span class=\"doc\">messages documentation</span></a>. You should begin to\nupdate your code to use the new API immediately.</p>\n</section>\n<section id=\"date-format-helper-functions\">\n<h3>Date format helper functions<a class=\"heading-anchor\" href=\"#date-format-helper-functions\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p><code class=\"docutils literal notranslate\">django.utils.translation.get_date_formats()</code> and\n<code class=\"docutils literal notranslate\">django.utils.translation.get_partial_date_formats()</code> have been deprecated\nin favor of the appropriate calls to <code class=\"docutils literal notranslate\">django.utils.formats.get_format()</code>,\nwhich is locale-aware when <code class=\"docutils literal notranslate\">USE_L10N</code> is set to <code class=\"docutils literal notranslate\">True</code>, and falls\nback to default settings if set to <code class=\"docutils literal notranslate\">False</code>.</p>\n<p>To get the different date formats, instead of writing this:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span> <span class=\"nn\">django.utils.translation</span> <span class=\"kn\">import</span> get_date_formats\n\ndate_format<span class=\"p\">,</span> datetime_format<span class=\"p\">,</span> time_format <span class=\"o\">=</span> get_date_formats<span class=\"p\">()</span>\n</code></pre></div>\n<p>…use:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span> <span class=\"nn\">django.utils</span> <span class=\"kn\">import</span> formats\n\ndate_format <span class=\"o\">=</span> formats<span class=\"o\">.</span>get_format<span class=\"p\">(</span><span class=\"s2\">&quot;DATE_FORMAT&quot;</span><span class=\"p\">)</span>\ndatetime_format <span class=\"o\">=</span> formats<span class=\"o\">.</span>get_format<span class=\"p\">(</span><span class=\"s2\">&quot;DATETIME_FORMAT&quot;</span><span class=\"p\">)</span>\ntime_format <span class=\"o\">=</span> formats<span class=\"o\">.</span>get_format<span class=\"p\">(</span><span class=\"s2\">&quot;TIME_FORMAT&quot;</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Or, when directly formatting a date value:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span> <span class=\"nn\">django.utils</span> <span class=\"kn\">import</span> formats\n\nvalue_formatted <span class=\"o\">=</span> formats<span class=\"o\">.</span>date_format<span class=\"p\">(</span>value<span class=\"p\">,</span> <span class=\"s2\">&quot;DATETIME_FORMAT&quot;</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>The same applies to the globals found in <code class=\"docutils literal notranslate\">django.forms.fields</code>:</p>\n<ul class=\"simple\">\n<li><p><code class=\"docutils literal notranslate\">DEFAULT_DATE_INPUT_FORMATS</code></p></li>\n<li><p><code class=\"docutils literal notranslate\">DEFAULT_TIME_INPUT_FORMATS</code></p></li>\n<li><p><code class=\"docutils literal notranslate\">DEFAULT_DATETIME_INPUT_FORMATS</code></p></li>\n</ul>\n<p>Use <code class=\"docutils literal notranslate\">django.utils.formats.get_format()</code> to get the appropriate formats.</p>\n</section>\n<section id=\"function-based-test-runners\">\n<h3>Function-based test runners<a class=\"heading-anchor\" href=\"#function-based-test-runners\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Django 1.2 changes the test runner tools to use a class-based\napproach. Old style function-based test runners will still work, but\nshould be updated to use the new <a class=\"reference internal\" href=\"/en/dev/topics/testing/advanced/#topics-testing-test-runner\"><span class=\"std std-ref\">class-based runners</span></a>.</p>\n</section>\n<section id=\"feed-in-django-contrib-syndication-feeds\">\n<span id=\"updating-feeds\"></span><h3><code class=\"docutils literal notranslate\">Feed</code> in <code class=\"docutils literal notranslate\">django.contrib.syndication.feeds</code><a class=\"heading-anchor\" href=\"#feed-in-django-contrib-syndication-feeds\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>The <code class=\"docutils literal notranslate\">django.contrib.syndication.feeds.Feed</code> class has been\nreplaced by the <a class=\"reference internal\" href=\"/en/dev/ref/contrib/syndication/#django.contrib.syndication.views.Feed\" title=\"django.contrib.syndication.views.Feed\"><code class=\"xref py py-class docutils literal notranslate\">django.contrib.syndication.views.Feed</code></a> class.\nThe old <code class=\"docutils literal notranslate\">feeds.Feed</code> class is deprecated, and will be removed in\nDjango 1.4.</p>\n<p>The new class has an almost identical API, but allows instances to be\nused as views. For example, consider the use of the old framework in\nthe following <a class=\"reference internal\" href=\"/en/dev/topics/http/urls/\"><span class=\"doc\">URLconf</span></a>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span> <span class=\"nn\">django.conf.urls.defaults</span> <span class=\"kn\">import</span> <span class=\"o\">*</span>\n<span class=\"kn\">from</span> <span class=\"nn\">myproject.feeds</span> <span class=\"kn\">import</span> LatestEntries<span class=\"p\">,</span> LatestEntriesByCategory\n\nfeeds <span class=\"o\">=</span> <span class=\"p\">{</span>\n    <span class=\"s2\">&quot;latest&quot;</span><span class=\"p\">:</span> LatestEntries<span class=\"p\">,</span>\n    <span class=\"s2\">&quot;categories&quot;</span><span class=\"p\">:</span> LatestEntriesByCategory<span class=\"p\">,</span>\n<span class=\"p\">}</span>\n\nurlpatterns <span class=\"o\">=</span> patterns<span class=\"p\">(</span>\n    <span class=\"s2\">&quot;&quot;</span><span class=\"p\">,</span>\n    <span class=\"c1\"># ...</span>\n    <span class=\"p\">(</span>\n        <span class=\"sa\">r</span><span class=\"s2\">&quot;^feeds/(?P&lt;url&gt;.*)/$&quot;</span><span class=\"p\">,</span>\n        <span class=\"s2\">&quot;django.contrib.syndication.views.feed&quot;</span><span class=\"p\">,</span>\n        <span class=\"p\">{</span><span class=\"s2\">&quot;feed_dict&quot;</span><span class=\"p\">:</span> feeds<span class=\"p\">},</span>\n    <span class=\"p\">),</span>\n    <span class=\"c1\"># ...</span>\n<span class=\"p\">)</span>\n</code></pre></div>\n<p>Using the new Feed class, these feeds can be deployed directly as views:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span> <span class=\"nn\">django.conf.urls.defaults</span> <span class=\"kn\">import</span> <span class=\"o\">*</span>\n<span class=\"kn\">from</span> <span class=\"nn\">myproject.feeds</span> <span class=\"kn\">import</span> LatestEntries<span class=\"p\">,</span> LatestEntriesByCategory\n\nurlpatterns <span class=\"o\">=</span> patterns<span class=\"p\">(</span>\n    <span class=\"s2\">&quot;&quot;</span><span class=\"p\">,</span>\n    <span class=\"c1\"># ...</span>\n    <span class=\"p\">(</span><span class=\"sa\">r</span><span class=\"s2\">&quot;^feeds/latest/$&quot;</span><span class=\"p\">,</span> LatestEntries<span class=\"p\">()),</span>\n    <span class=\"p\">(</span><span class=\"sa\">r</span><span class=\"s2\">&quot;^feeds/categories/(?P&lt;category_id&gt;\\d+)/$&quot;</span><span class=\"p\">,</span> LatestEntriesByCategory<span class=\"p\">()),</span>\n    <span class=\"c1\"># ...</span>\n<span class=\"p\">)</span>\n</code></pre></div>\n<p>If you currently use the <code class=\"docutils literal notranslate\">feed()</code> view, the <code class=\"docutils literal notranslate\">LatestEntries</code> class would\noften not need to be modified apart from subclassing the new\n<a class=\"reference internal\" href=\"/en/dev/ref/contrib/syndication/#django.contrib.syndication.views.Feed\" title=\"django.contrib.syndication.views.Feed\"><code class=\"xref py py-class docutils literal notranslate\">Feed</code></a> class. The exception is if\nDjango was automatically working out the name of the template to use to render\nthe feed’s description and title elements (if you were not specifying the\n<code class=\"docutils literal notranslate\">title_template</code> and <code class=\"docutils literal notranslate\">description_template</code> attributes). You should ensure\nthat you always specify <code class=\"docutils literal notranslate\">title_template</code> and <code class=\"docutils literal notranslate\">description_template</code>\nattributes, or provide <code class=\"docutils literal notranslate\">item_title()</code> and <code class=\"docutils literal notranslate\">item_description()</code> methods.</p>\n<p>However, <code class=\"docutils literal notranslate\">LatestEntriesByCategory</code> uses the <code class=\"docutils literal notranslate\">get_object()</code> method\nwith the <code class=\"docutils literal notranslate\">bits</code> argument to specify a specific category to show. In\nthe new <a class=\"reference internal\" href=\"/en/dev/ref/contrib/syndication/#django.contrib.syndication.views.Feed\" title=\"django.contrib.syndication.views.Feed\"><code class=\"xref py py-class docutils literal notranslate\">Feed</code></a> class,\n<code class=\"docutils literal notranslate\">get_object()</code> method takes a <code class=\"docutils literal notranslate\">request</code> and arguments from the\nURL, so it would look like this:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span> <span class=\"nn\">django.contrib.syndication.views</span> <span class=\"kn\">import</span> Feed\n<span class=\"kn\">from</span> <span class=\"nn\">django.shortcuts</span> <span class=\"kn\">import</span> get_object_or_404\n<span class=\"kn\">from</span> <span class=\"nn\">myproject.models</span> <span class=\"kn\">import</span> Category\n\n\n<span class=\"k\">class</span> <span class=\"nc\">LatestEntriesByCategory</span><span class=\"p\">(</span>Feed<span class=\"p\">):</span>\n    <span class=\"k\">def</span> <span class=\"nf\">get_object</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> request<span class=\"p\">,</span> category_id<span class=\"p\">):</span>\n        <span class=\"k\">return</span> get_object_or_404<span class=\"p\">(</span>Category<span class=\"p\">,</span> <span class=\"nb\">id</span><span class=\"o\">=</span>category_id<span class=\"p\">)</span>\n\n    <span class=\"c1\"># ...</span>\n</code></pre></div>\n<p>Additionally, the <code class=\"docutils literal notranslate\">get_feed()</code> method on <code class=\"docutils literal notranslate\">Feed</code> classes now take\ndifferent arguments, which may impact you if you use the <code class=\"docutils literal notranslate\">Feed</code>\nclasses directly. Instead of just taking an optional <code class=\"docutils literal notranslate\">url</code> argument,\nit now takes two arguments: the object returned by its own\n<code class=\"docutils literal notranslate\">get_object()</code> method, and the current <code class=\"docutils literal notranslate\">request</code> object.</p>\n<p>To take into account <code class=\"docutils literal notranslate\">Feed</code> classes not being initialized for each\nrequest, the <code class=\"docutils literal notranslate\">__init__()</code> method now takes no arguments by default.\nPreviously it would have taken the <code class=\"docutils literal notranslate\">slug</code> from the URL and the\n<code class=\"docutils literal notranslate\">request</code> object.</p>\n<p>In accordance with <a class=\"reference external\" href=\"https://www.rssboard.org/rss-profile\">RSS best practices</a>, RSS feeds will now include\nan <code class=\"docutils literal notranslate\">atom:link</code> element. You may need to update your tests to take\nthis into account.</p>\n<p>For more information, see the full <a class=\"reference internal\" href=\"/en/dev/ref/contrib/syndication/\"><span class=\"doc\">syndication framework\ndocumentation</span></a>.</p>\n</section>\n<section id=\"technical-message-ids\">\n<h3>Technical message IDs<a class=\"heading-anchor\" href=\"#technical-message-ids\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Up to version 1.1 Django used technical message IDs\nto provide localizers the possibility to translate date and time formats. They\nwere translatable <a class=\"reference internal\" href=\"/en/dev/topics/i18n/#term-translation-string\"><span class=\"xref std std-term\">translation strings</span></a> that could\nbe recognized because they were all upper case (for example\n<a class=\"reference internal\" href=\"/en/dev/ref/settings/#std-setting-DATETIME_FORMAT\"><code class=\"xref std std-setting docutils literal notranslate\">DATETIME_FORMAT</code></a>, <a class=\"reference internal\" href=\"/en/dev/ref/settings/#std-setting-DATE_FORMAT\"><code class=\"xref std std-setting docutils literal notranslate\">DATE_FORMAT</code></a>, <a class=\"reference internal\" href=\"/en/dev/ref/settings/#std-setting-TIME_FORMAT\"><code class=\"xref std std-setting docutils literal notranslate\">TIME_FORMAT</code></a>).\nThey have been deprecated in favor of the new <a class=\"reference internal\" href=\"/en/dev/topics/i18n/formatting/\"><span class=\"doc\">Format localization</span></a>\ninfrastructure that allows localizers to specify that information in a\n<code class=\"docutils literal notranslate\">formats.py</code> file in the corresponding <code class=\"docutils literal notranslate\">django/conf/locale/&lt;locale name&gt;/</code>\ndirectory.</p>\n</section>\n<section id=\"id6\">\n<h3>GeoDjango<a class=\"heading-anchor\" href=\"#id6\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>To allow support for multiple databases, the GeoDjango database internals were\nchanged substantially. The largest backwards-incompatible change is that\nthe module <code class=\"docutils literal notranslate\">django.contrib.gis.db.backend</code> was renamed to\n<a class=\"reference internal\" href=\"/en/dev/ref/contrib/gis/db-api/#module-django.contrib.gis.db.backends\" title=\"django.contrib.gis.db.backends: GeoDjango's spatial database backends.\"><code class=\"xref py py-mod docutils literal notranslate\">django.contrib.gis.db.backends</code></a>, where the full-fledged\n<a class=\"reference internal\" href=\"/en/dev/ref/contrib/gis/db-api/#spatial-backends\"><span class=\"std std-ref\">spatial database backends</span></a> now exist. The\nfollowing sections provide information on the most-popular APIs that\nwere affected by these changes.</p>\n<section id=\"spatialbackend\">\n<h4><code class=\"docutils literal notranslate\">SpatialBackend</code><a class=\"heading-anchor\" href=\"#spatialbackend\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>Prior to the creation of the separate spatial backends, the\n<code class=\"docutils literal notranslate\">django.contrib.gis.db.backend.SpatialBackend</code> object was\nprovided as an abstraction to introspect on the capabilities of\nthe spatial database. All of the attributes and routines provided by\n<code class=\"docutils literal notranslate\">SpatialBackend</code> are now a part of the <code class=\"docutils literal notranslate\">ops</code> attribute of the\ndatabase backend.</p>\n<p>The old module <code class=\"docutils literal notranslate\">django.contrib.gis.db.backend</code> is still provided\nfor backwards-compatibility access to a <code class=\"docutils literal notranslate\">SpatialBackend</code> object,\nwhich is just an alias to the <code class=\"docutils literal notranslate\">ops</code> module of the\n<em>default</em> spatial database connection.</p>\n<p>Users that were relying on undocumented modules and objects\nwithin <code class=\"docutils literal notranslate\">django.contrib.gis.db.backend</code>, rather the abstractions\nprovided by <code class=\"docutils literal notranslate\">SpatialBackend</code>, are required to modify their code.\nFor example, the following import which would work in 1.1 and\nbelow:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span> <span class=\"nn\">django.contrib.gis.db.backend.postgis</span> <span class=\"kn\">import</span> PostGISAdaptor\n</code></pre></div>\n<p>Would need to be changed:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span> <span class=\"nn\">django.db</span> <span class=\"kn\">import</span> connection\n\nPostGISAdaptor <span class=\"o\">=</span> connection<span class=\"o\">.</span>ops<span class=\"o\">.</span>Adapter\n</code></pre></div>\n</section>\n<section id=\"spatialrefsys-and-geometrycolumns-models\">\n<h4><code class=\"docutils literal notranslate\">SpatialRefSys</code> and <code class=\"docutils literal notranslate\">GeometryColumns</code> models<a class=\"heading-anchor\" href=\"#spatialrefsys-and-geometrycolumns-models\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h4>\n<p>In previous versions of GeoDjango, <a class=\"reference internal\" href=\"/en/dev/ref/contrib/gis/model-api/#module-django.contrib.gis.db.models\" title=\"django.contrib.gis.db.models: GeoDjango model and field API.\"><code class=\"xref py py-mod docutils literal notranslate\">django.contrib.gis.db.models</code></a>\nhad <code class=\"docutils literal notranslate\">SpatialRefSys</code> and <code class=\"docutils literal notranslate\">GeometryColumns</code> models for querying\nthe OGC spatial metadata tables <code class=\"docutils literal notranslate\">spatial_ref_sys</code> and <code class=\"docutils literal notranslate\">geometry_columns</code>,\nrespectively.</p>\n<p>While these aliases are still provided, they are only for the\n<em>default</em> database connection and exist only if the default connection\nis using a supported spatial database backend.</p>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Note</p>\n<p>Because the table structure of the OGC spatial metadata tables\ndiffers across spatial databases, the <code class=\"docutils literal notranslate\">SpatialRefSys</code> and\n<code class=\"docutils literal notranslate\">GeometryColumns</code> models can no longer be associated with\nthe <code class=\"docutils literal notranslate\">gis</code> application name. Thus, no models will be returned\nwhen using the <code class=\"docutils literal notranslate\">get_models</code> method in the following example:</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span> <span class=\"nn\">django.db.models</span> <span class=\"kn\">import</span> get_app<span class=\"p\">,</span> get_models\n<span class=\"gp\">&gt;&gt;&gt; </span>get_models<span class=\"p\">(</span>get_app<span class=\"p\">(</span><span class=\"s2\">&quot;gis&quot;</span><span class=\"p\">))</span>\n<span class=\"go\">[]</span>\n</code></pre></div>\n</aside>\n<p>To get the correct <code class=\"docutils literal notranslate\">SpatialRefSys</code> and <code class=\"docutils literal notranslate\">GeometryColumns</code>\nfor your spatial database use the methods provided by the spatial backend:</p>\n<blockquote>\n<div><div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span> <span class=\"nn\">django.db</span> <span class=\"kn\">import</span> connections\n<span class=\"gp\">&gt;&gt;&gt; </span>SpatialRefSys <span class=\"o\">=</span> connections<span class=\"p\">[</span><span class=\"s2\">&quot;my_spatialite&quot;</span><span class=\"p\">]</span><span class=\"o\">.</span>ops<span class=\"o\">.</span>spatial_ref_sys<span class=\"p\">()</span>\n<span class=\"gp\">&gt;&gt;&gt; </span>GeometryColumns <span class=\"o\">=</span> connections<span class=\"p\">[</span><span class=\"s2\">&quot;my_postgis&quot;</span><span class=\"p\">]</span><span class=\"o\">.</span>ops<span class=\"o\">.</span>geometry_columns<span class=\"p\">()</span>\n</code></pre></div>\n</div></blockquote>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Note</p>\n<p>When using the models returned from the <code class=\"docutils literal notranslate\">spatial_ref_sys()</code> and\n<code class=\"docutils literal notranslate\">geometry_columns()</code> method, you’ll still need to use the\ncorrect database alias when querying on the non-default connection.\nIn other words, to ensure that the models in the example above\nuse the correct database:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code>sr_qs <span class=\"o\">=</span> SpatialRefSys<span class=\"o\">.</span>objects<span class=\"o\">.</span>using<span class=\"p\">(</span><span class=\"s2\">&quot;my_spatialite&quot;</span><span class=\"p\">)</span><span class=\"o\">.</span>filter<span class=\"p\">(</span><span class=\"o\">...</span><span class=\"p\">)</span>\ngc_qs <span class=\"o\">=</span> GeometryColumns<span class=\"o\">.</span>objects<span class=\"o\">.</span>using<span class=\"p\">(</span><span class=\"s2\">&quot;my_postgis&quot;</span><span class=\"p\">)</span><span class=\"o\">.</span>filter<span class=\"p\">(</span><span class=\"o\">...</span><span class=\"p\">)</span>\n</code></pre></div>\n</aside>\n</section>\n</section>\n<section id=\"language-code-no\">\n<h3>Language code <code class=\"docutils literal notranslate\">no</code><a class=\"heading-anchor\" href=\"#language-code-no\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>The currently used language code for Norwegian Bokmål <code class=\"docutils literal notranslate\">no</code> is being\nreplaced by the more common language code <code class=\"docutils literal notranslate\">nb</code>.</p>\n</section>\n<section id=\"function-based-template-loaders\">\n<h3>Function-based template loaders<a class=\"heading-anchor\" href=\"#function-based-template-loaders\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Django 1.2 changes the template loading mechanism to use a class-based\napproach. Old style function-based template loaders will still work, but should\nbe updated to use the new class-based template loaders.</p>\n</section>\n</section>","rootId":"django-1-2-release-notes","toc":[{"title":"Overview","anchor":"overview","children":[]},{"title":"Python compatibility","anchor":"python-compatibility","children":[]},{"title":"What’s new in Django 1.2","anchor":"what-s-new-in-django-1-2","children":[{"title":"Support for multiple databases","anchor":"support-for-multiple-databases","children":[]},{"title":"Model validation","anchor":"model-validation","children":[]},{"title":"Improved CSRF protection","anchor":"improved-csrf-protection","children":[]},{"title":"Messages framework","anchor":"messages-framework","children":[]},{"title":"Object-level permissions","anchor":"object-level-permissions","children":[]},{"title":"Permissions for anonymous users","anchor":"permissions-for-anonymous-users","children":[]},{"title":"Relaxed requirements for usernames","anchor":"relaxed-requirements-for-usernames","children":[]},{"title":"Email backends","anchor":"email-backends","children":[]},{"title":"“Smart” if tag","anchor":"smart-if-tag","children":[]},{"title":"Template caching","anchor":"template-caching","children":[]},{"title":"Class-based template loaders","anchor":"class-based-template-loaders","children":[]},{"title":"Natural keys in fixtures","anchor":"natural-keys-in-fixtures","children":[]},{"title":"Fast failure for tests","anchor":"fast-failure-for-tests","children":[]},{"title":"BigIntegerField","anchor":"bigintegerfield","children":[]},{"title":"Improved localization","anchor":"improved-localization","children":[]},{"title":"readonly_fields in ModelAdmin","anchor":"readonly-fields-in-modeladmin","children":[]},{"title":"Customizable syntax highlighting","anchor":"customizable-syntax-highlighting","children":[]},{"title":"Syndication feeds as views","anchor":"syndication-feeds-as-views","children":[]},{"title":"GeoDjango","anchor":"geodjango","children":[]},{"title":"JavaScript-assisted handling of inline related objects in the admin","anchor":"javascript-assisted-handling-of-inline-related-objects-in-the-admin","children":[]},{"title":"New now template tag format specifier characters: c and u","anchor":"new-now-template-tag-format-specifier-characters-c-and-u","children":[]}]},{"title":"Backwards-incompatible changes in 1.2","anchor":"backwards-incompatible-changes-in-1-2","children":[{"title":"CSRF Protection","anchor":"csrf-protection","children":[]},{"title":"get_db_prep_*() methods on Field","anchor":"get-db-prep-methods-on-field","children":[]},{"title":"Stateful template tags","anchor":"stateful-template-tags","children":[]},{"title":"user_passes_test, login_required and permission_required","anchor":"user-passes-test-login-required-and-permission-required","children":[]},{"title":"if tag changes","anchor":"if-tag-changes","children":[]},{"title":"LazyObject","anchor":"lazyobject","children":[]},{"title":"__dict__ on model instances","anchor":"dict-on-model-instances","children":[]},{"title":"Test runner exit status code","anchor":"test-runner-exit-status-code","children":[]},{"title":"Cookie encoding","anchor":"cookie-encoding","children":[]},{"title":"ModelForm.is_valid() and ModelForm.errors","anchor":"modelform-is-valid-and-modelform-errors","children":[]},{"title":"BooleanField on MySQL","anchor":"booleanfield-on-mysql","children":[]},{"title":"Changes to the interpretation of max_num in FormSets","anchor":"changes-to-the-interpretation-of-max-num-in-formsets","children":[]},{"title":"email_re","anchor":"email-re","children":[]}]},{"title":"Features deprecated in 1.2","anchor":"features-deprecated-in-1-2","children":[{"title":"Specifying databases","anchor":"specifying-databases","children":[]},{"title":"postgresql database backend","anchor":"postgresql-database-backend","children":[]},{"title":"CSRF response-rewriting middleware","anchor":"csrf-response-rewriting-middleware","children":[]},{"title":"SMTPConnection","anchor":"smtpconnection","children":[]},{"title":"User Messages API","anchor":"user-messages-api","children":[]},{"title":"Date format helper functions","anchor":"date-format-helper-functions","children":[]},{"title":"Function-based test runners","anchor":"function-based-test-runners","children":[]},{"title":"Feed in django.contrib.syndication.feeds","anchor":"feed-in-django-contrib-syndication-feeds","children":[]},{"title":"Technical message IDs","anchor":"technical-message-ids","children":[]},{"title":"GeoDjango","anchor":"id6","children":[{"title":"SpatialBackend","anchor":"spatialbackend","children":[]},{"title":"SpatialRefSys and GeometryColumns models","anchor":"spatialrefsys-and-geometrycolumns-models","children":[]}]},{"title":"Language code no","anchor":"language-code-no","children":[]},{"title":"Function-based template loaders","anchor":"function-based-template-loaders","children":[]}]}],"breadcrumbs":[{"docname":"releases/index","title":"Release notes","url":"/en/dev/releases/"}],"prev":{"docname":"releases/1.2.1","title":"Django 1.2.1 release notes","url":"/en/dev/releases/1.2.1/"},"next":{"docname":"releases/1.1.4","title":"Django 1.1.4 release notes","url":"/en/dev/releases/1.1.4/"},"formats":{"html":"/en/dev/releases/1.2/","markdown":"/en/dev/releases/1.2.md","json":"/en/dev/releases/1.2.json"},"source":"https://github.com/django/django/blob/main/docs/releases/1.2.txt","official":"https://docs.djangoproject.com/en/dev/releases/1.2/","inVersions":["dev","6.1","6.0","5.2","5.1","5.0","4.2","4.1","4.0","3.2","3.1","3.0","2.2","2.1","2.0","1.11","1.10","1.9","1.8"],"inLocales":["en"]}