{"title":"Django 1.2.5 release notes","version":"dev","locale":"en","docname":"releases/1.2.5","url":"/en/dev/releases/1.2.5/","canonical":"https://djangodocs.dev/en/dev/releases/1.2.5/","summary":"Welcome to Django 1.2.5! This is the fifth “bugfix” release in the Django 1.2 series, improving the stability and performance of the Django 1.2 codebase.","html":"<h1>Django 1.2.5 release notes<a class=\"heading-anchor\" href=\"#django-1-2-5-release-notes\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h1>\n<p>Welcome to Django 1.2.5!</p>\n<p>This is the fifth “bugfix” release in the Django 1.2 series,\nimproving the stability and performance of the Django 1.2 codebase.</p>\n<p>With four exceptions, Django 1.2.5 maintains backwards compatibility\nwith Django 1.2.4. It also contains a number of fixes and other\nimprovements. Django 1.2.5 is a recommended upgrade for any\ndevelopment or deployment currently using or targeting Django 1.2.</p>\n<p>For full details on the new features, backwards incompatibilities, and\ndeprecated features in the 1.2 branch, see the <a class=\"reference internal\" href=\"/en/dev/releases/1.2/\"><span class=\"doc\">Django 1.2 release notes</span></a>.</p>\n<section id=\"backwards-incompatible-changes\">\n<h2>Backwards incompatible changes<a class=\"heading-anchor\" href=\"#backwards-incompatible-changes\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<section id=\"csrf-exception-for-ajax-requests\">\n<h3>CSRF exception for AJAX requests<a class=\"heading-anchor\" href=\"#csrf-exception-for-ajax-requests\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Django includes a CSRF-protection mechanism, which makes use of a\ntoken inserted into outgoing forms. Middleware then checks for the\ntoken’s presence on form submission, and validates it.</p>\n<p>Prior to Django 1.2.5, our CSRF protection made an exception for AJAX\nrequests, on the following basis:</p>\n<ul class=\"simple\">\n<li><p>Many AJAX toolkits add an X-Requested-With header when using\nXMLHttpRequest.</p></li>\n<li><p>Browsers have strict same-origin policies regarding\nXMLHttpRequest.</p></li>\n<li><p>In the context of a browser, the only way that a custom header\nof this nature can be added is with XMLHttpRequest.</p></li>\n</ul>\n<p>Therefore, for ease of use, we did not apply CSRF checks to requests\nthat appeared to be AJAX on the basis of the X-Requested-With header.\nThe Ruby on Rails web framework had a similar exemption.</p>\n<p>Recently, engineers at Google made members of the Ruby on Rails\ndevelopment team aware of a combination of browser plugins and\nredirects which can allow an attacker to provide custom HTTP headers\non a request to any website. This can allow a forged request to appear\nto be an AJAX request, thereby defeating CSRF protection which trusts\nthe same-origin nature of AJAX requests.</p>\n<p>Michael Koziarski of the Rails team brought this to our attention, and\nwe were able to produce a proof-of-concept demonstrating the same\nvulnerability in Django’s CSRF handling.</p>\n<p>To remedy this, Django will now apply full CSRF validation to all\nrequests, regardless of apparent AJAX origin. This is technically\nbackwards-incompatible, but the security risks have been judged to\noutweigh the compatibility concerns in this case.</p>\n<p>Additionally, Django will now accept the CSRF token in the custom HTTP\nheader X-CSRFTOKEN, as well as in the form submission itself, for ease\nof use with popular JavaScript toolkits which allow insertion of\ncustom headers into all AJAX requests.</p>\n<p>Please see the <a class=\"reference internal\" href=\"/en/dev/howto/csrf/#csrf-ajax\"><span class=\"std std-ref\">CSRF docs for example jQuery code</span></a>\nthat demonstrates this technique, ensuring that you are looking at the\ndocumentation for your version of Django, as the exact code necessary\nis different for some older versions of Django.</p>\n</section>\n<section id=\"filefield-no-longer-deletes-files\">\n<h3>FileField no longer deletes files<a class=\"heading-anchor\" href=\"#filefield-no-longer-deletes-files\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>In earlier Django versions, when a model instance containing a\n<a class=\"reference internal\" href=\"/en/dev/ref/models/fields/#django.db.models.FileField\" title=\"django.db.models.FileField\"><code class=\"xref py py-class docutils literal notranslate\">FileField</code></a> was deleted,\n<a class=\"reference internal\" href=\"/en/dev/ref/models/fields/#django.db.models.FileField\" title=\"django.db.models.FileField\"><code class=\"xref py py-class docutils literal notranslate\">FileField</code></a> took it upon itself to also delete the\nfile from the backend storage. This opened the door to several potentially\nserious data-loss scenarios, including rolled-back transactions and fields on\ndifferent models referencing the same file. In Django 1.2.5,\n<a class=\"reference internal\" href=\"/en/dev/ref/models/fields/#django.db.models.FileField\" title=\"django.db.models.FileField\"><code class=\"xref py py-class docutils literal notranslate\">FileField</code></a> will never delete files from the backend\nstorage. If you need cleanup of orphaned files, you’ll need to handle it\nyourself (for instance, with a custom management command that can be run\nmanually or scheduled to run periodically via e.g. cron).</p>\n</section>\n<section id=\"use-of-custom-sql-to-load-initial-data-in-tests\">\n<h3>Use of custom SQL to load initial data in tests<a class=\"heading-anchor\" href=\"#use-of-custom-sql-to-load-initial-data-in-tests\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Django provides a custom SQL hooks as a way to inject hand-crafted SQL\ninto the database synchronization process. One of the possible uses\nfor this custom SQL is to insert data into your database. If your\ncustom SQL contains <code class=\"docutils literal notranslate\">INSERT</code> statements, those insertions will be\nperformed every time your database is synchronized. This includes the\nsynchronization of any test databases that are created when you run a\ntest suite.</p>\n<p>However, in the process of testing the Django 1.3, it was discovered\nthat this feature has never completely worked as advertised. When\nusing database backends that don’t support transactions, or when using\na TransactionTestCase, data that has been inserted using custom SQL\nwill not be visible during the testing process.</p>\n<p>Unfortunately, there was no way to rectify this problem without\nintroducing a backwards incompatibility. Rather than leave\nSQL-inserted initial data in an uncertain state, Django now enforces\nthe policy that data inserted by custom SQL will <em>not</em> be visible\nduring testing.</p>\n<p>This change only affects the testing process. You can still use custom\nSQL to load data into your production database as part of the <code class=\"docutils literal notranslate\">syncdb</code>\nprocess. If you require data to exist during test conditions, you\nshould either insert it using <a class=\"reference internal\" href=\"/en/dev/topics/testing/tools/#topics-testing-fixtures\"><span class=\"std std-ref\">test fixtures</span></a>, or using the <code class=\"docutils literal notranslate\">setUp()</code> method of your\ntest case.</p>\n</section>\n<section id=\"modeladmin-lookup-allowed-signature-changed\">\n<h3>ModelAdmin.lookup_allowed signature changed<a class=\"heading-anchor\" href=\"#modeladmin-lookup-allowed-signature-changed\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Django 1.2.4 introduced a method <code class=\"docutils literal notranslate\">lookup_allowed</code> on <code class=\"docutils literal notranslate\">ModelAdmin</code>, to cope\nwith a security issue (changeset <a class=\"extlink-commit reference external\" href=\"https://github.com/django/django/commit/85207a245bf09fdebe486b4c7bbcb65300f2a693\">[15033]</a>). Although this method was never\ndocumented, it seems some people have overridden <code class=\"docutils literal notranslate\">lookup_allowed</code>, especially\nto cope with regressions introduced by that changeset. While the method is\nstill undocumented and not marked as stable, it may be helpful to know that the\nsignature of this function has changed.</p>\n</section>\n</section>","rootId":"django-1-2-5-release-notes","toc":[{"title":"Backwards incompatible changes","anchor":"backwards-incompatible-changes","children":[{"title":"CSRF exception for AJAX requests","anchor":"csrf-exception-for-ajax-requests","children":[]},{"title":"FileField no longer deletes files","anchor":"filefield-no-longer-deletes-files","children":[]},{"title":"Use of custom SQL to load initial data in tests","anchor":"use-of-custom-sql-to-load-initial-data-in-tests","children":[]},{"title":"ModelAdmin.lookup_allowed signature changed","anchor":"modeladmin-lookup-allowed-signature-changed","children":[]}]}],"breadcrumbs":[{"docname":"releases/index","title":"Release notes","url":"/en/dev/releases/"}],"prev":{"docname":"releases/1.2.6","title":"Django 1.2.6 release notes","url":"/en/dev/releases/1.2.6/"},"next":{"docname":"releases/1.2.4","title":"Django 1.2.4 release notes","url":"/en/dev/releases/1.2.4/"},"formats":{"html":"/en/dev/releases/1.2.5/","markdown":"/en/dev/releases/1.2.5.md","json":"/en/dev/releases/1.2.5.json"},"source":"https://github.com/django/django/blob/main/docs/releases/1.2.5.txt","official":"https://docs.djangoproject.com/en/dev/releases/1.2.5/","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"]}