Compare commits

...

226 Commits

Author SHA1 Message Date
Tim Graham 6726d75097 [1.3.x] Fixed #21869 -- Fixed docs building with Sphinx 1.2.1.
Thanks tragiclifestories for the report.

Backport of e1d18b9d2e from master
2014-07-18 13:07:52 +00:00
Luke Plant e982cbd4a1 [1.3.x] Fixed djangodocs Sphinx extension to work with latest Sphinx
git-svn-id: http://code.djangoproject.com/svn/django/trunk@16231 bcc190cf-cafb-0310-a4f2-bffc1f526a37

Backport of 66fd824ee0 from master
2014-07-18 13:07:31 +00:00
Tim Graham 8892b0c2c3 [1.3.x] Added a bugfix in docutils 0.11 -- docs will now build properly.
Backport of a3a59a3197 from master
2014-07-18 13:05:52 +00:00
Luke Plant 8dc1b2e03f [1.3.x] Fixed our Sphinx extension to work with latest Sphinx
This is pretty hacky, but there doesn't seem to be a nice way to fix it,
since we can't call the base method - we are deliberately overriding it in
order to not call the base method, which adds an unwanted 'border=1' to the
HTML.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@16223 bcc190cf-cafb-0310-a4f2-bffc1f526a37

Backport of e127e17b49 from master
2014-07-18 13:03:38 +00:00
Tim Graham adea5a3880 Merge pull request #2227 from jheasly/patch-1
Fixed bad link
2014-02-01 10:38:57 -08:00
John Heasly 1989df6014 Fixed bad link 2014-01-31 17:15:13 -08:00
Tim Graham 7dd37edf62 [1.3.x] Added missing release notes for older versions of Django
Backport of 3f6cc33cff from master
2013-08-12 14:26:48 -04:00
Carl Meyer 956b755d7e [1.3.x] Bump version to no longer claim to be 1.3.7 final. 2013-03-28 15:12:13 -06:00
James Bennett 304a5e0628 [1.3.x] Bump version numbers to roll a clean package. 2013-02-20 13:52:28 -06:00
Carl Meyer a57743c9ff [1.4.x] Note that ALLOWED_HOSTS default changes in Django 1.5. 2013-02-20 12:28:39 -07:00
Carl Meyer a6927d8219 [1.3.x] Fixed #19857 -- Fixed broken docs link in project template.
Backport of 4cdfb24c98 from 1.4.x.
2013-02-19 18:38:58 -07:00
Carl Meyer 2378c31430 [1.3.x] Don't characterize XML vulnerabilities as DoS-only. 2013-02-19 18:23:25 -07:00
James Bennett 747d3f0d03 [1.3.x] Bump version numbers for security release. 2013-02-19 14:18:32 -06:00
Carl Meyer f6f6f87a98 [1.3.x] Update 1.3.6 release notes for all security fixes. 2013-02-19 11:52:19 -07:00
Aymeric Augustin d7094bbce8 [1.3.x] Added a default limit to the maximum number of forms in a formset.
This is a security fix. Disclosure and advisory coming shortly.
2013-02-12 12:13:42 +01:00
Carl Meyer d3a45e10c8 [1.3.x] Checked object permissions on admin history view.
This is a security fix. Disclosure and advisory coming shortly.

Patch by Russell Keith-Magee.
2013-02-12 12:13:42 +01:00
Carl Meyer d19a27066b [1.3.x] Restrict the XML deserializer to prevent network and entity-expansion DoS attacks.
This is a security fix. Disclosure and advisory coming shortly.
2013-02-12 12:13:42 +01:00
Carl Meyer 27cd872e6e [1.3.x] Added ALLOWED_HOSTS setting for HTTP host header validation.
This is a security fix; disclosure and advisory coming shortly.
2013-02-12 11:41:43 +01:00
Florian Apolloner 6e70f67470 [1.3.X] Fixed a test failure in the comment tests.
Backport of 1eb0da1c5b from master.
2012-12-10 23:37:47 +01:00
James Bennett 59a3e26425 [1.3.x] Bump version numbers for security release. 2012-12-10 15:38:03 -06:00
Florian Apolloner 2da4ace0bc [1.3.X] Fixed a security issue in get_host.
Full disclosure and new release forthcoming.
2012-12-03 13:11:34 +01:00
Florian Apolloner 1515eb46da [1.3.X] Fixed #18856 -- Ensured that redirects can't be poisoned by malicious users. 2012-11-17 23:03:15 +01:00
Preston Holmes 6383d2358c Added missed poisoned host header test material 2012-10-18 11:21:54 -07:00
James Bennett 25d23d9846 [1.3.x] Bump version numbers for security release. 2012-10-17 17:25:52 -05:00
Preston Holmes b45c377f8f Fixed a security issue related to password resets
Full disclosure and new release are forthcoming

backport from master
2012-10-17 14:43:08 -07:00
James Bennett c718b4a036 [1.3.x] Bump version numbers for bugfix release. 2012-08-01 15:06:44 -05:00
Florian Apolloner d0d5dc6cd7 [1.3.x] Fixed #18692 -- Restored python 2.4 compatibility.
Thanks to chipx86 for the report.
2012-08-01 11:01:52 +02:00
James Bennett e2ac91735f [1.3.x] Use correct download URL. 2012-07-30 16:00:55 -05:00
James Bennett 0b0c51a095 [1.3.x] Bump version numbers for security releases. 2012-07-30 15:54:15 -05:00
Florian Apolloner 4dea4883e6 [1.3.x] Fixed a security issue in http redirects. Disclosure and new release forthcoming.
Backport of 4129201c3e from master.
2012-07-30 22:03:46 +02:00
Florian Apolloner b2eb4787a0 [1.3.x] Fixed second security issue in image uploading. Disclosure and release forthcoming.
Backport of b1d4634686 from master.
2012-07-30 21:58:22 +02:00
Florian Apolloner 9ca0ff6268 [1.3.x] Fixed a security issue in image uploading. Disclosure and release forthcoming.
Backport of dd16b17099 from master.
2012-07-30 21:55:23 +02:00
Anssi Kääriäinen 7ca10b1dac Reverted "[1.3.x] Fixed #18135 -- Close connection used for db version checking"
This reverts commit a15d3b58d8. Django
1.3.x is in security fixes only state, and this wasn't a security
issue.
2012-05-28 20:41:39 +03:00
Michael Newman a15d3b58d8 [1.3.x] Fixed #18135 -- Close connection used for db version checking
On MySQL when checking the server version, a new connection could be
created but never closed. This could result in open connections on
server startup.

Backport of 4423757c0c.
2012-05-27 22:09:49 +03:00
Julien Phalip e293d82c36 [1.3.X] Fixed #17972 -- Ensured that admin filters on a foreign key respect the to_field attribute. This fixes a regression introduced in [14674] and Django 1.3. Thanks to graveyboat and Karen Tracey for the report.
Backport of r17854 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@17857 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2012-03-31 18:42:38 +00:00
Aymeric Augustin 0bbe7379ee [1.3.X] Fixed #17634 -- Optimized the performance of MultiValueDict by using append instead of copy and by minimizing the number of dict lookups. Backport of r17464 from trunk.
git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@17807 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2012-03-25 06:53:47 +00:00
Aymeric Augustin 15fb61c62c [1.3.X] Avoided a test failure if the settings module used to run the test suite is called "test_settings".
The globbing feature and this test were removed in 1.4.


git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@17806 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2012-03-24 13:56:48 +00:00
Aymeric Augustin 8e73302070 [1.3.x] Fixed #16481 -- Adapted one raw SQL query in cull implementation of the database-based cache backend so it works with Oracle. Backport of r16635 from trunk.
git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@17805 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2012-03-24 12:26:46 +00:00
Aymeric Augustin fd2efb35fb [1.3.X] Fixed #16677 -- Fixed the future version of the ssi template tag to work with template file names that contain spaces. Backport of r16687 from trunk.
git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@17804 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2012-03-24 07:43:24 +00:00
Aymeric Augustin 651c0414a8 [1.3.X] Fixed #16812 -- Percent-encode URLs in verify_exists, to fix test failures on Python 2.5 and 2.6. Backport of r16838 from trunk.
git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@17803 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2012-03-24 07:36:23 +00:00
Ramiro Morales 92929d5ef4 [1.3.X] Fixed #17488 -- This test passed in 2011 only because 2012-01-01 is a Sunday. Thanks Florian Apolloner for the report and patch.
Fixes #17912. Thanks Julien for the report.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@17759 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2012-03-17 12:58:16 +00:00
Claude Paroz 1dd8848beb [1.3.X] Fixed #17841 -- Clarified caching note about authentication backends. Thanks auzigog for the proposal and lukegb for the patch.
Backport of r17752 from trunk.


git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@17753 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2012-03-16 19:32:13 +00:00
Julien Phalip 2f6b8482f6 [1.3.X] Fixed #17908 -- Made some `contrib.markup` tests be skipped so they don't fail on old versions of Markdown. Thanks to Preston Holmes for the patch.
Backport of r17749 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@17750 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2012-03-16 00:38:18 +00:00
Julien Phalip 838adb2312 [1.3.X] Ensured that some staticfiles tests get properly cleaned up on teardown. Thanks to Claude Paroz for the patch.
Backport of r17747 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@17748 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2012-03-16 00:32:42 +00:00
Claude Paroz 2acf028b4b [1.3.X] Fixed #17900 -- StreamHandler output defaults to stderr. Thanks c4m3lo for the report.
Backport of r17741 from trunk.


git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@17742 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2012-03-15 07:58:19 +00:00
Paul McMillan 1f924cf72d [1.3.X] Fixed #17837. Improved markdown safety.
Markdown enable_attributes is now False when safe_mode is enabled. Documented
the markdown "safe" argument. Added warnings when the safe argument is
passed to versions of markdown which cannot be made safe.


git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@17734 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2012-03-14 18:51:20 +00:00
Claude Paroz d498033818 [1.3.X] Updated some outdated external URLs in docs.
Backport of r17710 from trunk.


git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@17711 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2012-03-14 07:48:03 +00:00
Claude Paroz ddfa89b959 Fixed #17584 -- Updated create_template_postgis-debian.sh script for PostgreSQL 9.1 installs. Thanks akaihola for the initial patch.
Backport of r17706 from trunk.


git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@17707 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2012-03-13 22:25:10 +00:00
Jannis Leidel 6951879023 [1.3.X] Fixed the localization docs a little to point to the correct Transifex URL. Also reworded it a bit to follow the site's new UI.
Backport from trunk (r17690).

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@17691 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2012-03-12 22:13:34 +00:00
Jannis Leidel 523d6167d6 [1.3.X] Fixed #17737 -- Stopped the collectstatic management command from copying the wrong file in repeated runs. Thanks, pigletto.
Backport from trunk (r17612).

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@17613 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2012-03-01 23:03:46 +00:00
Carl Meyer dad3e55234 [1.3.X] Fixed broken link to python-markdown in contrib.markup docs.
Backport of r17608 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@17609 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2012-03-01 19:34:23 +00:00
Timo Graham 41cd3b2ab1 [1.3.X] Fixed #17743 - Typo in topics/i18n/index.txt
git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@17587 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2012-02-25 12:55:41 +00:00
Timo Graham c0258f1da7 [1.3.X] Fixed #17757 - Typo in docs/intro/overview.txt; thanks kaushik1618.
Backport of r17584 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@17585 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2012-02-24 22:54:00 +00:00
Timo Graham 38715d8af8 [1.3.X] Fixed #17749 - Documented better way of overriding ModelAdmin; thanks chrisdpratt and claudep.
Backport of r17582 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@17583 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2012-02-24 22:50:58 +00:00
Chris Beaven b45fbc6667 [1.3.X] Don't let ALLOWED_INCLUDE_ROOTS be accidentally set to a string rather than a tuple.
Backport of r17571 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@17572 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2012-02-22 00:52:19 +00:00
Timo Graham 0af93e108e [1.3.X] Fixed #16758 - Added a warning regarding overriding default settings; thanks cyclops for the suggestion & Aymeric Augustin for the patch.
Backport of r17566 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@17567 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2012-02-20 19:08:56 +00:00
Timo Graham 4f6c36435c [1.3.X] Fixed #17390 - Added a note to topics/auth.txt regarding how to decorate class-based generic views; thanks zsiciarz for the patch.
Backport of r17564 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@17565 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2012-02-20 18:58:34 +00:00
Aymeric Augustin 4d959686e6 [1.3.X] Fixed #17319 -- Made the example for set_language less error-prone. Backport of r17560 from trunk.
git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@17561 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2012-02-19 09:22:18 +00:00
Aymeric Augustin 25b5da2abd [1.3.X] Fixed #17166 -- Documented how FIXTURE_DIRS works in the inital data how-to, and edited related bits in the settings reference. Backport of r17558 from trunk.
git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@17559 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2012-02-19 09:04:19 +00:00
Aymeric Augustin 7baee7a03b [1.3.X] Fixed #17316 -- Mentionned that the MultipleProxyMiddleware provided as an example must run rather early. Backport of r17556 from trunk.
git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@17557 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2012-02-19 08:10:20 +00:00
Aymeric Augustin 2a5a0b8097 [1.3.X] Fixed #16452 -- Clarified that the DATE/DATETIME/TIME_INPUT_FORMATS settings have no effect when USE_L10N is True. Backport of r17554 from trunk.
git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@17555 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2012-02-19 08:00:59 +00:00
Aymeric Augustin 1addaafa0a [1.3.X] Fixed #17573 -- Documented MySQL's switch to InnoDB as default storage engine. Backport of r17552 from trunk.
git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@17553 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2012-02-19 07:42:02 +00:00
Timo Graham 9729ad7466 [1.3.X] Fixed #17706 - Improved short description example in Tutorial 2; thanks xbito and claudep.
Backport of r17550 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@17551 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2012-02-18 21:51:18 +00:00
Timo Graham 5144f72be2 [1.3.X] Fixed #17685 - Typo in BaseDateListView.get_dated_items(); thanks ejb.
Backport of r17548 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@17549 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2012-02-18 21:40:26 +00:00
Aymeric Augustin 813dc01cd8 [1.3.x] Fixed #15496 -- Corrected handling of base64 file upload encoding. Backport of r16176 from trunk.
git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@17546 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2012-02-18 10:11:17 +00:00
Timo Graham c63a454bb6 [1.3.X] Updated link to Django Debug Toolbar homepage.
Thanks to rowynm AT gmail DOT com for the report and to Claude Paroz for
the patch.

Fixes #17543.

Backport of r17376 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@17523 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2012-02-14 23:05:23 +00:00
Timo Graham ce9916a2c8 Fixed #16653 - Added example of kwargs support for resolve(); thanks krzysiumed for the patch.
Backport of r17517 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@17518 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2012-02-12 17:16:37 +00:00
Timo Graham f202387e6c [1.3.X] Fixed #17618 - Documented that variable names in template must not start with an underscore; thanks guillemette and krzysiumed.
Backport of r17504 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@17505 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2012-02-11 12:47:58 +00:00
Ramiro Morales 2646df4537 [1.3.X] Fixed link to SpatiaLite 2.x initial SQL files.
Backport of [17491] and [17496] from trunk. Refs #17554.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@17498 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2012-02-11 02:07:40 +00:00
Timo Graham a7a703dbdc [1.3.X] Fixed #17571 - Fixed documentation of skipUnlessDBFeature; thanks EnTeQuAk for the report.
Backport of r17459 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@17460 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2012-02-05 15:54:01 +00:00
Timo Graham 46c08c8f95 [1.3.X] Fixed #17510 - Typo in docs/topics/class-based-views.txt; thanks andrew and noria.
Backport of r17457 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@17458 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2012-02-05 15:41:53 +00:00
Ramiro Morales 33f9ba7ba0 [1.3.X] Fixed #17240 -- Replaced links to the online version of the docs by internal references.
Backport of [17100] from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@17397 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2012-01-26 15:00:57 +00:00
Ramiro Morales 723f995658 [1.3.X] Added note about deprecation of project-level translations to the deprecation timeline document.
Thanks Jannis for the report. Fixes #17588.

Backport of [17394] from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@17395 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2012-01-25 14:33:15 +00:00
Aymeric Augustin 0d7431774f [1.3.X] Fixed #17575 -- Typo in an example of ModelAdmin.list_filter. Thanks apelisse AT gmail com for the report.
git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@17388 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2012-01-22 18:53:41 +00:00
Aymeric Augustin 405a0ba9de [1.3.X] Fixed the link to the IRC logs in the README and docs. Refs #17453, #16277. Backport of [17149] and [17385].
git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@17386 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2012-01-21 15:48:08 +00:00
Jacob Kaplan-Moss 2b793b1a35 [1.3.X] Fixed #17078: properly invoke IPython 0.12.
Backport of r17379.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@17380 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2012-01-19 17:39:59 +00:00
Carl Meyer 9bc6119daf Fixed #17538 -- corrected the section in tutorial 3 about the handler404 default. Thanks matt at brozowski dot com for the report.
Backport of r17369 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@17370 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2012-01-12 22:17:22 +00:00
Aymeric Augustin 9e12492616 [1.3.X] Fixed #17100 -- Typo in the regex for EmailValidator. Backport of r17349 from trunk.
git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@17350 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2012-01-07 18:48:12 +00:00
Aymeric Augustin a9789c0d44 [1.3.X] Fixed #17415 -- Reset database sequence for Site's pk after creating the default site with an explicit pk. Backport of r17343 from trunk.
git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@17344 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2012-01-07 09:05:36 +00:00
Carl Meyer ca14105128 [1.3.X] Clarified deployment docs to avoid giving users the impression that staticfiles should be used to actually serve files in production.
Backport of r17338 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@17339 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2012-01-04 18:35:45 +00:00
Timo Graham 79248a7e0a [1.3.X] Fixed #11986 - Added sudo to Mac OS permissions note in tutorial.
Backport of r17318 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@17319 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-12-31 15:35:04 +00:00
Timo Graham 7bee6b451a [1.3.X] Fixed #640 - Documented that changing order_with_respect_to requires a schema change; thanks fcurella and poirier for the draft patches.
Backport of r17316 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@17317 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-12-31 15:30:41 +00:00
Timo Graham 580389c588 [1.3.X] Fixed #702 - Documented that ManyToMany fields can't be in unique_together; thanks poirier for the patch.
Backport of r17314 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@17315 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-12-31 00:43:31 +00:00
Timo Graham 7b9016e5a2 [1.3.X] Fixed #17068 - Documented that documentation fixes will be more freely backported.
Backport of r17300 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@17301 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-12-30 15:31:09 +00:00
Timo Graham c9ab2bfb39 [1.3.X] Fixed #17470 - Broken links in 0.95/0.96 release notes; thanks fastinetserver for the report; aaugustin for the patch.
Backport of r17290 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@17291 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-12-30 12:29:47 +00:00
Aymeric Augustin b5853cf043 [1.3.X] Fixed #16632 -- Crash on responses without Content-Type with IE. Backport of r17196.
git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@17198 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-12-11 10:09:15 +00:00
Aymeric Augustin 68f37a9081 [1.3.X] Backported the fix for #15852 -- Modified cookie parsing so it can handle duplicate invalid cookie names. Thanks goes to Fredrik Stålnacke for the report and to vung for the patch.
git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@17168 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-12-03 21:17:41 +00:00
Timo Graham bf5fdf1397 [1.3.X] Fixed #17028 - Changed diveintopython.org -> diveintopython.net
Backport of r17115 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@17116 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-11-19 22:57:47 +00:00
Carl Meyer eabbb361d2 [1.3.X] Fixed #17171 -- Updated tutorial urls.py code snippets to match startproject template and recommended practice. (No 'import *', use 'urls()' function.). Thanks haimunt for report.
Parts of this are a backport of r17073 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@17074 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-11-06 16:59:26 +00:00
Carl Meyer 6372368b56 [1.3.X] Fixed #17123 -- corrected the path to admin static assets in 1.3 docs. Thanks glarrain for the report.
git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@17044 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-10-27 16:10:08 +00:00
Carl Meyer 07c404be88 [1.3.X] Refs #16072 -- Corrected blocktrans multiple-argument syntax example in the docs.
git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@17011 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-10-18 18:09:23 +00:00
Paul McMillan a084a07ebe [1.3.X] Fixed #16910 -- Misleading urlpatterns docs regex example.
git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16892 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-09-22 23:02:57 +00:00
Paul McMillan e3bc259081 [1.3.X] Reverting r16878 (improved admin error message) per advice from jezdez. refs #16837
git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16891 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-09-22 22:55:47 +00:00
Paul McMillan ed156a44ca [1.3.X] Fixed #11674 -- Clarified docs on excluded fields of ModelForms. Thanks PieterSwinkels for the patch.
git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16881 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-09-22 05:48:42 +00:00
Paul McMillan 4443c6fd72 [1.3.X] Spelling fix for r16879.
git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16880 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-09-22 05:40:54 +00:00
Paul McMillan 35e807c4a5 [1.3.X] Fixed #15633 -- Improved docs for post_syncdb signal. Thanks Justin Lilly for the patch.
git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16879 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-09-22 05:39:07 +00:00
Paul McMillan 2a4aa8bcf7 [1.3.X] Fixed #16837 -- Improved error messages for admin login. Thanks Wim Feijen for the patch.
git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16878 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-09-22 05:36:57 +00:00
Paul McMillan 5978d7a341 [1.3.X] backport minor docs fix for GeoIP
git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16870 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-09-22 00:58:42 +00:00
Carl Meyer 65942eb31f [1.3.X] Fixed #16353 -- don't try to create Site objects on all databases. Refs #15573, #15346. Thanks Aymeric Augustin for the report and the patch.
Backport of r16868 in trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16869 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-09-21 22:58:15 +00:00
Simon Meers 3606f1f7b2 [1.3.X] Fixed #16904 -- Additional clarification regarding contrib.messages iteration. Thanks murphyke for the report and patch.
Backport of [16866] from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16867 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-09-21 22:45:25 +00:00
Simon Meers add0628528 [1.3.X] Fixed #16886 -- Memcached socket file documentation. Thanks ddbeck for the report and patch.
Backport of [16858] from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16859 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-09-21 01:37:17 +00:00
Justin Bronn ae51b46d19 [1.3.X] Fixed #14648 -- Fixed annotated date querysets when `GeoManager` is used. Thanks, codysoyland, for the bug report.
Backport of r16796 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16844 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-09-17 18:08:28 +00:00
Carl Meyer c9676d035f [1.3.X] Fixed #16094 -- Added missing colon in custom permissions docs.
Backport of r16836 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16837 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-09-16 10:57:53 +00:00
Julien Phalip 27c8d61280 [1.3.X] Reverted the change in r16684, which, while fixing an alignment issue in IE7 with the admin's "Save and continue editing" and "Save and add another" buttons, caused the swapping of those buttons' order. Thanks to jocmeh for the report. Refs #16852.
git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16834 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-09-16 06:26:22 +00:00
Carl Meyer ee23919a8a [1.3.X] Fixed #16839 - Added basic release notes for 1.2.7. Thanks claudep for the report.
Backport of r16803 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16828 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-09-14 20:33:55 +00:00
Carl Meyer 70a6901775 [1.3.X] Refs #16839 - Added basic release notes for 1.2.6 and 1.3.1.
Backport of r16777 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16827 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-09-14 20:33:42 +00:00
James Bennett 2c8e45e1f4 [1.3.X] Fixed #16334: Make it quite clear that cache_page's 'cache' argument refers to the name of a cache in the CACHES setting. Backport of [16815] from trunk.
git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16816 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-09-11 05:58:34 +00:00
James Bennett 460150975c [1.3.X] Fixed #16094: Added clear example of how to refer to custom permissions. Backport of [16813] from trunk.
git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16814 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-09-11 05:48:39 +00:00
James Bennett 16787c6903 [1.3.X] Fixed #16109: Corrected an inconsistency in URLconf examples for matching a numeric month. Backport of [16811] from trunk.
git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16812 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-09-11 05:45:26 +00:00
James Bennett f242c02fb9 [1.3.X] Fixed #16293: Document a way to return dicts with column names from a DB cursor. Backport of [16808] from trunk.
git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16809 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-09-11 05:38:50 +00:00
James Bennett 0326e2e611 [1.3.X] Fixed #16552: Noted that contrib.sessions is a requirement for the admin. Backport of [16806] from trunk.
git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16807 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-09-11 05:32:14 +00:00
James Bennett 2954c36ff7 [1.3.X] Fixed #16079: Clarified (for real this time) how handler404 and handler500 work, and that they only work in a root URLconf. Backport of [16804] from trunk.
git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16805 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-09-11 04:06:29 +00:00
James Bennett 5e451b9e6f [1.3.X] Bump docs version number, too.
git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16768 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-09-10 01:34:55 +00:00
James Bennett 722d4068a7 [1.3.X] Bump to 1.3.1 for security release.
git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16767 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-09-10 01:32:14 +00:00
Russell Keith-Magee 1a76dbefdf [1.3.X] Altered the behavior of URLField to avoid a potential DOS vector, and to avoid potential leakage of local filesystem data. A security announcement will be made shortly.
Backport of r16760 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16763 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-09-10 01:08:24 +00:00
Russell Keith-Magee fbe2eead2f [1.3.X] Corrected an issue which could allow attackers to manipulate session data using the cache. A security announcement will be made shortly.
Backport of r16759 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16762 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-09-10 01:08:02 +00:00
Russell Keith-Magee 2f7fadc38e [1.3.X] Added protection against spoofing of X_FORWARDED_HOST headers. A security announcement will be made shortly.
Backport of r16758 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16761 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-09-10 01:07:50 +00:00
Gabriel Hurley afe47636f7 [1.3.X] Fixed #16782 -- Corrected a broken cross-reference to the database engine setting in the tutorial. Thanks to mjumbewu for the report and patch.
Backport of r16754 from trunk.


git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16755 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-09-09 23:27:31 +00:00
Justin Bronn 52279a4113 [1.3.X] Fixed #16408 -- Fixed conversion of dates, and other problems with the SpatiaLite backend.
Backport of r16749 and r16750 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16751 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-09-09 22:50:03 +00:00
Gabriel Hurley 1f7c6c011a [1.3.X] Fixed #16791 -- Updated a broken URL in the README file. Thanks to paulcwatts for the report and patch.
Backport of r16743 from trunk.


git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16744 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-09-09 21:43:11 +00:00
Julien Phalip 71836f4c76 [1.3.X] Fixed a small admin CSS issue where the "Save and continue editing" and "Save and add another" buttons were wrongly aligned with left-to-right languages in IE7.
Backport of r16683 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16684 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-08-25 08:13:28 +00:00
Russell Keith-Magee 8b42dfa47e [1.3.X] Corrected the setup and teardown of the refactored invalid_models test so that it guarantees that stdout is restored, and purges all the temporary models from the app cache after running the test.
Backport of r16670 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16677 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-08-23 15:57:19 +00:00
Russell Keith-Magee e2d7a784c8 [1.3.X] Fixed #16201 -- Ensure that requests with Content-Length=0 don't break the multipart parser. Thanks to albsen for the report and patch
Backport of r16353 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16676 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-08-23 15:57:01 +00:00
Russell Keith-Magee f317bd20d7 [1.3.X] Fixed #16299 -- Ensure that unicode strings can be used to identify classes in ForeignKey and ManyToManyFields. Unicode strings aren't actually legal as class names, but this is an issue if you use from __future__ import unicode_literals in your models.py file. Thanks to Martijn Bastiaan for the report, and Anthony Briggs for the final patch.
Backport of r16663 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16675 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-08-23 15:56:40 +00:00
Russell Keith-Magee 38530700bf [1.3.X] Fixed #16681 -- Refactored the invalid_models unit test so that it can be invoked manually. Thanks to Anthony Briggs for the report and patch.
Backport of r16661 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16674 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-08-23 15:56:18 +00:00
Russell Keith-Magee 3e7d79b6ac [1.3.X] Fixed #15499 -- Ensure that cache control headers don't try to set public and private as a result of multiple calls to patch_cache_control with different arguments. Thanks to AndiDog for the report and patch.
Backport of r16657 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16673 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-08-23 15:55:48 +00:00
Russell Keith-Magee e9a1c03dba [1.3.X] Fixed #10571 -- Factored out the payload encoding code to make sure it is used for PUT requests. Thanks to kennu for the report, pterk for the patch, and wildfire for the review comments.
Backport of r16651 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16672 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-08-23 15:55:22 +00:00
Russell Keith-Magee 671483f37b [1.3.X] Fixed #14876 -- Ensure that join promotion works correctly when there are nullable related fields. Thanks to simonpercivall for the report, oinopion and Aleksandra Sendecka for the original patch, and to Malcolm for helping me wrestle the edge cases to the ground.
Backport of r16648 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16671 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-08-23 15:54:45 +00:00
Julien Phalip a7ec5c433c [1.3.X] Fixed #16680 -- Used single quotes for the TEMPLATE_DIRS examples in part 2 of the tutorial to be consistent with the settings.py file generated by the startproject command. Thanks, Michael Tomkins.
Backport of r16660 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16666 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-08-23 06:00:08 +00:00
Julien Phalip e71d0133bd [1.3.X] Fixed #16669 -- Made the startproject instruction formatting easier to read and more consistent with other formatting in the tutorial part 1. Thanks to Daniel Lawrence and Aymeric Augustin.
Backport of r16664 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16665 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-08-23 05:59:54 +00:00
Timo Graham 6f9d250698 [1.3.X] Fixed #16654 - Syntax error in reverse() example; thanks jedie.
Backport of r16630 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16631 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-08-20 19:28:25 +00:00
Timo Graham 329d80faab [1.3.X] Fixed #16595 - Add pop() to session docs; thanks wilfred.
Backport of r16628 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16629 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-08-20 19:23:16 +00:00
Timo Graham 3e5fc7ebb1 [1.3.X] Fixed #16430 - Stronger wording for CSRF protection in `modifying upload handlers on the fly`; thanks tomchristie.
Backport of r16588 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16589 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-08-06 20:34:19 +00:00
Timo Graham 199f10f9c0 [1.3.X] Fixed #16513 - Add forms import to example; thanks teraom.
Backport of r16586 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16587 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-08-06 19:02:56 +00:00
Timo Graham 4217f358c0 [1.3.X] Fixed #16528 - Documented test runner returns 1, regardless of the number of test failures; thanks teraom.
Backport of r16584 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16585 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-08-06 18:54:40 +00:00
Timo Graham fe96e20a3e [1.3.X] Fixed #16580 - Typo in docs/ref/models/querysets.txt
Backport of r16582 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16583 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-08-06 18:50:19 +00:00
Timo Graham 1959aa939d [1.3.X] Fixed #16566 - Typo in docs/ref/files/storage.txt; thanks thejaswi_puthraya.
Backport of r16580 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16581 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-08-06 18:41:00 +00:00
Jannis Leidel c0fa1965e2 [1.3.X] Fixed #16531 -- Fixed various instances of "undefined name" issues. Thanks, Bruno Renié.
Backport from trunk (r16557).

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16571 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-07-29 09:48:05 +00:00
Chris Beaven 41e086cfb5 [1.3.X] Fixes #16532 -- Clearer explanation of how the test client expects HTTP headers to be passed. Thanks for the patch, Ricardo Bánffy.
Backport of r16554 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16555 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-07-28 22:10:27 +00:00
Brian Rosner 2a1874521e [1.3.X] Added a note about the AJAX CSRF example not working on jQuery 1.5
Backport of [16543] from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16544 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-07-14 19:40:30 +00:00
Ramiro Morales a925b3780e [1.3.X] Reverted [14563] because it introduced a dependency from core on a contrib app (contenttypes). Fixes #16283, Refs #3055. Thanks TheRoSS for the report and Aymeric Augustin for finding the problem.
This caused models shipped with some contrib apps to pollute the namespace when user's apps had the same name (e.g. auth, sites), even when these contrib apps weren't installed.

This undesired loading of contrib apps happened when model validation was executed, for example when running management commands that set or inherit `requires_model_validation=True`:
cleanup, dumpdata, flush, loaddata, reset, runfcgi, sql, sqlall, sqlclear, sqlcustom, sqlflush, sqlindexes, sqlinitialdata, sqlreset, sqlsequencereset, syncdb, createsuperusers, ping_google, collectstatic, findstatic.

This could also cause hard to diagnose problems e.g. when performing reverse URL resolving.

Backport of [16493] from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16541 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-07-14 00:27:55 +00:00
Simon Meers 220ce42333 [1.3.X] Fixed #16000 -- reference natural keys in contenttypes documentation. Thanks jsdalton.
Backport of r16536 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16537 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-07-10 21:52:50 +00:00
Simon Meers c828cc1ba6 [1.3.X] Fixed #15715 -- added non-trivial decorator example to CBV docs. Thanks toofishes.
Backport of r16534 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16535 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-07-10 21:40:14 +00:00
Simon Meers 00886dfd2b [1.3.X] Fixed #16440 -- minor ungettext documentation issue, thanks Bradley Ayers.
Backport of r16532 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16533 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-07-10 21:33:42 +00:00
Jannis Leidel 5a0787f904 [1.3.X] Fixed #15974 -- Correctly link to static files handling in deployment docs. Thanks, RogueBean.
Backport from trunk (r16491).

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16492 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-07-01 15:19:34 +00:00
Justin Bronn a441032e0e [1.3.X] Fixed #16232 -- Corrected typo in geographic admin reference. Thanks, Issac Kelly.
Backport of r16484 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16486 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-06-29 16:40:31 +00:00
Simon Meers d8ef686e24 [1.3.X] Fixed #16297 -- make_list documentation error regarding integers. Thanks ned and teraom.
Backport of r16468 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16469 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-06-26 21:29:13 +00:00
Timo Graham a0285bb612 [1.3.X] Fixed #16258 - typo in middleware docs.
Backport of r16441 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16442 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-06-19 19:40:50 +00:00
Jannis Leidel d90bd88d73 [1.3.X] Fixed #16292 -- Removed broken link for Swiss localflavor documentation. Thanks, BernhardEssl.
Backport from trunk (r16435).

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16436 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-06-18 12:01:10 +00:00
Jannis Leidel 7880d99900 [1.3.X] Fixed #16031 -- Corrected comments template examples. Thanks, teraom.
Backport from trunk (r16412).

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16421 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-06-16 16:42:54 +00:00
Jannis Leidel 25ee9b4913 [1.3.X] Fixed #16273 -- Fixed typo in staticfiles docs. Thanks, BernhardEssl.
Backport from trunk (r16407).

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16409 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-06-16 15:28:12 +00:00
Jannis Leidel eb96665b7a [1.3.X] Added a few cross references to the i18n docs and documented pgettext and colleagues.
Backport from trunk (r16403).

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16404 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-06-15 10:50:08 +00:00
Timo Graham 4f215cfcd7 Fixed #15764 - Corrected mixin docs for DeleteView; thanks linovia for the report.
git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16380 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-06-12 00:26:43 +00:00
Timo Graham 5d71bec5e4 [1.3.X] Fixed #15949 - Clarified the docs for password_reset_done view; thanks cyclops for the suggestion; Horst Gutmann for the patch.
Backport of r16378 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16379 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-06-11 23:41:28 +00:00
Timo Graham 1b51aa74b8 [1.3.X] Fixed #16158 - Changed FALLBACK_DYLD_LIBRARY_PATH to DYLD_FALLBACK_LIBRARY_PATH in GIS documentation; thanks adam for the report.
Backport of r16364 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16365 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-06-11 09:35:36 +00:00
Carl Meyer a5b44ed873 [1.3.X] Refs #15855 -- Recommended the csrf_protect decorator rather than vary_on_cookie as workaround for cache_page caching the response before it gets to middleware.
Backport of r16361 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16362 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-06-10 16:19:56 +00:00
Karen Tracey c1baaa8c87 [1.3.X] Fix #15880: Prevent "stalling" when running dev server in background by ignoring SIGTTOU for the duration of tcsetattr.
Backport of [16326] from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16327 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-06-04 15:31:41 +00:00
Timo Graham f578563291 [1.3.X] Fixed #16145 - typo in manager docs; thanks leereilly.
Backport of r16324 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16325 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-06-04 14:39:16 +00:00
Luke Plant 0e90de0a15 [1.3.X] Fixed #16144 - layout of admin changelist broken for RTL languages.
Backport of [16314] from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16315 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-06-02 12:20:11 +00:00
Timo Graham 9f71bef7e9 [1.3.X] Fixed #16090, #16091 - Typos in docs; thanks teraom.
Backport of r16300 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16302 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-05-31 09:44:21 +00:00
Timo Graham d2abec535e [1.3.X] Fixed #15801 - Incorrect external link for dictConfig; thanks David Niergarth for the report; jonash for the patch.
Backport of r16100 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16301 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-05-31 09:44:18 +00:00
Luke Plant 6e87dacf62 [1.3.X] Fixed #15776 - delete regression in Django 1.3 involving nullable foreign keys
Many thanks to aaron.l.madison for the detailed report and to emulbreh for
the fix.

Backport of [16295] from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16296 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-05-30 16:19:53 +00:00
Timo Graham 4124ef339c [1.3.X] Fixed #16093 - Typo in "Performing raw SQL queries"; thanks direvus.
Backport of r16293 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16294 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-05-30 12:11:46 +00:00
Jannis Leidel 879267f254 [1.3.X] Fixed #15992 -- Added more references to settings. Thanks, aaugustin.
Backport from trunk (r16290).

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16291 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-05-29 17:50:52 +00:00
Luke Plant 7f3eda2f76 [1.3.X] Fixed #16004 - csrf_protect does not send cookie if view returns TemplateResponse
The root bug was in decorator_from_middleware, and the fix also corrects
bugs with gzip_page and other decorators.

Backport of [16276] from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16279 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-05-25 17:31:47 +00:00
Luke Plant afa092853f [1.3.X] Changed utils/decorators.py tests to use RequestFactory
Backport of [16272] from trunk. Backported to make the backport of a
bugfix (regression) easier.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16278 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-05-25 17:31:36 +00:00
Chris Beaven 18ecfad767 [1.3.X] Fixes #16072 -- incorrect documentation for multiple expressions inside a blocktrans tag
Backport of r16268 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16269 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-05-23 01:54:37 +00:00
Timo Graham b9bdc96f9e [1.3.X] Fixed #16056 - Memcached configuration mistake in docs; thanks antonio/d0ugal.
Backport of r16265 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16266 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-05-22 17:00:23 +00:00
Timo Graham 82b9fed1c7 [1.3.X] Fixed #16067 - Couple reST fixes in ref/templates/builtins.txt; thanks julien.
Backport of r16263 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16264 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-05-22 16:44:14 +00:00
Timo Graham 2c3d3400ef [1.3.X] Fixed #16051 - Changed a "file" reference in the tutorial to be an actual file rather than a module; thanks felix.morency for the suggestion.
Backport of r16258 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16259 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-05-22 00:13:08 +00:00
Timo Graham 08f5ac3d51 [1.3.X] Fixed #16021 - Minor documentation fixes for Generic Class Views; thanks Bradley Ayers.
Backport of r16256 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16257 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-05-22 00:08:40 +00:00
Chris Beaven b5c6b4f1d4 [1.3.X] Tweaks to paginator documentation.
Backport of 16248 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16249 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-05-20 01:48:41 +00:00
Chris Beaven be776521db [1.3.X] Tidy up the sessions documentation creating links for session methods and crosslinking settings
Backport of r16245 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16246 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-05-20 00:52:36 +00:00
Ramiro Morales 770b91ca7b [1.3.X] Fixed small typos in staticfiles howto document.
git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16244 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-05-19 02:51:39 +00:00
Gabriel Hurley d12ac6d048 git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16243 bcc190cf-cafb-0310-a4f2-bffc1f526a37 2011-05-18 20:35:32 +00:00
Gabriel Hurley 49f4a28cce [1.3.X] Fixed #16044 -- Corrected a copy-and-paste error in the opening paragraph of the views topic guide. Thanks to aplanas for the report and suggested wording.
Backport of [16240] from trunk.


git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16241 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-05-18 20:12:15 +00:00
Jannis Leidel e1dfa95cd1 [1.3.X] Fixed #15983 and #16032 -- Another pass over the staticfiles docs. Many thanks to Frank Wiles and EvilDMP.
Backport form trunk (r16235).

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16236 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-05-18 09:52:44 +00:00
Timo Graham 5be8fdb03e [1.3.X] Fixed #15769 - Documented FormWizard's initial argument; thanks aimaz for the suggestion; jrothenbuhler for the patch.
Backport of r16229 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16230 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-05-15 19:12:29 +00:00
Simon Meers 8385b31c89 [1.3.X] Fixed #16014 -- numerous documentation typos -- thanks psmith.
Backport of r16220 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16221 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-05-13 04:39:49 +00:00
Simon Meers fc39163177 [1.3.X] Fixed #16005 -- Error in blocktrans docs -- thanks bezidejni
Backport of r16218 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16219 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-05-13 00:49:26 +00:00
Chris Beaven 9a4e5112b2 [1.3.X] Fixes #15595 -- emphasize the benefits of django.test.TestCase. Thanks for the patch Shawn Milochik
Backport of r16214 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16215 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-05-11 21:30:05 +00:00
Luke Plant 5c08cda611 [1.3.X] Fixed #13648 - '%s' escaping support for sqlite3 regression.
Thanks to master for the report and initial patch, and salgado and others
for work on the patch.

Backport of [16209] from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16210 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-05-10 12:28:29 +00:00
Chris Beaven 7fd113e618 [1.3.X] Fixes #15963 -- Misleading FileField.save documentation. Thanks for the report and patch, ejucovy.
Backport of r16207 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16208 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-05-10 00:28:05 +00:00
Chris Beaven 4cb2b53c22 [1.3.X] Fixes #15588 -- 1.3 release documentation for FileField no longer deleting files unclear. Thanks for the patch, Philip Neustrom.
Backport of r16205 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16206 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-05-10 00:20:21 +00:00
Luke Plant fda65ffea5 [1.3.X] Updated AJAX example code in CSRF docs to be consistent regarding what are safe HTTP methods
Backport of [16202] from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16203 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-05-09 23:47:50 +00:00
Simon Meers af1943f139 [1.3.X] Fixed #15989 -- typo in static-files howto. Thanks luizvital.
Backport of r16195 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16196 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-05-09 22:31:07 +00:00
Luke Plant fb052a15ed [1.3.X] Fixed #15469 - CSRF token is inserted on GET requests
Thanks to goran for report.

Backport of [16191] from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16193 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-05-09 21:37:52 +00:00
Luke Plant b3a4613595 [1.3.X] Fixed #15869 - example AJAX code in CSRF docs fails sometimes for IE7 or absolute same origin URLs
Thanks to nick for the report.

Backport of [16183] from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16184 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-05-09 15:45:10 +00:00
Chris Beaven d06531d3f0 [1.3.X] Fixes #15975 -- Test failure in model validation tests due to us now having https://www.djangoproject.com
Backport of r16163 from trunk

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16164 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-05-05 23:12:55 +00:00
Timo Graham 64e625b6a1 [1.3.X] Fixed #15827 - Documented that OneToOneField in Profile should be named 'user'; thanks lawgon.
Backport of r16155 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16156 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-05-04 23:44:54 +00:00
Timo Graham 53354f80f6 [1.3.X] Fixed #15942 - removed duplicate module id in docs; thanks magopian.
Backport of r16142 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16143 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-05-03 10:25:50 +00:00
Timo Graham fa261ea432 [1.3.X] Fixed #15887 - Added clarification for required_*() decorators; thanks RoySmith for the sugggestion.
Backport of r16139 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16140 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-05-01 20:11:04 +00:00
Jannis Leidel b44757ce51 [1.3.X] Fixed #6581 -- Moved documentation of django.contrib.auth.views.redirect_to_login to an own "Helper functions" section.
Backport form trunk (r16130).

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16131 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-04-30 13:37:53 +00:00
Timo Graham c05dd20fa5 [1.3.X] Fixed #15876 - Document that test.client.RequestFactory doesn't support sessions or request-altering middleware; thanks slinkp for the suggestion, ShawnMilo for the patch.
Backport of r16128 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16129 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-04-30 13:02:47 +00:00
Ramiro Morales 0e9e0f0b21 [1.3.X] Fixed small typos in custom template tags docs.
Backport of [16126] from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16127 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-04-30 02:48:56 +00:00
Simon Meers 5aeeafba26 [1.3.X] Fixed #15865 -- correct class name for BaseGenericInlineFormset. Thanks leonelfreire for the report.
Backport of r16113 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16114 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-04-28 01:47:21 +00:00
Simon Meers 637cf5de3a [1.3.X] Fixed #15830 -- Add documentation regarding localflavor i18n. Thanks framos.
Backport of r16109 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16110 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-04-28 00:23:42 +00:00
Timo Graham 44dbac6482 [1.3.X] Fixed #15853 - typo in m2m_changed signal documentation; thanks elbarto.
Backport of r16098 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16099 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-04-24 23:47:36 +00:00
Timo Graham f53fe1e79e [1.3.X] Fixed #15875 - typo in F() example; thanks jblaine.
Backport of r16096 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16097 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-04-23 21:49:22 +00:00
Carl Meyer 6a3d91828f [1.3.X] Fixed #15819 - Fixed 1.3 regression from r15526 causing duplicate search results in admin with search_fields traversing to non-M2M related models. Thanks to Adam Kochanowski for the report and Ryan Kaskel for the patch.
Backport of r16093 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16094 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-04-23 04:40:06 +00:00
Chris Beaven fe2713dd5e [1.3.X] Fixes #15862 -- Error in post_syncdb documentation example. Thanks for the report and patch andialbrecht.
Backport of r16091 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16092 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-04-22 21:25:16 +00:00
Chris Beaven 9269b606ba [1.3.X] Fixes regression #15721 -- {% include %} and RequestContext not working together. Refs #15814.
Backport of r16031, plus the utility from r16030.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16089 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-04-22 21:05:29 +00:00
Jannis Leidel 5977193c01 [1.3.X] Fixed #15758 -- Removed stale constants that were missed in r15983.
Backport from trunk (r16084).

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16085 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-04-22 12:28:58 +00:00
Jannis Leidel e87c9da437 [1.3.X] Fixed #15672 -- Refined changes made in r15918. Thanks, vung.
Backport from trunk (r16082).

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16083 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-04-22 12:21:58 +00:00
Jannis Leidel 4d62386cad [1.3.X] Fixed #15698 -- Fixed inconsistant handling of context_object_name in paginated MultipleObjectMixin views. Thanks, Dave Hall.
Backport from trunk (r16079).

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16080 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-04-22 12:06:11 +00:00
Ian Kelly 53678ef508 [1.3.X] Refs #15573, #15850: Added a check for whether the sites app is installed when creating the test database, in order to work around a bug in get_model. Thanks to adsva and carljm.
git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16062 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-04-21 17:43:22 +00:00
Gabriel Hurley 64995cdd63 [1.3.X] Fixed #15794 -- Corrected an error in the docs which indicated applying decorators to any of the view-like methods would work when it will only work reliably with dispatch. Thanks to carbonXT for the report and patch.
Backport of [16056] from trunk.


git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16057 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-04-20 20:04:46 +00:00
Gabriel Hurley 24adaf76f1 [1.3.X] Fixed #15593 -- Added a note that the output of `reverse` is urlquoted. Thanks to guettli for the report and draft patch.
Backport of [16054] from trunk.


git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16055 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-04-20 19:51:54 +00:00
Gabriel Hurley b061cb97be [1.3.X] Fixed #15843 -- removed an extraneous quotation mark in the template tag docs. Thanks to Titan, Jer-ming Lin for the report.
Backport of [16042] from trunk.


git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16043 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-04-18 23:20:07 +00:00
Ramiro Morales 1d499d50d0 [1.3.X] Fixed #15848 -- Fixed regression introduced in [15882] in makemessages management command when processing multi-line comments that contain non-ASCCI characters in templates. Thanks for the report Denis Drescher.
Backport of r16038/r16039 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16040 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-04-18 21:10:42 +00:00
Jacob Kaplan-Moss 9b21a0c921 [1.3.X] Updated the contributing document to accurately reflect our security process.
Backport of [16032] from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16033 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-04-17 14:27:53 +00:00
Karen Tracey cdd75e078a [1.3.X] Ensure stdin is a tty before handing it to termios, so as to prevent prolems when running under IDEs.
Backport of [15911] from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16029 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-04-17 04:12:01 +00:00
Ian Kelly 79bb9c1456 [1.3.X] Fixed #15573: Forced the default site id to be 1 when creating
test databases, to prevent a large number of errors when running the 
tests using the oracle backend. Backport of r16027 from trunk.


git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16028 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-04-16 18:43:01 +00:00
Simon Meers 05054aba76 [1.3.X] Fixed #15746. Clarified updated list_filter documentation.
Backport of r16010 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16011 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-04-03 23:09:39 +00:00
Russell Keith-Magee e5aa2bdcec [1.3.X] Fixed #15672 -- Fixed bug in core/handlers/wsgi.py where we were referring to the 'request' variable before assigning to it. Thanks for the report, vkryachko
Backport of r15918 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@16009 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-04-03 00:11:29 +00:00
Russell Keith-Magee 686ef6c759 [1.3.X] Fixed #15739 -- Added support to RedirectView for HEAD, OPTIONS, POST, PUT and DELETE requests
Backport of r15992 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@15995 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-04-02 08:50:05 +00:00
Jannis Leidel e6fe336f10 [1.3.X] Fixed #15681 -- Fixed a documentation error regarding the default value of the STATIC_URL setting. Thanks, Chris Drackett.
Backport from trunk (r15913 and r15914).

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@15966 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-03-31 23:20:55 +00:00
Jannis Leidel 6bf0fe6c4e [1.3.X] Fixed #15726 -- Fixed the name of a file of the Mexican Spanish translation added in r15433.
Backport from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@15963 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-03-31 08:35:20 +00:00
Justin Bronn e37fae7fb9 [1.3.X] Fixed `LayerMapping` to support `BigIntegerField`.
Backport of r15961 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@15962 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-03-30 19:26:11 +00:00
Justin Bronn 032beb11da [1.3.X] Fixed integer overflows that occurred when `OFTReal` fields were treated as `OFTInteger`.
Backport of 15946 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@15960 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-03-30 18:49:42 +00:00
Timo Graham d935b232a2 [1.2.X] Fixed #15710 - removed "that that" typos.
Backport of r15942 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@15943 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-03-29 10:25:18 +00:00
Luke Plant ce9b216882 [1.3.X] Fixed #15679 - regression in HttpRequest.POST and raw_post_data access.
Thanks to vkryachko for the report.

This also fixes a slight inconsistency with raw_post_data after parsing of a
multipart request, and adds a test for that.  (Previously accessing
raw_post_data would have returned the empty string rather than raising an
Exception).

Backport of [15938] from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@15939 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-03-28 16:15:43 +00:00
Timo Graham 9b0f1de566 [1.3.X] Fixed #15664 - Removed extra parens in commit_on_success example.
Backport of r15923 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@15924 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-03-27 23:01:47 +00:00
Ramiro Morales 258957f4b9 [1.3.X] Bumped django_next_version so that "New in Django 1.3" links appear correctly.
Backport of [15909] from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@15920 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-03-26 13:19:04 +00:00
Simon Meers d0052fcc5c [1.3.X] Fixed a few typos in the 1.3 release notes.
Backport of r15907 from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@15908 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-03-23 08:52:39 +00:00
James Bennett 81f7a6587f Create 1.3 release branch.
git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.3.X@15905 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2011-03-23 06:01:52 +00:00
226 changed files with 4132 additions and 1717 deletions

View File

@ -92,6 +92,7 @@ answer newbie questions, and generally made Django that much better:
Sean Brant
Andrew Brehaut <http://brehaut.net/blog>
David Brenneman <http://davidbrenneman.com>
Anthony Briggs <anthony.briggs@gmail.com>
brut.alll@gmail.com
bthomas
btoll@bestweb.net

4
README
View File

@ -28,7 +28,7 @@ http://code.djangoproject.com/newticket
To get more help:
* Join the #django channel on irc.freenode.net. Lots of helpful people
hang out there. Read the archives at http://botland.oebfare.com/logger/django/.
hang out there. Read the archives at http://django-irc-logs.com/.
* Join the django-users mailing list, or read the archives, at
http://groups.google.com/group/django-users.
@ -42,5 +42,5 @@ To run Django's test suite:
* Follow the instructions in the "Unit tests" section of
docs/internals/contributing.txt, published online at
http://docs.djangoproject.com/en/dev/internals/contributing/#running-the-unit-tests
https://docs.djangoproject.com/en/dev/internals/contributing/writing-code/unit-tests/#running-the-unit-tests

View File

@ -1,4 +1,4 @@
VERSION = (1, 3, 0, 'final', 0)
VERSION = (1, 3, 8, 'alpha', 0)
def get_version():
version = '%s.%s' % (VERSION[0], VERSION[1])

View File

@ -70,6 +70,9 @@ class BaseSettings(object):
if name in ("MEDIA_URL", "STATIC_URL") and value and not value.endswith('/'):
warnings.warn('If set, %s must end with a slash' % name,
PendingDeprecationWarning)
elif name == "ALLOWED_INCLUDE_ROOTS" and isinstance(value, basestring):
raise ValueError("The ALLOWED_INCLUDE_ROOTS setting must be set "
"to a tuple, not a string.")
object.__setattr__(self, name, value)

View File

@ -29,6 +29,10 @@ ADMINS = ()
# * Receive x-headers
INTERNAL_IPS = ()
# Hosts/domain names that are valid for this site.
# "*" matches anything, ".example.com" matches example.com and all subdomains
ALLOWED_HOSTS = ['*']
# Local time zone for this installation. All choices can be found here:
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name (although not all
# systems may support all possibilities).
@ -399,6 +403,8 @@ URL_VALIDATOR_USER_AGENT = "Django/%s (http://www.djangoproject.com)" % get_vers
DEFAULT_TABLESPACE = ''
DEFAULT_INDEX_TABLESPACE = ''
USE_X_FORWARDED_HOST = False
##############
# MIDDLEWARE #
##############

View File

@ -20,6 +20,10 @@ DATABASES = {
}
}
# Hosts/domain names that are valid for this site; required if DEBUG is False
# See https://docs.djangoproject.com/en/1.3/ref/settings/#allowed-hosts
ALLOWED_HOSTS = []
# Local time zone for this installation. Choices can be found here:
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
# although not all choices may be available on all operating systems.

View File

@ -74,9 +74,12 @@ class RelatedFilterSpec(FilterSpec):
self.lookup_title = other_model._meta.verbose_name
else:
self.lookup_title = f.verbose_name # use field name
rel_name = other_model._meta.pk.name
if hasattr(f, 'rel'):
rel_name = f.rel.get_related_field().name
else:
rel_name = other_model._meta.pk.name
self.lookup_kwarg = '%s__%s__exact' % (self.field_path, rel_name)
self.lookup_kwarg_isnull = '%s__isnull' % (self.field_path)
self.lookup_kwarg_isnull = '%s__isnull' % self.field_path
self.lookup_val = request.GET.get(self.lookup_kwarg, None)
self.lookup_val_isnull = request.GET.get(
self.lookup_kwarg_isnull, None)
@ -176,7 +179,7 @@ FilterSpec.register(lambda f: bool(f.choices), ChoicesFilterSpec)
class DateFieldFilterSpec(FilterSpec):
def __init__(self, f, request, params, model, model_admin,
field_path=None):
field_path=None):
super(DateFieldFilterSpec, self).__init__(f, request, params, model,
model_admin,
field_path=field_path)

View File

@ -46,6 +46,11 @@ th {
float: left;
}
thead th:first-child,
tfoot td:first-child {
border-left: 1px solid #ddd !important;
}
/* LAYOUT */
#user-tools {
@ -73,6 +78,19 @@ div.breadcrumbs {
margin-right: 10px !important;
}
/* SORTABLE TABLES */
table thead th.sorted a {
padding-left: 13px;
padding-right: 0px;
}
table thead th.ascending a,
table thead th.descending a {
background-position: left;
}
/* dashboard styles */
.dashboard .module table td a {
@ -102,7 +120,7 @@ div.breadcrumbs {
border-right: 1px solid #ddd;
}
.change-list .filtered table, .change-list .filtered .paginator, .filtered #toolbar, .filtered div.xfull {
.change-list .filtered .results, .change-list .filtered .paginator, .filtered #toolbar, .filtered div.xfull {
margin-right: 0px !important;
margin-left: 160px !important;
}
@ -123,6 +141,11 @@ div.breadcrumbs {
margin-right:0 !important;
}
#changelist table tbody td:first-child, #changelist table tbody th:first-child {
border-right: 0;
border-left: 1px solid #ddd;
}
/* FORMS */
.aligned label {

View File

@ -225,18 +225,18 @@ class BaseModelAdmin(object):
# if foo has been specificially included in the lookup list; so
# drop __id if it is the last part. However, first we need to find
# the pk attribute name.
pk_attr_name = None
rel_name = None
for part in parts[:-1]:
field, _, _, _ = model._meta.get_field_by_name(part)
if hasattr(field, 'rel'):
model = field.rel.to
pk_attr_name = model._meta.pk.name
rel_name = field.rel.get_related_field().name
elif isinstance(field, RelatedObject):
model = field.model
pk_attr_name = model._meta.pk.name
rel_name = model._meta.pk.name
else:
pk_attr_name = None
if pk_attr_name and len(parts) > 1 and parts[-1] == pk_attr_name:
rel_name = None
if rel_name and len(parts) > 1 and parts[-1] == rel_name:
parts.pop()
try:
@ -1242,15 +1242,21 @@ class ModelAdmin(BaseModelAdmin):
def history_view(self, request, object_id, extra_context=None):
"The 'history' admin view for this model."
from django.contrib.admin.models import LogEntry
# First check if the user can see this history.
model = self.model
obj = get_object_or_404(model, pk=unquote(object_id))
if not self.has_change_permission(request, obj):
raise PermissionDenied
# Then get the history for this object.
opts = model._meta
app_label = opts.app_label
action_list = LogEntry.objects.filter(
object_id = object_id,
content_type__id__exact = ContentType.objects.get_for_model(model).id
).select_related().order_by('action_time')
# If no history was found, see whether this object even exists.
obj = get_object_or_404(model, pk=unquote(object_id))
context = {
'title': _('Change history: %s') % force_unicode(obj),
'action_list': action_list,

View File

@ -26,6 +26,15 @@ ERROR_FLAG = 'e'
# Text to display within change-list table cells if the value is blank.
EMPTY_CHANGELIST_VALUE = ugettext_lazy('(None)')
def field_needs_distinct(field):
if ((hasattr(field, 'rel') and
isinstance(field.rel, models.ManyToManyRel)) or
(isinstance(field, models.related.RelatedObject) and
not field.field.unique)):
return True
return False
class ChangeList(object):
def __init__(self, request, model, list_display, list_display_links, list_filter, date_hierarchy, search_fields, list_select_related, list_per_page, list_editable, model_admin):
self.model = model
@ -189,8 +198,7 @@ class ChangeList(object):
f = self.lookup_opts.get_field_by_name(field_name)[0]
except models.FieldDoesNotExist:
raise IncorrectLookupParameters
if hasattr(f, 'rel') and isinstance(f.rel, models.ManyToManyRel):
use_distinct = True
use_distinct = field_needs_distinct(f)
# if key ends with __in, split parameter into separate values
if key.endswith('__in'):
@ -264,7 +272,7 @@ class ChangeList(object):
for search_spec in orm_lookups:
field_name = search_spec.split('__', 1)[0]
f = self.lookup_opts.get_field_by_name(field_name)[0]
if hasattr(f, 'rel') and isinstance(f.rel, models.ManyToManyRel):
if field_needs_distinct(f):
use_distinct = True
break

View File

@ -19,6 +19,7 @@ urlpatterns = urlpatterns + patterns('',
(r'^logout/next_page/$', 'django.contrib.auth.views.logout', dict(next_page='/somewhere/')),
(r'^remote_user/$', remote_user_auth_view),
(r'^password_reset_from_email/$', 'django.contrib.auth.views.password_reset', dict(from_email='staffmember@example.com')),
(r'^admin_password_reset/$', 'django.contrib.auth.views.password_reset', dict(is_admin_site=True)),
(r'^login_required/$', login_required(password_reset)),
(r'^login_required_login_url/$', login_required(password_reset, login_url='/somewhere/')),
)

View File

@ -9,6 +9,7 @@ from django.contrib.sites.models import Site, RequestSite
from django.contrib.auth.models import User
from django.test import TestCase
from django.core import mail
from django.core.exceptions import SuspiciousOperation
from django.core.urlresolvers import reverse
from django.http import QueryDict
@ -69,6 +70,44 @@ class PasswordResetTest(AuthViewsTestCase):
self.assertEqual(len(mail.outbox), 1)
self.assertEqual("staffmember@example.com", mail.outbox[0].from_email)
def test_admin_reset(self):
"If the reset view is marked as being for admin, the HTTP_HOST header is used for a domain override."
response = self.client.post('/admin_password_reset/',
{'email': 'staffmember@example.com'},
HTTP_HOST='adminsite.com'
)
self.assertEqual(response.status_code, 302)
self.assertEqual(len(mail.outbox), 1)
self.assertTrue("http://adminsite.com" in mail.outbox[0].body)
self.assertEqual(settings.DEFAULT_FROM_EMAIL, mail.outbox[0].from_email)
def test_poisoned_http_host(self):
"Poisoned HTTP_HOST headers can't be used for reset emails"
# This attack is based on the way browsers handle URLs. The colon
# should be used to separate the port, but if the URL contains an @,
# the colon is interpreted as part of a username for login purposes,
# making 'evil.com' the request domain. Since HTTP_HOST is used to
# produce a meaningful reset URL, we need to be certain that the
# HTTP_HOST header isn't poisoned. This is done as a check when get_host()
# is invoked, but we check here as a practical consequence.
def test_host_poisoning():
self.client.post('/password_reset/',
{'email': 'staffmember@example.com'},
HTTP_HOST='www.example:dr.frankenstein@evil.tld'
)
self.assertRaises(SuspiciousOperation, test_host_poisoning)
self.assertEqual(len(mail.outbox), 0)
def test_poisoned_http_host_admin_site(self):
"Poisoned HTTP_HOST headers can't be used for reset emails on admin views"
def test_host_poisoning():
self.client.post('/admin_password_reset/',
{'email': 'staffmember@example.com'},
HTTP_HOST='www.example:dr.frankenstein@evil.tld'
)
self.assertRaises(SuspiciousOperation, test_host_poisoning)
self.assertEqual(len(mail.outbox), 0)
def _test_confirm_start(self):
# Start by creating the email
response = self.client.post('/password_reset/', {'email': 'staffmember@example.com'})

View File

@ -5,7 +5,7 @@ from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect, QueryDict
from django.shortcuts import render_to_response
from django.template import RequestContext
from django.utils.http import base36_to_int
from django.utils.http import base36_to_int, is_safe_url
from django.utils.translation import ugettext as _
from django.views.decorators.cache import never_cache
from django.views.decorators.csrf import csrf_protect
@ -33,18 +33,11 @@ def login(request, template_name='registration/login.html',
if request.method == "POST":
form = authentication_form(data=request.POST)
if form.is_valid():
netloc = urlparse.urlparse(redirect_to)[1]
# Use default setting if redirect_to is empty
if not redirect_to:
# Ensure the user-originating redirection url is safe.
if not is_safe_url(url=redirect_to, host=request.get_host()):
redirect_to = settings.LOGIN_REDIRECT_URL
# Security check -- don't allow redirection to a different
# host.
elif netloc and netloc != request.get_host():
redirect_to = settings.LOGIN_REDIRECT_URL
# Okay, security checks complete. Log the user in.
# Okay, security check complete. Log the user in.
auth_login(request, form.get_user())
if request.session.test_cookie_worked():
@ -76,26 +69,27 @@ def logout(request, next_page=None,
Logs out the user and displays 'You are logged out' message.
"""
auth_logout(request)
redirect_to = request.REQUEST.get(redirect_field_name, '')
if redirect_to:
netloc = urlparse.urlparse(redirect_to)[1]
# Security check -- don't allow redirection to a different host.
if not (netloc and netloc != request.get_host()):
return HttpResponseRedirect(redirect_to)
if next_page is None:
current_site = get_current_site(request)
context = {
'site': current_site,
'site_name': current_site.name,
'title': _('Logged out')
}
context.update(extra_context or {})
return render_to_response(template_name, context,
context_instance=RequestContext(request, current_app=current_app))
else:
if redirect_field_name in request.REQUEST:
next_page = request.REQUEST[redirect_field_name]
# Security check -- don't allow redirection to a different host.
if not is_safe_url(url=next_page, host=request.get_host()):
next_page = request.path
if next_page:
# Redirect to this page until the session has been cleared.
return HttpResponseRedirect(next_page or request.path)
return HttpResponseRedirect(next_page)
current_site = get_current_site(request)
context = {
'site': current_site,
'site_name': current_site.name,
'title': _('Logged out')
}
if extra_context is not None:
context.update(extra_context)
return render_to_response(template_name, context,
context_instance=RequestContext(request, current_app=current_app))
def logout_then_login(request, login_url=None, current_app=None, extra_context=None):
"""
@ -151,7 +145,7 @@ def password_reset(request, is_admin_site=False,
'request': request,
}
if is_admin_site:
opts = dict(opts, domain_override=request.META['HTTP_HOST'])
opts = dict(opts, domain_override=request.get_host())
form.save(**opts)
return HttpResponseRedirect(post_reset_redirect)
else:

View File

@ -40,9 +40,6 @@ def post_comment(request, next=None, using=None):
if not data.get('email', ''):
data["email"] = request.user.email
# Check to see if the POST data overrides the view's next argument.
next = data.get("next", next)
# Look up the object we're trying to comment about
ctype = data.get("content_type")
object_pk = data.get("object_pk")
@ -94,9 +91,9 @@ def post_comment(request, next=None, using=None):
]
return render_to_response(
template_list, {
"comment" : form.data.get("comment", ""),
"form" : form,
"next": next,
"comment": form.data.get("comment", ""),
"form": form,
"next": data.get("next", next),
},
RequestContext(request, {})
)
@ -127,7 +124,7 @@ def post_comment(request, next=None, using=None):
request = request
)
return next_redirect(data, next, comment_done, c=comment._get_pk_val())
return next_redirect(request, next, comment_done, c=comment._get_pk_val())
comment_done = confirmation_view(
template = "comments/posted.html",

View File

@ -7,6 +7,7 @@ from django.contrib import comments
from django.contrib.comments import signals
from django.views.decorators.csrf import csrf_protect
@csrf_protect
@login_required
def flag(request, comment_id, next=None):
@ -23,7 +24,7 @@ def flag(request, comment_id, next=None):
# Flag on POST
if request.method == 'POST':
perform_flag(request, comment)
return next_redirect(request.POST.copy(), next, flag_done, c=comment.pk)
return next_redirect(request, next, flag_done, c=comment.pk)
# Render a form on GET
else:
@ -50,7 +51,7 @@ def delete(request, comment_id, next=None):
if request.method == 'POST':
# Flag the comment as deleted instead of actually deleting it.
perform_delete(request, comment)
return next_redirect(request.POST.copy(), next, delete_done, c=comment.pk)
return next_redirect(request, next, delete_done, c=comment.pk)
# Render a form on GET
else:
@ -77,7 +78,7 @@ def approve(request, comment_id, next=None):
if request.method == 'POST':
# Flag the comment as approved.
perform_approve(request, comment)
return next_redirect(request.POST.copy(), next, approve_done, c=comment.pk)
return next_redirect(request, next, approve_done, c=comment.pk)
# Render a form on GET
else:

View File

@ -4,14 +4,15 @@ A few bits of helper functions for comment views.
import urllib
import textwrap
from django.http import HttpResponseRedirect
from django.core import urlresolvers
from django.http import HttpResponseRedirect
from django.shortcuts import render_to_response
from django.template import RequestContext
from django.core.exceptions import ObjectDoesNotExist
from django.contrib import comments
from django.utils.http import is_safe_url
def next_redirect(data, default, default_view, **get_kwargs):
def next_redirect(request, default, default_view, **get_kwargs):
"""
Handle the "where should I go next?" part of comment views.
@ -21,9 +22,10 @@ def next_redirect(data, default, default_view, **get_kwargs):
Returns an ``HttpResponseRedirect``.
"""
next = data.get("next", default)
if next is None:
next = request.POST.get('next', default)
if not is_safe_url(url=next, host=request.get_host()):
next = urlresolvers.reverse(default_view)
if get_kwargs:
if '#' in next:
tmp = next.rsplit('#', 1)

View File

@ -122,7 +122,7 @@ class BaseSpatialOperations(object):
raise NotImplementedError('Aggregate support not implemented for this spatial backend.')
def spatial_lookup_sql(self, lvalue, lookup_type, value, field):
raise NotImplmentedError
raise NotImplementedError
# Routines for getting the OGC-compliant models.
def geometry_columns(self):

View File

@ -2,15 +2,16 @@ from ctypes.util import find_library
from django.conf import settings
from django.core.exceptions import ImproperlyConfigured
from django.db.backends.sqlite3.base import *
from django.db.backends.sqlite3.base import DatabaseWrapper as SqliteDatabaseWrapper, \
_sqlite_extract, _sqlite_date_trunc, _sqlite_regexp
from django.db.backends.sqlite3.base import (
_sqlite_extract, _sqlite_date_trunc, _sqlite_regexp, _sqlite_format_dtdelta,
connection_created, Database, DatabaseWrapper as SQLiteDatabaseWrapper,
SQLiteCursorWrapper)
from django.contrib.gis.db.backends.spatialite.client import SpatiaLiteClient
from django.contrib.gis.db.backends.spatialite.creation import SpatiaLiteCreation
from django.contrib.gis.db.backends.spatialite.introspection import SpatiaLiteIntrospection
from django.contrib.gis.db.backends.spatialite.operations import SpatiaLiteOperations
class DatabaseWrapper(SqliteDatabaseWrapper):
class DatabaseWrapper(SQLiteDatabaseWrapper):
def __init__(self, *args, **kwargs):
# Before we get too far, make sure pysqlite 2.5+ is installed.
if Database.version_info < (2, 5, 0):
@ -51,6 +52,7 @@ class DatabaseWrapper(SqliteDatabaseWrapper):
self.connection.create_function("django_extract", 2, _sqlite_extract)
self.connection.create_function("django_date_trunc", 2, _sqlite_date_trunc)
self.connection.create_function("regexp", 2, _sqlite_regexp)
self.connection.create_function("django_format_dtdelta", 5, _sqlite_format_dtdelta)
connection_created.send(sender=self.__class__, connection=self)
## From here on, customized for GeoDjango ##

View File

@ -3,7 +3,6 @@ from django.conf import settings
from django.core.cache import get_cache
from django.core.cache.backends.db import BaseDatabaseCache
from django.core.exceptions import ImproperlyConfigured
from django.core.management import call_command
from django.db.backends.sqlite3.creation import DatabaseCreation
class SpatiaLiteCreation(DatabaseCreation):
@ -16,26 +15,56 @@ class SpatiaLiteCreation(DatabaseCreation):
This method is overloaded to load up the SpatiaLite initialization
SQL prior to calling the `syncdb` command.
"""
if verbosity >= 1:
print "Creating test database '%s'..." % self.connection.alias
# Don't import django.core.management if it isn't needed.
from django.core.management import call_command
test_database_name = self._create_test_db(verbosity, autoclobber)
test_database_name = self._get_test_db_name()
if verbosity >= 1:
test_db_repr = ''
if verbosity >= 2:
test_db_repr = " ('%s')" % test_database_name
print "Creating test database for alias '%s'%s..." % (self.connection.alias, test_db_repr)
self._create_test_db(verbosity, autoclobber)
self.connection.close()
self.connection.settings_dict["NAME"] = test_database_name
# Confirm the feature set of the test database
self.connection.features.confirm()
# Need to load the SpatiaLite initialization SQL before running `syncdb`.
self.load_spatialite_sql()
call_command('syncdb', verbosity=verbosity, interactive=False, database=self.connection.alias)
# Report syncdb messages at one level lower than that requested.
# This ensures we don't get flooded with messages during testing
# (unless you really ask to be flooded)
call_command('syncdb',
verbosity=max(verbosity - 1, 0),
interactive=False,
database=self.connection.alias,
load_initial_data=False)
# We need to then do a flush to ensure that any data installed by
# custom SQL has been removed. The only test data should come from
# test fixtures, or autogenerated from post_syncdb triggers.
# This has the side effect of loading initial data (which was
# intentionally skipped in the syncdb).
call_command('flush',
verbosity=max(verbosity - 1, 0),
interactive=False,
database=self.connection.alias)
from django.core.cache import get_cache
from django.core.cache.backends.db import BaseDatabaseCache
for cache_alias in settings.CACHES:
cache = get_cache(cache_alias)
if isinstance(cache, BaseDatabaseCache):
from django.db import router
if router.allow_syncdb(self.connection.alias, cache.cache_model_class):
call_command('createcachetable', cache._table, database=self.connection.alias)
# Get a cursor (even though we don't need one yet). This has
# the side effect of initializing the test database.
cursor = self.connection.cursor()

View File

@ -1,7 +1,7 @@
from itertools import izip
from django.db.backends.util import truncate_name
from django.db.backends.util import truncate_name, typecast_timestamp
from django.db.models.sql import compiler
from django.db.models.sql.constants import TABLE_NAME
from django.db.models.sql.constants import TABLE_NAME, MULTI
from django.db.models.sql.query import get_proxied_model
SQLCompiler = compiler.SQLCompiler
@ -194,7 +194,7 @@ class GeoSQLCompiler(compiler.SQLCompiler):
# We resolve the rest of the columns if we're on Oracle or if
# the `geo_values` attribute is defined.
for value, field in map(None, row[index_start:], fields):
values.append(self.query.convert_values(value, field, connection=self.connection))
values.append(self.query.convert_values(value, field, self.connection))
else:
values.extend(row[index_start:])
return tuple(values)
@ -202,7 +202,7 @@ class GeoSQLCompiler(compiler.SQLCompiler):
#### Routines unique to GeoQuery ####
def get_extra_select_format(self, alias):
sel_fmt = '%s'
if alias in self.query.custom_select:
if hasattr(self.query, 'custom_select') and alias in self.query.custom_select:
sel_fmt = sel_fmt % self.query.custom_select[alias]
return sel_fmt
@ -275,4 +275,24 @@ class SQLAggregateCompiler(compiler.SQLAggregateCompiler, GeoSQLCompiler):
pass
class SQLDateCompiler(compiler.SQLDateCompiler, GeoSQLCompiler):
pass
"""
This is overridden for GeoDjango to properly cast date columns, since
`GeoQuery.resolve_columns` is used for spatial values.
See #14648, #16757.
"""
def results_iter(self):
if self.connection.ops.oracle:
from django.db.models.fields import DateTimeField
fields = [DateTimeField()]
else:
needs_string_cast = self.connection.features.needs_datetime_string_cast
offset = len(self.query.extra_select)
for rows in self.execute_sql(MULTI):
for row in rows:
date = row[offset]
if self.connection.ops.oracle:
date = self.resolve_columns(row, fields)[offset]
elif needs_string_cast:
date = typecast_timestamp(str(date))
yield date

View File

@ -20,7 +20,7 @@ class Field(GDALBase):
# Setting the feature pointer and index.
self._feat = feat
self._index = index
# Getting the pointer for this field.
fld_ptr = capi.get_feat_field_defn(feat, index)
if not fld_ptr:
@ -33,6 +33,7 @@ class Field(GDALBase):
# OFTReal with no precision should be an OFTInteger.
if isinstance(self, OFTReal) and self.precision == 0:
self.__class__ = OFTInteger
self._double = True
def __str__(self):
"Returns the string representation of the Field."
@ -95,10 +96,17 @@ class Field(GDALBase):
### The Field sub-classes for each OGR Field type. ###
class OFTInteger(Field):
_double = False
@property
def value(self):
"Returns an integer contained in this field."
return self.as_int()
if self._double:
# If this is really from an OFTReal field with no precision,
# read as a double and cast as Python int (to prevent overflow).
return int(self.as_double())
else:
return self.as_int()
@property
def type(self):
@ -137,7 +145,7 @@ class OFTDateTime(Field):
"Returns a Python `datetime` object for this OFTDateTime field."
# TODO: Adapt timezone information.
# See http://lists.maptools.org/pipermail/gdal-dev/2006-February/007990.html
# The `tz` variable has values of: 0=unknown, 1=localtime (ambiguous),
# The `tz` variable has values of: 0=unknown, 1=localtime (ambiguous),
# 100=GMT, 104=GMT+1, 80=GMT-5, etc.
try:
yy, mm, dd, hh, mn, ss, tz = self.as_datetime()

View File

@ -1,7 +1,8 @@
import os, os.path, unittest
import os
import unittest
from django.contrib.gis.gdal import DataSource, Envelope, OGRGeometry, OGRException, OGRIndexError, GDAL_VERSION
from django.contrib.gis.gdal.field import OFTReal, OFTInteger, OFTString
from django.contrib.gis.geometry.test_data import get_ds_file, TestDS
from django.contrib.gis.geometry.test_data import get_ds_file, TestDS, TEST_DATA
# List of acceptable data sources.
ds_list = (TestDS('test_point', nfeat=5, nfld=3, geom='POINT', gtype=1, driver='ESRI Shapefile',
@ -72,7 +73,7 @@ class DataSourceTest(unittest.TestCase):
self.assertEqual(source.nfld, len(layer.fields))
# Testing the layer's extent (an Envelope), and it's properties
if source.driver == 'VRT' and (GDAL_VERSION > (1, 7, 0) and GDAL_VERSION < (1, 7, 3)):
if source.driver == 'VRT' and (GDAL_VERSION >= (1, 7, 0) and GDAL_VERSION < (1, 7, 3)):
# There's a known GDAL regression with retrieving the extent
# of a VRT layer in versions 1.7.0-1.7.2:
# http://trac.osgeo.org/gdal/ticket/3783
@ -217,6 +218,16 @@ class DataSourceTest(unittest.TestCase):
lyr.spatial_filter = None
self.assertEqual(3, len(lyr))
def test07_integer_overflow(self):
"Testing that OFTReal fields, treated as OFTInteger, do not overflow."
# Using *.dbf from Census 2010 TIGER Shapefile for Texas,
# which has land area ('ALAND10') stored in a Real field
# with no precision.
ds = DataSource(os.path.join(TEST_DATA, 'texas.dbf'))
feat = ds[0][0]
# Reference value obtained using `ogrinfo`.
self.assertEqual(676586997978, feat.get('ALAND10'))
def suite():
s = unittest.TestSuite()
s.addTest(unittest.makeSuite(DataSourceTest))

Binary file not shown.

View File

@ -19,6 +19,7 @@ class City(models.Model):
# This is an inherited model from City
class PennsylvaniaCity(City):
county = models.CharField(max_length=30)
founded = models.DateTimeField(null=True)
objects = models.GeoManager() # TODO: This should be implicitly inherited.
class State(models.Model):

View File

@ -1,9 +1,10 @@
import os, unittest
from datetime import datetime
from django.contrib.gis.tests.utils import no_mysql, no_oracle, no_postgis, no_spatialite
from django.contrib.gis.shortcuts import render_to_kmz
from models import City
from django.test import TestCase
from models import City, PennsylvaniaCity
class GeoRegressionTests(unittest.TestCase):
class GeoRegressionTests(TestCase):
def test01_update(self):
"Testing GeoQuerySet.update(), see #10411."
@ -35,3 +36,10 @@ class GeoRegressionTests(unittest.TestCase):
extent = City.objects.filter(name='Pueblo').extent()
for ref_val, val in zip(ref_ext, extent):
self.assertAlmostEqual(ref_val, val, 4)
def test04_unicode_date(self):
"Testing dates are converted properly, even on SpatiaLite, see #16408."
founded = datetime(1857, 5, 23)
mansfield = PennsylvaniaCity.objects.create(name='Mansfield', county='Tioga', point='POINT(-77.071445 41.823881)',
founded=founded)
self.assertEqual(founded, PennsylvaniaCity.objects.dates('founded', 'day')[0])

View File

@ -36,6 +36,7 @@ class Parcel(models.Model):
# These use the GeoManager but do not have any geographic fields.
class Author(models.Model):
name = models.CharField(max_length=100)
dob = models.DateField()
objects = models.GeoManager()
class Article(models.Model):

View File

@ -1,3 +1,4 @@
from datetime import date
from django.test import TestCase
from django.contrib.gis.geos import GEOSGeometry, Point, MultiPoint
@ -281,4 +282,11 @@ class RelatedGeoModelTest(TestCase):
# evaluated as list generation swallows TypeError in CPython.
sql = str(qs.query)
def test16_annotated_date_queryset(self):
"Ensure annotated date querysets work if spatial backend is used. See #14648."
birth_years = [dt.year for dt in
list(Author.objects.annotate(num_books=Count('books')).dates('dob', 'year'))]
birth_years.sort()
self.assertEqual([1950, 1974], birth_years)
# TODO: Related tests for KML, GML, and distance lookups.

View File

@ -57,6 +57,7 @@ class LayerMapping(object):
# This is a reminder that XMLField is deprecated
# and this needs to be removed in 1.4
models.XMLField : OFTString,
models.BigIntegerField : (OFTInteger, OFTReal, OFTString),
models.SmallIntegerField : (OFTInteger, OFTReal, OFTString),
models.PositiveSmallIntegerField : (OFTInteger, OFTReal, OFTString),
}

View File

@ -59,7 +59,6 @@ class CHIdentityCardNumberField(Field):
* Conforms to the X1234567<0 or 1234567890 format.
* Included checksums match calculated checksums
Algorithm is documented at http://adi.kousz.ch/artikel/IDCHE.htm
"""
default_error_messages = {
'invalid': _('Enter a valid Swiss identity or passport card number in X1234567<0 or 1234567890 format.'),

View File

@ -11,6 +11,8 @@ markup syntaxes to HTML; currently there is support for:
* reStructuredText, which requires docutils from http://docutils.sf.net/
"""
import warnings
from django import template
from django.conf import settings
from django.utils.encoding import smart_str, force_unicode
@ -65,10 +67,21 @@ def markdown(value, arg=''):
# Unicode support only in markdown v1.7 or above. Version_info
# exist only in markdown v1.6.2rc-2 or above.
if getattr(markdown, "version_info", None) < (1,7):
markdown_vers = getattr(markdown, "version_info", None)
if markdown_vers < (1,7):
return mark_safe(force_unicode(markdown.markdown(smart_str(value), extensions, safe_mode=safe_mode)))
else:
return mark_safe(markdown.markdown(force_unicode(value), extensions, safe_mode=safe_mode))
if markdown_vers >= (2,1):
if safe_mode:
return mark_safe(markdown.markdown(force_unicode(value), extensions, safe_mode=safe_mode, enable_attributes=False))
else:
return mark_safe(markdown.markdown(force_unicode(value), extensions, safe_mode=safe_mode))
else:
warnings.warn("Versions of markdown prior to 2.1 do not "
"support disabling of attributes, no "
"attributes have been removed and the result "
"is insecure.")
return mark_safe(markdown.markdown(force_unicode(value), extensions, safe_mode=safe_mode))
else:
return mark_safe(force_unicode(markdown.markdown(smart_str(value))))
markdown.is_safe = True

View File

@ -14,6 +14,7 @@ except ImportError:
try:
import markdown
markdown_version = getattr(markdown, "version_info", 0)
except ImportError:
markdown = None
@ -38,7 +39,6 @@ Paragraph 2 with a link_
.. _link: http://www.example.com/"""
@unittest.skipUnless(textile, 'texttile not installed')
def test_textile(self):
t = Template("{{ textile_content|textile }}")
@ -60,6 +60,20 @@ Paragraph 2 with a link_
pattern = re.compile("""<p>Paragraph 1\s*</p>\s*<h2>\s*An h2</h2>""")
self.assertTrue(pattern.match(rendered))
@unittest.skipUnless(markdown and markdown_version >= (2,1), 'markdown >= 2.1 not installed')
def test_markdown_attribute_disable(self):
t = Template("{% load markup %}{{ markdown_content|markdown:'safe' }}")
markdown_content = "{@onclick=alert('hi')}some paragraph"
rendered = t.render(Context({'markdown_content':markdown_content})).strip()
self.assertTrue('@' in rendered)
@unittest.skipUnless(markdown and markdown_version >= (2,1), 'markdown >= 2.1 not installed')
def test_markdown_attribute_enable(self):
t = Template("{% load markup %}{{ markdown_content|markdown }}")
markdown_content = "{@onclick=alert('hi')}some paragraph"
rendered = t.render(Context({'markdown_content':markdown_content})).strip()
self.assertFalse('@' in rendered)
@unittest.skipIf(markdown, 'markdown is installed')
def test_no_markdown(self):
t = Template("{{ markdown_content|markdown }}")

View File

@ -1,6 +1,8 @@
from django.contrib.sessions.backends.base import SessionBase, CreateError
from django.core.cache import cache
KEY_PREFIX = "django.contrib.sessions.cache"
class SessionStore(SessionBase):
"""
A cache-based session store.
@ -10,7 +12,7 @@ class SessionStore(SessionBase):
super(SessionStore, self).__init__(session_key)
def load(self):
session_data = self._cache.get(self.session_key)
session_data = self._cache.get(KEY_PREFIX + self.session_key)
if session_data is not None:
return session_data
self.create()
@ -37,13 +39,13 @@ class SessionStore(SessionBase):
func = self._cache.add
else:
func = self._cache.set
result = func(self.session_key, self._get_session(no_load=must_create),
result = func(KEY_PREFIX + self.session_key, self._get_session(no_load=must_create),
self.get_expiry_age())
if must_create and not result:
raise CreateError
def exists(self, session_key):
if self._cache.has_key(session_key):
if self._cache.has_key(KEY_PREFIX + session_key):
return True
return False
@ -52,5 +54,5 @@ class SessionStore(SessionBase):
if self._session_key is None:
return
session_key = self._session_key
self._cache.delete(session_key)
self._cache.delete(KEY_PREFIX + session_key)

View File

@ -6,6 +6,8 @@ from django.conf import settings
from django.contrib.sessions.backends.db import SessionStore as DBStore
from django.core.cache import cache
KEY_PREFIX = "django.contrib.sessions.cached_db"
class SessionStore(DBStore):
"""
Implements cached, database backed sessions.
@ -15,10 +17,11 @@ class SessionStore(DBStore):
super(SessionStore, self).__init__(session_key)
def load(self):
data = cache.get(self.session_key, None)
data = cache.get(KEY_PREFIX + self.session_key, None)
if data is None:
data = super(SessionStore, self).load()
cache.set(self.session_key, data, settings.SESSION_COOKIE_AGE)
cache.set(KEY_PREFIX + self.session_key, data,
settings.SESSION_COOKIE_AGE)
return data
def exists(self, session_key):
@ -26,11 +29,12 @@ class SessionStore(DBStore):
def save(self, must_create=False):
super(SessionStore, self).save(must_create)
cache.set(self.session_key, self._session, settings.SESSION_COOKIE_AGE)
cache.set(KEY_PREFIX + self.session_key, self._session,
settings.SESSION_COOKIE_AGE)
def delete(self, session_key=None):
super(SessionStore, self).delete(session_key)
cache.delete(session_key or self.session_key)
cache.delete(KEY_PREFIX + (session_key or self.session_key))
def flush(self):
"""
@ -39,4 +43,4 @@ class SessionStore(DBStore):
"""
self.clear()
self.delete(self.session_key)
self.create()
self.create()

View File

@ -3,15 +3,34 @@ Creates the default Site object.
"""
from django.db.models import signals
from django.db import connections
from django.db import router
from django.contrib.sites.models import Site
from django.contrib.sites import models as site_app
from django.core.management.color import no_style
def create_default_site(app, created_models, verbosity, db, **kwargs):
if Site in created_models:
# Only create the default sites in databases where Django created the table
if Site in created_models and router.allow_syncdb(db, Site) :
# The default settings set SITE_ID = 1, and some tests in Django's test
# suite rely on this value. However, if database sequences are reused
# (e.g. in the test suite after flush/syncdb), it isn't guaranteed that
# the next id will be 1, so we coerce it. See #15573 and #16353. This
# can also crop up outside of tests - see #15346.
if verbosity >= 2:
print "Creating example.com Site object"
s = Site(domain="example.com", name="example.com")
s.save(using=db)
Site(pk=1, domain="example.com", name="example.com").save(using=db)
# We set an explicit pk instead of relying on auto-incrementation,
# so we need to reset the database sequence.
sequence_sql = connections[db].ops.sequence_reset_sql(no_style(), [Site])
if sequence_sql:
if verbosity >= 2:
print "Resetting sequence"
cursor = connections[db].cursor()
for command in sequence_sql:
cursor.execute(command)
Site.objects.clear_cache()
signals.post_syncdb.connect(create_default_site, sender=site_app)

View File

@ -15,6 +15,12 @@ class SitesFrameworkTests(TestCase):
def tearDown(self):
Site._meta.installed = self.old_Site_meta_installed
def test_save_another(self):
# Regression for #17415
# On some backends the sequence needs reset after save with explicit ID.
# Test that there is no sequence collisions by saving another site.
Site(domain="example2.com", name="example2.com").save()
def test_site_manager(self):
# Make sure that get_current() does not return a deleted Site object.
s = Site.objects.get_current()

View File

@ -76,6 +76,7 @@ Type 'yes' to continue, or 'no' to cancel: """)
if confirm != 'yes':
raise CommandError("Collecting static files cancelled.")
processed_files = []
for finder in finders.get_finders():
for path, storage in finder.list(ignore_patterns):
# Prefix the relative path if the source storage contains it
@ -83,10 +84,13 @@ Type 'yes' to continue, or 'no' to cancel: """)
prefixed_path = os.path.join(storage.prefix, path)
else:
prefixed_path = path
if prefixed_path in processed_files:
continue
if symlink:
self.link_file(path, prefixed_path, storage, **options)
else:
self.copy_file(path, prefixed_path, storage, **options)
processed_files.append(prefixed_path)
actual_count = len(self.copied_files) + len(self.symlinked_files)
unmodified_count = len(self.unmodified_files)
@ -196,9 +200,7 @@ Type 'yes' to continue, or 'no' to cancel: """)
os.makedirs(os.path.dirname(full_path))
except OSError:
pass
shutil.copy2(source_path, full_path)
else:
source_file = source_storage.open(path)
self.storage.save(prefixed_path, source_file)
source_file = source_storage.open(path)
self.storage.save(prefixed_path, source_file)
if not prefixed_path in self.copied_files:
self.copied_files.append(prefixed_path)

View File

@ -132,7 +132,13 @@ class DatabaseCache(BaseDatabaseCache):
cursor.execute("SELECT COUNT(*) FROM %s" % table)
num = cursor.fetchone()[0]
if num > self._max_entries:
cursor.execute("SELECT cache_key FROM %s ORDER BY cache_key LIMIT 1 OFFSET %%s" % table, [num / self._cull_frequency])
cull_num = num / self._cull_frequency
if connections[db].vendor == 'oracle':
# Special case for Oracle because it doesn't support LIMIT + OFFSET
cursor.execute("SELECT cache_key FROM (SELECT ROW_NUMBER() OVER (ORDER BY cache_key) AS counter, cache_key FROM %s) WHERE counter > %%s AND COUNTER <= %%s" % table, [cull_num, cull_num + 1])
else:
# This isn't standard SQL, it's likely to break with some non officially supported databases
cursor.execute("SELECT cache_key FROM %s ORDER BY cache_key LIMIT 1 OFFSET %%s" % table, [cull_num])
cursor.execute("DELETE FROM %s WHERE cache_key < %%s" % table, [cursor.fetchone()[0]])
def clear(self):

View File

@ -47,13 +47,18 @@ def get_image_dimensions(file_or_path, close=False):
file = open(file_or_path, 'rb')
close = True
try:
# Most of the time PIL only needs a small chunk to parse the image and
# get the dimensions, but with some TIFF files PIL needs to parse the
# whole file.
chunk_size = 1024
while 1:
data = file.read(1024)
data = file.read(chunk_size)
if not data:
break
p.feed(data)
if p.image:
return p.image.size
chunk_size = chunk_size*2
return None
finally:
if close:

View File

@ -133,7 +133,7 @@ class BaseHandler(object):
if hasattr(response, 'render') and callable(response.render):
for middleware_method in self._template_response_middleware:
response = middleware_method(request, response)
response.render()
response = response.render()
except http.Http404, e:
logger.warning('Not Found: %s' % request.path,

View File

@ -179,11 +179,10 @@ class ModPythonHandler(BaseHandler):
try:
request = self.request_class(req)
except UnicodeDecodeError:
logger.warning('Bad Request (UnicodeDecodeError): %s' % request.path,
logger.warning('Bad Request (UnicodeDecodeError)',
exc_info=sys.exc_info(),
extra={
'status_code': 400,
'request': request
}
)
response = http.HttpResponseBadRequest()

View File

@ -261,11 +261,10 @@ class WSGIHandler(base.BaseHandler):
try:
request = self.request_class(environ)
except UnicodeDecodeError:
logger.warning('Bad Request (UnicodeDecodeError): %s' % request.path,
logger.warning('Bad Request (UnicodeDecodeError)',
exc_info=sys.exc_info(),
extra={
'status_code': 400,
'request': request
}
)
response = http.HttpResponseBadRequest()

View File

@ -13,9 +13,8 @@ class Command(NoArgsCommand):
def ipython(self):
try:
from IPython.frontend.terminal.embed import TerminalInteractiveShell
shell = TerminalInteractiveShell()
shell.mainloop()
from IPython import embed
embed()
except ImportError:
# IPython < 0.11
# Explicitly pass an empty list as arguments, because otherwise

View File

@ -1,6 +1,5 @@
import sys
from django.contrib.contenttypes.generic import GenericForeignKey, GenericRelation
from django.core.management.color import color_style
from django.utils.itercompat import is_iterable
@ -240,12 +239,6 @@ def get_validation_errors(outfile, app=None):
e.add(opts, "'%s' specifies an m2m relation through model %s, "
"which has not been installed" % (f.name, f.rel.through)
)
elif isinstance(f, GenericRelation):
if not any([isinstance(vfield, GenericForeignKey) for vfield in f.rel.to._meta.virtual_fields]):
e.add(opts, "Model '%s' must have a GenericForeignKey in "
"order to create a GenericRelation that points to it."
% f.rel.to.__name__
)
rel_opts = f.rel.to._meta
rel_name = RelatedObject(f.rel.to, cls, f).get_accessor_name()

View File

@ -8,6 +8,8 @@ from django.db import models, DEFAULT_DB_ALIAS
from django.utils.xmlutils import SimplerXMLGenerator
from django.utils.encoding import smart_unicode
from xml.dom import pulldom
from xml.sax import handler
from xml.sax.expatreader import ExpatParser as _ExpatParser
class Serializer(base.Serializer):
"""
@ -154,9 +156,13 @@ class Deserializer(base.Deserializer):
def __init__(self, stream_or_string, **options):
super(Deserializer, self).__init__(stream_or_string, **options)
self.event_stream = pulldom.parse(self.stream)
self.event_stream = pulldom.parse(self.stream, self._make_parser())
self.db = options.pop('using', DEFAULT_DB_ALIAS)
def _make_parser(self):
"""Create a hardened XML parser (no custom/external entities)."""
return DefusedExpatParser()
def next(self):
for event, node in self.event_stream:
if event == "START_ELEMENT" and node.nodeName == "object":
@ -295,3 +301,89 @@ def getInnerText(node):
else:
pass
return u"".join(inner_text)
# Below code based on Christian Heimes' defusedxml
class DefusedExpatParser(_ExpatParser):
"""
An expat parser hardened against XML bomb attacks.
Forbids DTDs, external entity references
"""
def __init__(self, *args, **kwargs):
_ExpatParser.__init__(self, *args, **kwargs)
self.setFeature(handler.feature_external_ges, False)
self.setFeature(handler.feature_external_pes, False)
def start_doctype_decl(self, name, sysid, pubid, has_internal_subset):
raise DTDForbidden(name, sysid, pubid)
def entity_decl(self, name, is_parameter_entity, value, base,
sysid, pubid, notation_name):
raise EntitiesForbidden(name, value, base, sysid, pubid, notation_name)
def unparsed_entity_decl(self, name, base, sysid, pubid, notation_name):
# expat 1.2
raise EntitiesForbidden(name, None, base, sysid, pubid, notation_name)
def external_entity_ref_handler(self, context, base, sysid, pubid):
raise ExternalReferenceForbidden(context, base, sysid, pubid)
def reset(self):
_ExpatParser.reset(self)
parser = self._parser
parser.StartDoctypeDeclHandler = self.start_doctype_decl
parser.EntityDeclHandler = self.entity_decl
parser.UnparsedEntityDeclHandler = self.unparsed_entity_decl
parser.ExternalEntityRefHandler = self.external_entity_ref_handler
class DefusedXmlException(ValueError):
"""Base exception."""
def __repr__(self):
return str(self)
class DTDForbidden(DefusedXmlException):
"""Document type definition is forbidden."""
def __init__(self, name, sysid, pubid):
self.name = name
self.sysid = sysid
self.pubid = pubid
def __str__(self):
tpl = "DTDForbidden(name='{}', system_id={!r}, public_id={!r})"
return tpl.format(self.name, self.sysid, self.pubid)
class EntitiesForbidden(DefusedXmlException):
"""Entity definition is forbidden."""
def __init__(self, name, value, base, sysid, pubid, notation_name):
super(EntitiesForbidden, self).__init__()
self.name = name
self.value = value
self.base = base
self.sysid = sysid
self.pubid = pubid
self.notation_name = notation_name
def __str__(self):
tpl = "EntitiesForbidden(name='{}', system_id={!r}, public_id={!r})"
return tpl.format(self.name, self.sysid, self.pubid)
class ExternalReferenceForbidden(DefusedXmlException):
"""Resolving an external reference is forbidden."""
def __init__(self, context, base, sysid, pubid):
super(ExternalReferenceForbidden, self).__init__()
self.context = context
self.base = base
self.sysid = sysid
self.pubid = pubid
def __str__(self):
tpl = "ExternalReferenceForbidden(system_id='{}', public_id={})"
return tpl.format(self.sysid, self.pubid)

View File

@ -1,4 +1,6 @@
import platform
import re
import urllib
import urllib2
import urlparse
@ -39,10 +41,6 @@ class RegexValidator(object):
if not self.regex.search(smart_unicode(value)):
raise ValidationError(self.message, code=self.code)
class HeadRequest(urllib2.Request):
def get_method(self):
return "HEAD"
class URLValidator(RegexValidator):
regex = re.compile(
r'^(?:http|ftp)s?://' # http:// or https://
@ -52,7 +50,8 @@ class URLValidator(RegexValidator):
r'(?::\d+)?' # optional port
r'(?:/?|[/?]\S+)$', re.IGNORECASE)
def __init__(self, verify_exists=False, validator_user_agent=URL_VALIDATOR_USER_AGENT):
def __init__(self, verify_exists=False,
validator_user_agent=URL_VALIDATOR_USER_AGENT):
super(URLValidator, self).__init__()
self.verify_exists = verify_exists
self.user_agent = validator_user_agent
@ -76,6 +75,7 @@ class URLValidator(RegexValidator):
else:
url = value
#This is deprecated and will be removed in a future release.
if self.verify_exists:
headers = {
"Accept": "text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5",
@ -85,24 +85,41 @@ class URLValidator(RegexValidator):
"User-Agent": self.user_agent,
}
url = url.encode('utf-8')
# Quote characters from the unreserved set, refs #16812
url = urllib.quote(url, "!*'();:@&=+$,/?#[]")
broken_error = ValidationError(
_(u'This URL appears to be a broken link.'), code='invalid_link')
try:
req = HeadRequest(url, None, headers)
u = urllib2.urlopen(req)
req = urllib2.Request(url, None, headers)
req.get_method = lambda: 'HEAD'
#Create an opener that does not support local file access
opener = urllib2.OpenerDirector()
#Don't follow redirects, but don't treat them as errors either
error_nop = lambda *args, **kwargs: True
http_error_processor = urllib2.HTTPErrorProcessor()
http_error_processor.http_error_301 = error_nop
http_error_processor.http_error_302 = error_nop
http_error_processor.http_error_307 = error_nop
handlers = [urllib2.UnknownHandler(),
urllib2.HTTPHandler(),
urllib2.HTTPDefaultErrorHandler(),
urllib2.FTPHandler(),
http_error_processor]
try:
import ssl
handlers.append(urllib2.HTTPSHandler())
except:
#Python isn't compiled with SSL support
pass
map(opener.add_handler, handlers)
if platform.python_version_tuple() >= (2, 6):
opener.open(req, timeout=10)
else:
opener.open(req)
except ValueError:
raise ValidationError(_(u'Enter a valid URL.'), code='invalid')
except urllib2.HTTPError, e:
if e.code in (405, 501):
# Try a GET request (HEAD refused)
# See also: http://www.w3.org/Protocols/rfc2616/rfc2616.html
try:
req = urllib2.Request(url, None, headers)
u = urllib2.urlopen(req)
except:
raise broken_error
else:
raise broken_error
except: # urllib2.URLError, httplib.InvalidURL, etc.
raise broken_error
@ -133,7 +150,8 @@ class EmailValidator(RegexValidator):
email_re = re.compile(
r"(^[-!#$%&'*+/=?^_`{}|~0-9A-Z]+(\.[-!#$%&'*+/=?^_`{}|~0-9A-Z]+)*" # dot-atom
r'|^"([\001-\010\013\014\016-\037!#-\[\]-\177]|\\[\001-011\013\014\016-\177])*"' # quoted-string
# quoted-string, see also http://tools.ietf.org/html/rfc2822#section-3.2.5
r'|^"([\001-\010\013\014\016-\037!#-\[\]-\177]|\\[\001-\011\013\014\016-\177])*"'
r')@(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+[A-Z]{2,6}\.?$', re.IGNORECASE) # domain
validate_email = EmailValidator(email_re, _(u'Enter a valid e-mail address.'), 'invalid')

View File

@ -220,7 +220,7 @@ class DatabaseWrapper(BaseDatabaseWrapper):
if self.settings_dict['NAME'] != ":memory:":
BaseDatabaseWrapper.close(self)
FORMAT_QMARK_REGEX = re.compile(r'(?![^%])%s')
FORMAT_QMARK_REGEX = re.compile(r'(?<!%)%s')
class SQLiteCursorWrapper(Database.Cursor):
"""

View File

@ -83,8 +83,8 @@ class Collector(object):
def add(self, objs, source=None, nullable=False, reverse_dependency=False):
"""
Adds 'objs' to the collection of objects to be deleted. If the call is
the result of a cascade, 'source' should be the model that caused it
and 'nullable' should be set to True, if the relation can be null.
the result of a cascade, 'source' should be the model that caused it,
and 'nullable' should be set to True if the relation can be null.
Returns a list of all objects that were not already collected.
"""
@ -100,7 +100,7 @@ class Collector(object):
# Nullable relationships can be ignored -- they are nulled out before
# deleting, and therefore do not affect the order in which objects have
# to be deleted.
if new_objs and source is not None and not nullable:
if source is not None and not nullable:
if reverse_dependency:
source, model = model, source
self.dependencies.setdefault(source, set()).add(model)

View File

@ -1119,7 +1119,7 @@ class TimeField(Field):
class URLField(CharField):
description = _("URL")
def __init__(self, verbose_name=None, name=None, verify_exists=True, **kwargs):
def __init__(self, verbose_name=None, name=None, verify_exists=False, **kwargs):
kwargs['max_length'] = kwargs.get('max_length', 200)
CharField.__init__(self, verbose_name, name, **kwargs)
self.validators.append(validators.URLValidator(verify_exists=verify_exists))

View File

@ -390,7 +390,7 @@ class Options(object):
cache[obj] = model
for klass in get_models(include_auto_created=True):
for f in klass._meta.local_fields:
if f.rel and not isinstance(f.rel.to, str) and self == f.rel.to._meta:
if f.rel and not isinstance(f.rel.to, basestring) and self == f.rel.to._meta:
cache[RelatedObject(f.rel.to, klass, f)] = None
self._related_objects_cache = cache
@ -427,7 +427,7 @@ class Options(object):
cache[obj] = model
for klass in get_models():
for f in klass._meta.local_many_to_many:
if f.rel and not isinstance(f.rel.to, str) and self == f.rel.to._meta:
if f.rel and not isinstance(f.rel.to, basestring) and self == f.rel.to._meta:
cache[RelatedObject(f.rel.to, klass, f)] = None
if app_cache_ready():
self._related_many_to_many_cache = cache

View File

@ -440,8 +440,6 @@ class Query(object):
"Cannot combine a unique query with a non-unique query."
self.remove_inherited_models()
l_tables = set([a for a in self.tables if self.alias_refcount[a]])
r_tables = set([a for a in rhs.tables if rhs.alias_refcount[a]])
# Work out how to relabel the rhs aliases, if necessary.
change_map = {}
used = set()
@ -462,16 +460,27 @@ class Query(object):
# all joins exclusive to either the lhs or the rhs must be converted
# to an outer join.
if not conjunction:
l_tables = set(self.tables)
r_tables = set(rhs.tables)
# Update r_tables aliases.
for alias in change_map:
if alias in r_tables:
r_tables.remove(alias)
r_tables.add(change_map[alias])
# r_tables may contain entries that have a refcount of 0
# if the query has references to a table that can be
# trimmed because only the foreign key is used.
# We only need to fix the aliases for the tables that
# actually have aliases.
if rhs.alias_refcount[alias]:
r_tables.remove(alias)
r_tables.add(change_map[alias])
# Find aliases that are exclusive to rhs or lhs.
# These are promoted to outer joins.
outer_aliases = (l_tables | r_tables) - (l_tables & r_tables)
for alias in outer_aliases:
self.promote_alias(alias, True)
outer_tables = (l_tables | r_tables) - (l_tables & r_tables)
for alias in outer_tables:
# Again, some of the tables won't have aliases due to
# the trimming of unnecessary tables.
if self.alias_refcount.get(alias) or rhs.alias_refcount.get(alias):
self.promote_alias(alias, True)
# Now relabel a copy of the rhs where-clause and add it to the current
# one.
@ -656,7 +665,7 @@ class Query(object):
False, the join is only promoted if it is nullable, otherwise it is
always promoted.
Returns True if the join was promoted.
Returns True if the join was promoted by this call.
"""
if ((unconditional or self.alias_map[alias][NULLABLE]) and
self.alias_map[alias][JOIN_TYPE] != self.LOUTER):
@ -1063,17 +1072,20 @@ class Query(object):
can_reuse)
return
table_promote = False
join_promote = False
if (lookup_type == 'isnull' and value is True and not negate and
len(join_list) > 1):
# If the comparison is against NULL, we may need to use some left
# outer joins when creating the join chain. This is only done when
# needed, as it's less efficient at the database level.
self.promote_alias_chain(join_list)
join_promote = True
# Process the join list to see if we can remove any inner joins from
# the far end (fewer tables in a query is better).
col, alias, join_list = self.trim_joins(target, join_list, last, trim)
if connector == OR:
# Some joins may need to be promoted when adding a new filter to a
# disjunction. We walk the list of new joins and where it diverges
@ -1083,19 +1095,29 @@ class Query(object):
join_it = iter(join_list)
table_it = iter(self.tables)
join_it.next(), table_it.next()
table_promote = False
join_promote = False
unconditional = False
for join in join_it:
table = table_it.next()
# Once we hit an outer join, all subsequent joins must
# also be promoted, regardless of whether they have been
# promoted as a result of this pass through the tables.
unconditional = (unconditional or
self.alias_map[join][JOIN_TYPE] == self.LOUTER)
if join == table and self.alias_refcount[join] > 1:
# We have more than one reference to this join table.
# This means that we are dealing with two different query
# subtrees, so we don't need to do any join promotion.
continue
join_promote = self.promote_alias(join)
join_promote = join_promote or self.promote_alias(join, unconditional)
if table != join:
table_promote = self.promote_alias(table)
# We only get here if we have found a table that exists
# in the join list, but isn't on the original tables list.
# This means we've reached the point where we only have
# new tables, so we can break out of this promotion loop.
break
self.promote_alias_chain(join_it, join_promote)
self.promote_alias_chain(table_it, table_promote)
self.promote_alias_chain(table_it, table_promote or join_promote)
if having_clause or force_having:
if (alias, col) not in self.group_by:

View File

@ -26,16 +26,14 @@ from django.utils.functional import lazy
from django.core.validators import EMPTY_VALUES
from util import ErrorList
from widgets import TextInput, PasswordInput, HiddenInput, MultipleHiddenInput, \
ClearableFileInput, CheckboxInput, Select, NullBooleanSelect, SelectMultiple, \
DateInput, DateTimeInput, TimeInput, SplitDateTimeWidget, SplitHiddenDateTimeWidget, \
FILE_INPUT_CONTRADICTION
from widgets import (TextInput, PasswordInput, HiddenInput,
MultipleHiddenInput, ClearableFileInput, CheckboxInput, Select,
NullBooleanSelect, SelectMultiple, DateInput, DateTimeInput, TimeInput,
SplitDateTimeWidget, SplitHiddenDateTimeWidget, FILE_INPUT_CONTRADICTION)
__all__ = (
'Field', 'CharField', 'IntegerField',
'DEFAULT_DATE_INPUT_FORMATS', 'DateField',
'DEFAULT_TIME_INPUT_FORMATS', 'TimeField',
'DEFAULT_DATETIME_INPUT_FORMATS', 'DateTimeField', 'TimeField',
'DateField', 'TimeField', 'DateTimeField', 'TimeField',
'RegexField', 'EmailField', 'FileField', 'ImageField', 'URLField',
'BooleanField', 'NullBooleanField', 'ChoiceField', 'MultipleChoiceField',
'ComboField', 'MultiValueField', 'FloatField', 'DecimalField',
@ -54,10 +52,6 @@ def en_format(name):
)
return getattr(formats, name)
DEFAULT_DATE_INPUT_FORMATS = lazy(lambda: en_format('DATE_INPUT_FORMATS'), tuple, list)()
DEFAULT_TIME_INPUT_FORMATS = lazy(lambda: en_format('TIME_INPUT_FORMATS'), tuple, list)()
DEFAULT_DATETIME_INPUT_FORMATS = lazy(lambda: en_format('DATETIME_INPUT_FORMATS'), tuple, list)()
class Field(object):
widget = TextInput # Default widget to use when rendering this type of Field.
hidden_widget = HiddenInput # Default widget to use when rendering this as "hidden".
@ -544,20 +538,10 @@ class ImageField(FileField):
file = StringIO(data['content'])
try:
# load() is the only method that can spot a truncated JPEG,
# but it cannot be called sanely after verify()
trial_image = Image.open(file)
trial_image.load()
# Since we're about to use the file again we have to reset the
# file object if possible.
if hasattr(file, 'reset'):
file.reset()
# verify() is the only method that can spot a corrupt PNG,
# but it must be called immediately after the constructor
trial_image = Image.open(file)
trial_image.verify()
# load() could spot a truncated JPEG, but it loads the entire
# image in memory, which is a DoS vector. See #3848 and #18520.
# verify() must be called immediately after the constructor.
Image.open(file).verify()
except ImportError:
# Under PyPy, it is possible to import PIL. However, the underlying
# _imaging C module isn't available, so an ImportError will be

View File

@ -16,6 +16,9 @@ MAX_NUM_FORM_COUNT = 'MAX_NUM_FORMS'
ORDERING_FIELD_NAME = 'ORDER'
DELETION_FIELD_NAME = 'DELETE'
# default maximum number of forms in a formset, to prevent memory exhaustion
DEFAULT_MAX_NUM = 1000
class ManagementForm(Form):
"""
``ManagementForm`` is used to keep track of how many form instances
@ -104,7 +107,7 @@ class BaseFormSet(StrAndUnicode):
def _construct_forms(self):
# instantiate all the forms and put them in self.forms
self.forms = []
for i in xrange(self.total_form_count()):
for i in xrange(min(self.total_form_count(), self.absolute_max)):
self.forms.append(self._construct_form(i))
def _construct_form(self, i, **kwargs):
@ -348,9 +351,14 @@ class BaseFormSet(StrAndUnicode):
def formset_factory(form, formset=BaseFormSet, extra=1, can_order=False,
can_delete=False, max_num=None):
"""Return a FormSet for the given form class."""
if max_num is None:
max_num = DEFAULT_MAX_NUM
# hard limit on forms instantiated, to prevent memory-exhaustion attacks
# limit defaults to DEFAULT_MAX_NUM, but developer can increase it via max_num
absolute_max = max(DEFAULT_MAX_NUM, max_num)
attrs = {'form': form, 'extra': extra,
'can_order': can_order, 'can_delete': can_delete,
'max_num': max_num}
'max_num': max_num, 'absolute_max': absolute_max}
return type(form.__name__ + 'FormSet', (formset,), attrs)
def all_valid(formsets):

View File

@ -4,7 +4,7 @@ import re
import time
from pprint import pformat
from urllib import urlencode, quote
from urlparse import urljoin
from urlparse import urljoin, urlparse
try:
from cStringIO import StringIO
except ImportError:
@ -92,7 +92,7 @@ else:
if not _cookie_allows_colon_in_names:
def load(self, rawdata, ignore_parse_errors=False):
if ignore_parse_errors:
self.bad_cookies = []
self.bad_cookies = set()
self._BaseCookie__set = self._loose_set
super(SimpleCookie, self).load(rawdata)
if ignore_parse_errors:
@ -106,8 +106,8 @@ else:
try:
self._strict_set(key, real_value, coded_value)
except Cookie.CookieError:
self.bad_cookies.append(key)
dict.__setitem__(self, key, None)
self.bad_cookies.add(key)
dict.__setitem__(self, key, Cookie.Morsel())
class CompatCookie(SimpleCookie):
@ -117,6 +117,7 @@ class CompatCookie(SimpleCookie):
warnings.warn("CompatCookie is deprecated, use django.http.SimpleCookie instead.",
PendingDeprecationWarning)
from django.core.exceptions import SuspiciousOperation
from django.utils.datastructures import MultiValueDict, ImmutableList
from django.utils.encoding import smart_str, iri_to_uri, force_unicode
from django.utils.http import cookie_date
@ -128,6 +129,8 @@ from utils import *
RESERVED_CHARS="!*'();:@&=+$,/?%#[]"
absolute_http_url_re = re.compile(r"^https?://", re.I)
host_validation_re = re.compile(r"^([a-z0-9.-]+|\[[a-f0-9]*:[a-f0-9:]+\])(:\d+)?$")
class Http404(Exception):
pass
@ -153,7 +156,8 @@ class HttpRequest(object):
def get_host(self):
"""Returns the HTTP host using the environment or request headers."""
# We try three options, in order of decreasing preference.
if 'HTTP_X_FORWARDED_HOST' in self.META:
if settings.USE_X_FORWARDED_HOST and (
'HTTP_X_FORWARDED_HOST' in self.META):
host = self.META['HTTP_X_FORWARDED_HOST']
elif 'HTTP_HOST' in self.META:
host = self.META['HTTP_HOST']
@ -163,7 +167,16 @@ class HttpRequest(object):
server_port = str(self.META['SERVER_PORT'])
if server_port != (self.is_secure() and '443' or '80'):
host = '%s:%s' % (host, server_port)
return host
if settings.DEBUG:
allowed_hosts = ['*']
else:
allowed_hosts = settings.ALLOWED_HOSTS
if validate_host(host, allowed_hosts):
return host
else:
raise SuspiciousOperation(
"Invalid HTTP_HOST header (you may need to set ALLOWED_HOSTS): %s" % host)
def get_full_path(self):
# RFC 3986 requires query string arguments to be in the ASCII range.
@ -262,14 +275,18 @@ class HttpRequest(object):
if self.method != 'POST':
self._post, self._files = QueryDict('', encoding=self._encoding), MultiValueDict()
return
if self._read_started:
if self._read_started and not hasattr(self, '_raw_post_data'):
self._mark_post_parse_error()
return
if self.META.get('CONTENT_TYPE', '').startswith('multipart'):
self._raw_post_data = ''
if hasattr(self, '_raw_post_data'):
# Use already read data
data = StringIO(self._raw_post_data)
else:
data = self
try:
self._post, self._files = self.parse_file_upload(self.META, self)
self._post, self._files = self.parse_file_upload(self.META, data)
except:
# An error occured while parsing POST data. Since when
# formatting the error the request handler might access
@ -630,20 +647,22 @@ class HttpResponse(object):
raise Exception("This %s instance cannot tell its position" % self.__class__)
return sum([len(chunk) for chunk in self._container])
class HttpResponseRedirect(HttpResponse):
class HttpResponseRedirectBase(HttpResponse):
allowed_schemes = ['http', 'https', 'ftp']
def __init__(self, redirect_to):
super(HttpResponseRedirectBase, self).__init__()
parsed = urlparse(redirect_to)
if parsed[0] and parsed[0] not in self.allowed_schemes:
raise SuspiciousOperation("Unsafe redirect to URL with scheme '%s'" % parsed[0])
self['Location'] = iri_to_uri(redirect_to)
class HttpResponseRedirect(HttpResponseRedirectBase):
status_code = 302
def __init__(self, redirect_to):
super(HttpResponseRedirect, self).__init__()
self['Location'] = iri_to_uri(redirect_to)
class HttpResponsePermanentRedirect(HttpResponse):
class HttpResponsePermanentRedirect(HttpResponseRedirectBase):
status_code = 301
def __init__(self, redirect_to):
super(HttpResponsePermanentRedirect, self).__init__()
self['Location'] = iri_to_uri(redirect_to)
class HttpResponseNotModified(HttpResponse):
status_code = 304
@ -689,3 +708,43 @@ def str_to_unicode(s, encoding):
else:
return s
def validate_host(host, allowed_hosts):
"""
Validate the given host header value for this site.
Check that the host looks valid and matches a host or host pattern in the
given list of ``allowed_hosts``. Any pattern beginning with a period
matches a domain and all its subdomains (e.g. ``.example.com`` matches
``example.com`` and any subdomain), ``*`` matches anything, and anything
else must match exactly.
Return ``True`` for a valid host, ``False`` otherwise.
"""
# All validation is case-insensitive
host = host.lower()
# Basic sanity check
if not host_validation_re.match(host):
return False
# Validate only the domain part.
if host[-1] == ']':
# It's an IPv6 address without a port.
domain = host
else:
domain = host.rsplit(':', 1)[0]
for pattern in allowed_hosts:
pattern = pattern.lower()
match = (
pattern == '*' or
pattern.startswith('.') and (
domain.endswith(pattern) or domain == pattern[1:]
) or
pattern == domain
)
if match:
return True
return False

View File

@ -75,7 +75,7 @@ class MultiPartParser(object):
# For now set it to 0; we'll try again later on down.
content_length = 0
if content_length <= 0:
if content_length < 0:
# This means we shouldn't continue...raise an error.
raise MultiPartParserError("Invalid content length: %r" % content_length)
@ -105,6 +105,11 @@ class MultiPartParser(object):
encoding = self._encoding
handlers = self._upload_handlers
# HTTP spec says that Content-Length >= 0 is valid
# handling content-length == 0 before continuing
if self._content_length == 0:
return QueryDict(MultiValueDict(), encoding=self._encoding), MultiValueDict()
limited_input_data = LimitBytes(self._input_data, self._content_length)
# See if the handler will want to take care of the parsing.
@ -145,6 +150,8 @@ class MultiPartParser(object):
continue
transfer_encoding = meta_data.get('content-transfer-encoding')
if transfer_encoding is not None:
transfer_encoding = transfer_encoding[0].strip()
field_name = force_unicode(field_name, encoding, errors='replace')
if item_type == FIELD:

View File

@ -76,7 +76,8 @@ def fix_IE_for_vary(request, response):
# The first part of the Content-Type field will be the MIME type,
# everything after ';', such as character-set, can be ignored.
if response['Content-Type'].split(';')[0] not in safe_mime_types:
mime_type = response.get('Content-Type', '').split(';', 1)[0]
if mime_type not in safe_mime_types:
try:
del response['Vary']
except KeyError:

View File

@ -14,21 +14,16 @@ class ContextPopException(Exception):
"pop() has been called more times than push()"
pass
class EmptyClass(object):
# No-op class which takes no args to its __init__ method, to help implement
# __copy__
pass
class BaseContext(object):
def __init__(self, dict_=None):
dict_ = dict_ or {}
self.dicts = [dict_]
self._reset_dicts(dict_)
def _reset_dicts(self, value=None):
self.dicts = [value or {}]
def __copy__(self):
duplicate = EmptyClass()
duplicate.__class__ = self.__class__
duplicate.__dict__ = self.__dict__.copy()
duplicate.dicts = duplicate.dicts[:]
duplicate = copy(super(BaseContext, self))
duplicate.dicts = self.dicts[:]
return duplicate
def __repr__(self):
@ -78,6 +73,15 @@ class BaseContext(object):
return d[key]
return otherwise
def new(self, values=None):
"""
Returns a new context with the same properties, but with only the
values given in 'values' stored.
"""
new_context = copy(self)
new_context._reset_dicts(values)
return new_context
class Context(BaseContext):
"A stack container for variable context"
def __init__(self, dict_=None, autoescape=True, current_app=None, use_l10n=None):
@ -99,14 +103,6 @@ class Context(BaseContext):
self.dicts.append(other_dict)
return other_dict
def new(self, values=None):
"""
Returns a new Context with the same 'autoescape' value etc, but with
only the values given in 'values' stored.
"""
return self.__class__(dict_=values, autoescape=self.autoescape,
current_app=self.current_app, use_l10n=self.use_l10n)
class RenderContext(BaseContext):
"""
A stack container for storing Template state.

View File

@ -92,11 +92,14 @@ class SimpleTemplateResponse(HttpResponse):
Returns the baked response instance.
"""
retval = self
if not self._is_rendered:
self._set_content(self.rendered_content)
for post_callback in self._post_render_callbacks:
post_callback(self)
return self
newretval = post_callback(retval)
if newretval is not None:
retval = newretval
return retval
is_rendered = property(lambda self: self._is_rendered)

View File

@ -22,7 +22,7 @@ def ssi(parser, token):
{% ssi "/home/html/ljworld.com/includes/right_generic.html" parsed %}
"""
bits = token.contents.split()
bits = token.split_contents()
parsed = False
if len(bits) not in (2, 3):
raise TemplateSyntaxError("'ssi' tag takes one argument: the path to"

View File

@ -207,6 +207,18 @@ class RequestFactory(object):
"Construct a generic request object."
return WSGIRequest(self._base_environ(**request))
def _encode_data(self, data, content_type, ):
if content_type is MULTIPART_CONTENT:
return encode_multipart(BOUNDARY, data)
else:
# Encode the content so that the byte representation is correct.
match = CONTENT_TYPE_RE.match(content_type)
if match:
charset = match.group(1)
else:
charset = settings.DEFAULT_CHARSET
return smart_str(data, encoding=charset)
def _get_path(self, parsed):
# If there are parameters, add them
if parsed[3]:
@ -232,16 +244,7 @@ class RequestFactory(object):
**extra):
"Construct a POST request."
if content_type is MULTIPART_CONTENT:
post_data = encode_multipart(BOUNDARY, data)
else:
# Encode the content so that the byte representation is correct.
match = CONTENT_TYPE_RE.match(content_type)
if match:
charset = match.group(1)
else:
charset = settings.DEFAULT_CHARSET
post_data = smart_str(data, encoding=charset)
post_data = self._encode_data(data, content_type)
parsed = urlparse(path)
r = {
@ -286,25 +289,16 @@ class RequestFactory(object):
**extra):
"Construct a PUT request."
if content_type is MULTIPART_CONTENT:
post_data = encode_multipart(BOUNDARY, data)
else:
post_data = data
# Make `data` into a querystring only if it's not already a string. If
# it is a string, we'll assume that the caller has already encoded it.
query_string = None
if not isinstance(data, basestring):
query_string = urlencode(data, doseq=True)
put_data = self._encode_data(data, content_type)
parsed = urlparse(path)
r = {
'CONTENT_LENGTH': len(post_data),
'CONTENT_LENGTH': len(put_data),
'CONTENT_TYPE': content_type,
'PATH_INFO': self._get_path(parsed),
'QUERY_STRING': query_string or parsed[4],
'QUERY_STRING': parsed[4],
'REQUEST_METHOD': 'PUT',
'wsgi.input': FakePayload(post_data),
'wsgi.input': FakePayload(put_data),
}
r.update(extra)
return self.request(**r)

View File

@ -6,12 +6,15 @@ from django.conf import settings
from django.core import mail
from django.core.mail.backends import locmem
from django.test import signals
from django.template import Template
from django.template import Template, loader, TemplateDoesNotExist
from django.template.loaders import cached
from django.utils.translation import deactivate
__all__ = ('Approximate', 'ContextList', 'setup_test_environment',
'teardown_test_environment', 'get_runner')
RESTORE_LOADERS_ATTR = '_original_template_source_loaders'
class Approximate(object):
def __init__(self, val, places=7):
@ -73,6 +76,9 @@ def setup_test_environment():
mail.original_email_backend = settings.EMAIL_BACKEND
settings.EMAIL_BACKEND = 'django.core.mail.backends.locmem.EmailBackend'
settings._original_allowed_hosts = settings.ALLOWED_HOSTS
settings.ALLOWED_HOSTS = ['*']
mail.outbox = []
deactivate()
@ -94,6 +100,9 @@ def teardown_test_environment():
settings.EMAIL_BACKEND = mail.original_email_backend
del mail.original_email_backend
settings.ALLOWED_HOSTS = settings._original_allowed_hosts
del settings._original_allowed_hosts
del mail.outbox
@ -125,3 +134,41 @@ def get_runner(settings):
test_module = __import__(test_module_name, {}, {}, test_path[-1])
test_runner = getattr(test_module, test_path[-1])
return test_runner
def setup_test_template_loader(templates_dict, use_cached_loader=False):
"""
Changes Django to only find templates from within a dictionary (where each
key is the template name and each value is the corresponding template
content to return).
Use meth:`restore_template_loaders` to restore the original loaders.
"""
if hasattr(loader, RESTORE_LOADERS_ATTR):
raise Exception("loader.%s already exists" % RESTORE_LOADERS_ATTR)
def test_template_loader(template_name, template_dirs=None):
"A custom template loader that loads templates from a dictionary."
try:
return (templates_dict[template_name], "test:%s" % template_name)
except KeyError:
raise TemplateDoesNotExist(template_name)
if use_cached_loader:
template_loader = cached.Loader(('test_template_loader',))
template_loader._cached_loaders = (test_template_loader,)
else:
template_loader = test_template_loader
setattr(loader, RESTORE_LOADERS_ATTR, loader.template_source_loaders)
loader.template_source_loaders = (template_loader,)
return template_loader
def restore_template_loaders():
"""
Restores the original template loaders after
:meth:`setup_test_template_loader` has been run.
"""
loader.template_source_loaders = getattr(loader, RESTORE_LOADERS_ATTR)
delattr(loader, RESTORE_LOADERS_ATTR)

View File

@ -28,7 +28,7 @@
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import os, sys, time
import os, sys, time, signal
try:
import thread
@ -73,11 +73,18 @@ def code_changed():
def ensure_echo_on():
if termios:
fd = sys.stdin.fileno()
attr_list = termios.tcgetattr(fd)
if not attr_list[3] & termios.ECHO:
attr_list[3] |= termios.ECHO
termios.tcsetattr(fd, termios.TCSANOW, attr_list)
fd = sys.stdin
if fd.isatty():
attr_list = termios.tcgetattr(fd)
if not attr_list[3] & termios.ECHO:
attr_list[3] |= termios.ECHO
if hasattr(signal, 'SIGTTOU'):
old_handler = signal.signal(signal.SIGTTOU, signal.SIG_IGN)
else:
old_handler = None
termios.tcsetattr(fd, termios.TCSANOW, attr_list)
if old_handler is not None:
signal.signal(signal.SIGTTOU, old_handler)
def reloader_thread():
ensure_echo_on()

View File

@ -67,6 +67,12 @@ def patch_cache_control(response, **kwargs):
if 'max-age' in cc and 'max_age' in kwargs:
kwargs['max_age'] = min(cc['max-age'], kwargs['max_age'])
# Allow overriding private caching and vice versa
if 'private' in cc and 'public' in kwargs:
del cc['private']
elif 'public' in cc and 'private' in kwargs:
del cc['public']
for (k, v) in kwargs.items():
cc[k.replace('_', '-')] = v
cc = ', '.join([dictvalue(el) for el in cc.items()])

View File

@ -319,17 +319,20 @@ class MultiValueDict(dict):
def setdefault(self, key, default=None):
if key not in self:
self[key] = default
return default
return self[key]
def setlistdefault(self, key, default_list=()):
def setlistdefault(self, key, default_list=None):
if key not in self:
if default_list is None:
default_list = []
self.setlist(key, default_list)
return default_list
return self.getlist(key)
def appendlist(self, key, value):
"""Appends an item to the internal list associated with key."""
self.setlistdefault(key, [])
super(MultiValueDict, self).__setitem__(key, self.getlist(key) + [value])
self.setlistdefault(key).append(value)
def items(self):
"""
@ -378,15 +381,15 @@ class MultiValueDict(dict):
other_dict = args[0]
if isinstance(other_dict, MultiValueDict):
for key, value_list in other_dict.lists():
self.setlistdefault(key, []).extend(value_list)
self.setlistdefault(key).extend(value_list)
else:
try:
for key, value in other_dict.items():
self.setlistdefault(key, []).append(value)
self.setlistdefault(key).append(value)
except TypeError:
raise ValueError("MultiValueDict.update() takes either a MultiValueDict or dictionary")
for key, value in kwargs.iteritems():
self.setlistdefault(key, []).append(value)
self.setlistdefault(key).append(value)
class DotExpandedDict(dict):
"""

View File

@ -97,10 +97,17 @@ def make_middleware_decorator(middleware_class):
if result is not None:
return result
raise
if hasattr(middleware, 'process_response'):
result = middleware.process_response(request, response)
if result is not None:
return result
if hasattr(response, 'render') and callable(response.render):
if hasattr(middleware, 'process_template_response'):
response = middleware.process_template_response(request, response)
# Defer running of process_response until after the template
# has been rendered:
if hasattr(middleware, 'process_response'):
callback = lambda response: middleware.process_response(request, response)
response.add_post_render_callback(callback)
else:
if hasattr(middleware, 'process_response'):
return middleware.process_response(request, response)
return response
return wraps(view_func, assigned=available_attrs(view_func))(_wrapped_view)
return _decorator

View File

@ -204,3 +204,15 @@ else:
"""
p1, p2 = urlparse.urlparse(url1), urlparse.urlparse(url2)
return p1[0:2] == p2[0:2]
def is_safe_url(url, host=None):
"""
Return ``True`` if the url is a safe redirection (i.e. it doesn't point to
a different host).
Always returns ``False`` on an empty url.
"""
if not url:
return False
netloc = urlparse.urlparse(url)[1]
return not netloc or netloc == host

View File

@ -447,16 +447,16 @@ def templatize(src, origin=None):
for t in Lexer(src, origin).tokenize():
if incomment:
if t.token_type == TOKEN_BLOCK and t.contents == 'endcomment':
content = u''.join(comment)
content = ''.join(comment)
translators_comment_start = None
for lineno, line in enumerate(content.splitlines(True)):
if line.lstrip().startswith(TRANSLATOR_COMMENT_MARK):
translators_comment_start = lineno
for lineno, line in enumerate(content.splitlines(True)):
if translators_comment_start is not None and lineno >= translators_comment_start:
out.write(u' # %s' % line)
out.write(' # %s' % line)
else:
out.write(u' #\n')
out.write(' #\n')
incomment = False
comment = []
else:

View File

@ -161,3 +161,18 @@ class RedirectView(View):
'request': self.request
})
return http.HttpResponseGone()
def head(self, request, *args, **kwargs):
return self.get(request, *args, **kwargs)
def post(self, request, *args, **kwargs):
return self.get(request, *args, **kwargs)
def options(self, request, *args, **kwargs):
return self.get(request, *args, **kwargs)
def delete(self, request, *args, **kwargs):
return self.get(request, *args, **kwargs)
def put(self, request, *args, **kwargs):
return self.get(request, *args, **kwargs)

View File

@ -211,9 +211,9 @@ class BaseDateListView(MultipleObjectMixin, DateMixin, View):
date_list = queryset.dates(date_field, date_type)[::-1]
if date_list is not None and not date_list and not allow_empty:
raise Http404(_(u"No %(verbose_name_plural)s available") % {
'verbose_name_plural': force_unicode(qs.model._meta.verbose_name_plural)
})
name = force_unicode(queryset.model._meta.verbose_name_plural)
raise Http404(_(u"No %(verbose_name_plural)s available") %
{'verbose_name_plural': name})
return date_list

View File

@ -89,6 +89,7 @@ class MultipleObjectMixin(object):
"""
queryset = kwargs.pop('object_list')
page_size = self.get_paginate_by(queryset)
context_object_name = self.get_context_object_name(queryset)
if page_size:
paginator, page, queryset, is_paginated = self.paginate_queryset(queryset, page_size)
context = {
@ -105,7 +106,6 @@ class MultipleObjectMixin(object):
'object_list': queryset
}
context.update(kwargs)
context_object_name = self.get_context_object_name(queryset)
if context_object_name is not None:
context[context_object_name] = queryset
return context

View File

@ -8,6 +8,8 @@ from django.utils.translation import check_for_language, activate, to_locale, ge
from django.utils.text import javascript_quote
from django.utils.encoding import smart_unicode
from django.utils.formats import get_format_modules, get_format
from django.utils.http import is_safe_url
def set_language(request):
"""
@ -20,11 +22,11 @@ def set_language(request):
redirect to the page in the request (the 'next' parameter) without changing
any state.
"""
next = request.REQUEST.get('next', None)
if not next:
next = request.META.get('HTTP_REFERER', None)
if not next:
next = '/'
next = request.REQUEST.get('next')
if not is_safe_url(url=next, host=request.get_host()):
next = request.META.get('HTTP_REFERER')
if not is_safe_url(url=next, host=request.get_host()):
next = '/'
response = http.HttpResponseRedirect(next)
if request.method == 'POST':
lang_code = request.POST.get('language', None)

View File

@ -127,12 +127,22 @@ class DjangoHTMLTranslator(SmartyPantsHTMLTranslator):
# Don't use border=1, which docutils does by default.
def visit_table(self, node):
self.context.append(self.compact_p)
self.compact_p = True
self._table_row_index = 0 # Needed by Sphinx
self.body.append(self.starttag(node, 'table', CLASS='docutils'))
# <big>? Really?
def depart_table(self, node):
self.compact_p = self.context.pop()
self.body.append('</table>\n')
def visit_desc_parameterlist(self, node):
self.body.append('(')
self.body.append('(') # by default sphinx puts <big> around the "("
self.first_param = 1
self.optional_param_level = 0
self.param_separator = node.child_text_separator
self.required_params_left = sum([isinstance(c, addnodes.desc_parameter)
for c in node.children])
def depart_desc_parameterlist(self, node):
self.body.append(')')

View File

@ -50,11 +50,11 @@ copyright = 'Django Software Foundation and contributors'
# built documents.
#
# The short X.Y version.
version = '1.3'
version = '1.3.7'
# The full version, including alpha/beta/rc tags.
release = '1.3'
release = '1.3.7'
# The next version to be released
django_next_version = '1.3'
django_next_version = '1.4'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.

View File

@ -8,8 +8,8 @@ The login cookie isn't being set correctly, because the domain of the cookie
sent out by Django doesn't match the domain in your browser. Try these two
things:
* Set the ``SESSION_COOKIE_DOMAIN`` setting in your admin config file
to match your domain. For example, if you're going to
* Set the :setting:`SESSION_COOKIE_DOMAIN` setting in your admin config
file to match your domain. For example, if you're going to
"http://www.example.com/admin/" in your browser, in
"myproject.settings" you should set ``SESSION_COOKIE_DOMAIN = 'www.example.com'``.
@ -17,7 +17,7 @@ things:
don't have dots in them. If you're running the admin site on "localhost"
or another domain that doesn't have a dot in it, try going to
"localhost.localdomain" or "127.0.0.1". And set
``SESSION_COOKIE_DOMAIN`` accordingly.
:setting:`SESSION_COOKIE_DOMAIN` accordingly.
I can't log in. When I enter a valid username and password, it brings up the login page again, with a "Please enter a correct username and password" error.
-----------------------------------------------------------------------------------------------------------------------------------------------------------

View File

@ -6,16 +6,17 @@ FAQ: Databases and models
How can I see the raw SQL queries Django is running?
----------------------------------------------------
Make sure your Django ``DEBUG`` setting is set to ``True``. Then, just do
this::
Make sure your Django :setting:`DEBUG` setting is set to ``True``.
Then, just do this::
>>> from django.db import connection
>>> connection.queries
[{'sql': 'SELECT polls_polls.id,polls_polls.question,polls_polls.pub_date FROM polls_polls',
'time': '0.002'}]
``connection.queries`` is only available if ``DEBUG`` is ``True``. It's a list
of dictionaries in order of query execution. Each dictionary has the following::
``connection.queries`` is only available if :setting:`DEBUG` is ``True``.
It's a list of dictionaries in order of query execution. Each dictionary has
the following::
``sql`` -- The raw SQL statement
``time`` -- How long the statement took to execute, in seconds.
@ -90,13 +91,13 @@ Why is Django leaking memory?
Django isn't known to leak memory. If you find your Django processes are
allocating more and more memory, with no sign of releasing it, check to make
sure your ``DEBUG`` setting is set to ``False``. If ``DEBUG`` is ``True``, then
Django saves a copy of every SQL statement it has executed.
sure your :setting:`DEBUG` setting is set to ``False``. If :setting:`DEBUG`
is ``True``, then Django saves a copy of every SQL statement it has executed.
(The queries are saved in ``django.db.connection.queries``. See
`How can I see the raw SQL queries Django is running?`_.)
To fix the problem, set ``DEBUG`` to ``False``.
To fix the problem, set :setting:`DEBUG` to ``False``.
If you need to clear the query list manually at any point in your functions,
just call ``reset_queries()``, like this::

View File

@ -71,7 +71,7 @@ The new custom command can be called using ``python manage.py closepoll
<poll_id>``.
The ``handle()`` method takes zero or more ``poll_ids`` and sets ``poll.opened``
to ``False`` for each one. If the user referenced any nonexistant polls, a
to ``False`` for each one. If the user referenced any nonexistent polls, a
:class:`CommandError` is raised. The ``poll.opened`` attribute does not exist
in the :doc:`tutorial</intro/tutorial01>` and was added to
``polls.models.Poll`` for this example.

View File

@ -627,13 +627,13 @@ resolve the string passed to it in the current context of the page.
Shortcut for simple tags
~~~~~~~~~~~~~~~~~~~~~~~~
Many template tags take a number of arguments -- strings or a template variables
Many template tags take a number of arguments -- strings or template variables
-- and return a string after doing some processing based solely on
the input argument and some external information. For example, the
the input arguments and some external information. For example, the
``current_time`` tag we wrote above is of this variety: we give it a format
string, it returns the time as a string.
To ease the creation of the types of tags, Django provides a helper function,
To ease the creation of these types of tags, Django provides a helper function,
``simple_tag``. This function, which is a method of
``django.template.Library``, takes a function that accepts any number of
arguments, wraps it in a ``render`` function and the other necessary bits
@ -829,7 +829,7 @@ Here's how you'd use this new version of the tag:
.. admonition:: Variable scope in context
Any variable set in the context will only be available in the same ``block``
of the template in which it was assigned. This behaviour is intentional;
of the template in which it was assigned. This behavior is intentional;
it provides a scope for variables so that they don't conflict with
context in other blocks.

View File

@ -246,9 +246,9 @@ Django -- for serving media. Here are some good choices:
* A stripped-down version of Apache_
* Cherokee_
If, however, you have no option but to serve media files on the same Apache
``VirtualHost`` as Django, here's how you can turn off mod_python for a
particular part of the site::
If, however, you have no option but to serve media or static files on the
same Apache ``VirtualHost`` as Django, here's how you can turn off mod_python
for a particular part of the site::
<Location "/media">
SetHandler None
@ -257,9 +257,9 @@ particular part of the site::
Just change ``Location`` to the root URL of your media files. You can also use
``<LocationMatch>`` to match a regular expression.
This example sets up Django at the site root but explicitly disables Django for
the ``media`` subdirectory and any URL that ends with ``.jpg``, ``.gif`` or
``.png``::
This example sets up Django at the site root but explicitly disables Django
for the ``media`` and ``static`` subdirectories and any URL that ends with
``.jpg``, ``.gif`` or ``.png``::
<Location "/">
SetHandler python-program
@ -271,11 +271,14 @@ the ``media`` subdirectory and any URL that ends with ``.jpg``, ``.gif`` or
SetHandler None
</Location>
<Location "/static">
SetHandler None
</Location>
<LocationMatch "\.(jpg|gif|png)$">
SetHandler None
</LocationMatch>
.. _lighttpd: http://www.lighttpd.net/
.. _Nginx: http://wiki.nginx.org/Main
.. _TUX: http://en.wikipedia.org/wiki/TUX_web_server
@ -285,22 +288,24 @@ the ``media`` subdirectory and any URL that ends with ``.jpg``, ``.gif`` or
Serving the admin files
=======================
Note that the Django development server automagically serves admin media files,
but this is not the case when you use any other server arrangement. You're
responsible for setting up Apache, or whichever media server you're using, to
serve the admin files.
Note that the Django development server automagically serves the static files
of the admin app, but this is not the case when you use any other server
arrangement. You're responsible for setting up Apache, or whichever media
server you're using, to serve the admin files.
The admin files live in (:file:`django/contrib/admin/media`) of the Django
distribution.
The admin files live in (:file:`django/contrib/admin/media/admin`) of the
Django distribution.
Here are two recommended approaches:
We **strongly** recommend using :mod:`django.contrib.staticfiles` to handle the
admin files (this means using the :djadmin:`collectstatic` management command
to collect the static files in :setting:`STATIC_ROOT`, and then configuring
your webserver to serve :setting:`STATIC_ROOT` at :setting:`STATIC_URL`), but
here are two other approaches:
1. Create a symbolic link to the admin media files from within your
document root. This way, all of your Django-related files -- code **and**
templates -- stay in one place, and you'll still be able to ``svn
update`` your code to get the latest admin templates, if they change.
1. Create a symbolic link to the admin static files from within your
document root.
2. Or, copy the admin media files so that they live within your Apache
2. Or, copy the admin static files so that they live within your Apache
document root.
Using "eggs" with mod_python

View File

@ -55,12 +55,12 @@ just below the ``import sys`` line to place your project on the path. Remember t
replace 'mysite.settings' with your correct settings file, and '/path/to/mysite'
with your own project's location.
.. _serving-media-files:
.. _serving-files:
Serving media files
===================
Serving files
=============
Django doesn't serve media files itself; it leaves that job to whichever Web
Django doesn't serve files itself; it leaves that job to whichever Web
server you choose.
We recommend using a separate Web server -- i.e., one that's not also running
@ -76,22 +76,29 @@ If, however, you have no option but to serve media files on the same Apache
``VirtualHost`` as Django, you can set up Apache to serve some URLs as
static media, and others using the mod_wsgi interface to Django.
This example sets up Django at the site root, but explicitly serves ``robots.txt``,
``favicon.ico``, any CSS file, and anything in the ``/media/`` URL space as a static
file. All other URLs will be served using mod_wsgi::
This example sets up Django at the site root, but explicitly serves
``robots.txt``, ``favicon.ico``, any CSS file, and anything in the
``/static/`` and ``/media/`` URL space as a static file. All other URLs
will be served using mod_wsgi::
Alias /robots.txt /usr/local/wsgi/static/robots.txt
Alias /favicon.ico /usr/local/wsgi/static/favicon.ico
AliasMatch ^/([^/]*\.css) /usr/local/wsgi/static/styles/$1
Alias /media/ /usr/local/wsgi/static/media/
Alias /media/ /usr/local/wsgi/media/
Alias /static/ /usr/local/wsgi/static/
<Directory /usr/local/wsgi/static>
Order deny,allow
Allow from all
</Directory>
<Directory /usr/local/wsgi/media>
Order deny,allow
Allow from all
</Directory>
WSGIScriptAlias / /usr/local/wsgi/scripts/django.wsgi
<Directory /usr/local/wsgi/scripts>
@ -105,8 +112,8 @@ file. All other URLs will be served using mod_wsgi::
.. _Apache: http://httpd.apache.org/
.. _Cherokee: http://www.cherokee-project.com/
More details on configuring a mod_wsgi site to serve static files can be found
in the mod_wsgi documentation on `hosting static files`_.
.. More details on configuring a mod_wsgi site to serve static files can be found
.. in the mod_wsgi documentation on `hosting static files`_.
.. _hosting static files: http://code.google.com/p/modwsgi/wiki/ConfigurationGuidelines#Hosting_Of_Static_Files
@ -115,22 +122,24 @@ in the mod_wsgi documentation on `hosting static files`_.
Serving the admin files
=======================
Note that the Django development server automagically serves admin media files,
but this is not the case when you use any other server arrangement. You're
responsible for setting up Apache, or whichever media server you're using, to
serve the admin files.
Note that the Django development server automagically serves the static files
of the admin app, but this is not the case when you use any other server
arrangement. You're responsible for setting up Apache, or whichever media
server you're using, to serve the admin files.
The admin files live in (:file:`django/contrib/admin/media`) of the Django
distribution.
The admin files live in (:file:`django/contrib/admin/media/admin`) of the
Django distribution.
Here are two recommended approaches:
We **strongly** recommend using :mod:`django.contrib.staticfiles` to handle the
admin files (this means using the :djadmin:`collectstatic` management command
to collect the static files in :setting:`STATIC_ROOT`, and then configuring
your webserver to serve :setting:`STATIC_ROOT` at :setting:`STATIC_URL`), but
here are two other approaches:
1. Create a symbolic link to the admin media files from within your
document root. This way, all of your Django-related files -- code **and**
templates -- stay in one place, and you'll still be able to ``svn
update`` your code to get the latest admin templates, if they change.
1. Create a symbolic link to the admin static files from within your
document root.
2. Or, copy the admin media files so that they live within your Apache
2. Or, copy the admin static files so that they live within your Apache
document root.
Details

View File

@ -55,7 +55,7 @@ message file specific to the project you are composing. The choice is yours.
All message file repositories are structured the same way. They are:
* All paths listed in ``LOCALE_PATHS`` in your settings file are
* All paths listed in :setting:`LOCALE_PATHS` in your settings file are
searched for ``<language>/LC_MESSAGES/django.(po|mo)``
* ``$PROJECTPATH/locale/<language>/LC_MESSAGES/django.(po|mo)`` --
deprecated, see above.

View File

@ -13,6 +13,8 @@ but initial SQL is also quite a bit more flexible.
.. _initial data as sql: `providing initial sql data`_
.. _initial data via fixtures: `providing initial data with fixtures`_
.. _initial-data-via-fixtures:
Providing initial data with fixtures
====================================
@ -65,12 +67,12 @@ And here's that same fixture as YAML:
You'll store this data in a ``fixtures`` directory inside your app.
Loading data is easy: just call :djadmin:`manage.py loaddata fixturename
<loaddata>`, where *fixturename* is the name of the fixture file you've created.
Every time you run :djadmin:`loaddata` the data will be read from the fixture
and re-loaded into the database. Note that this means that if you change one of
the rows created by a fixture and then run :djadmin:`loaddata` again you'll
wipe out any changes you've made.
Loading data is easy: just call :djadmin:`manage.py loaddata <fixturename>
<loaddata>`, where ``<fixturename>`` is the name of the fixture file you've
created. Every time you run :djadmin:`loaddata` the data will be read from the
fixture and re-loaded into the database. Note that this means that if you
change one of the rows created by a fixture and then run :djadmin:`loaddata`
again you'll wipe out any changes you've made.
Automatically loading initial data fixtures
-------------------------------------------
@ -80,6 +82,17 @@ be loaded every time you run :djadmin:`syncdb`. This is extremely convenient,
but be careful: remember that the data will be refreshed *every time* you run
:djadmin:`syncdb`. So don't use ``initial_data`` for data you'll want to edit.
Where Django finds fixture files
--------------------------------
By default, Django looks in the ``fixtures`` directory inside each app for
fixtures. You can set the :setting:`FIXTURE_DIRS` setting to a list of
additional directories where Django should look.
When running :djadmin:`manage.py loaddata <loaddata>`, you can also
specify an absolute path to a fixture file, which overrides searching
the usual directories.
.. seealso::
Fixtures are also used by the :ref:`testing framework

View File

@ -65,7 +65,7 @@ At this point, Django on Jython should behave nearly identically to Django
running on standard Python. However, are a few differences to keep in mind:
* Remember to use the ``jython`` command instead of ``python``. The
documentation uses ``python`` for consistancy, but if you're using Jython
documentation uses ``python`` for consistency, but if you're using Jython
you'll want to mentally replace ``python`` with ``jython`` every time it
occurs.

View File

@ -34,81 +34,91 @@ single location that can easily be served in production.
Using ``django.contrib.staticfiles``
====================================
Here's the basic usage in a nutshell:
Basic usage
-----------
1. Put your static files somewhere that ``staticfiles`` will find them.
1. Put your static files somewhere that ``staticfiles`` will find them.
By default, this means within ``static/`` subdirectories of apps in your
:setting:`INSTALLED_APPS`.
By default, this means within ``static/`` subdirectories of apps in your
:setting:`INSTALLED_APPS`.
Many projects will also have static assets that aren't tied to a
particular app; you can give ``staticfiles`` additional directories to
search via the :setting:`STATICFILES_DIRS` setting .
Your project will probably also have static assets that aren't tied to a
particular app. The :setting:`STATICFILES_DIRS` setting is a tuple of
filesystem directories to check when loading static files. It's a search
path that is by default empty. See the :setting:`STATICFILES_DIRS` docs
how to extend this list of additional paths.
See the documentation for the :setting:`STATICFILES_FINDERS` setting for
details on how ``staticfiles`` finds your files.
Additionally, see the documentation for the :setting:`STATICFILES_FINDERS`
setting for details on how ``staticfiles`` finds your files.
2. Make sure that ``django.contrib.staticfiles`` is in your
:setting:`INSTALLED_APPS`.
2. Make sure that ``django.contrib.staticfiles`` is included in your
:setting:`INSTALLED_APPS`.
For :ref:`local development<staticfiles-development>`, if you are using
:ref:`runserver<staticfiles-runserver>` or adding
:ref:`staticfiles_urlpatterns<staticfiles-development>` to your URLconf,
you're done! Your static files will automatically be served at the
default :setting:`STATIC_URL` of ``/static/``.
For :ref:`local development<staticfiles-development>`, if you are using
:ref:`runserver<staticfiles-runserver>` or adding
:ref:`staticfiles_urlpatterns<staticfiles-development>` to your
URLconf, you're done with the setup -- your static files will
automatically be served at the default (for
:djadmin:`newly created<startproject>` projects) :setting:`STATIC_URL`
of ``/static/``.
3. You'll probably need to refer to these files in your templates. The
easiest method is to use the included context processor which will allow
template code like:
3. You'll probably need to refer to these files in your templates. The
easiest method is to use the included context processor which allows
template code like:
.. code-block:: html+django
.. code-block:: html+django
<img src="{{ STATIC_URL }}images/hi.jpg />
<img src="{{ STATIC_URL }}images/hi.jpg" />
See :ref:`staticfiles-in-templates` for more details, including an
alternate method (using a template tag).
See :ref:`staticfiles-in-templates` for more details, including an
alternate method using a template tag.
Deploying static files in a nutshell
------------------------------------
When you're ready to move out of local development and deploy your project:
1. Set the :setting:`STATIC_URL` setting to the public URL for your static
files (in some cases, the default value of ``/static/`` may still be
fine).
1. Set the :setting:`STATIC_URL` setting to the public URL for your static
files (in most cases, the default value of ``/static/`` is just fine).
2. Set the :setting:`STATIC_ROOT` setting to point to where you'd like your
static files collected to when you use the :djadmin:`collectstatic`
management command. For example::
2. Set the :setting:`STATIC_ROOT` setting to point to the filesystem path
you'd like your static files collected to when you use the
:djadmin:`collectstatic` management command. For example::
STATIC_ROOT = "/home/jacob/projects/mysite.com/sitestatic"
STATIC_ROOT = "/home/jacob/projects/mysite.com/sitestatic"
3. Run the :djadmin:`collectstatic` management command::
3. Run the :djadmin:`collectstatic` management command::
./manage.py collectstatic
./manage.py collectstatic
This'll churn through your static file storage and copy them into the
directory given by :setting:`STATIC_ROOT`.
This'll churn through your static file storage and copy them into the
directory given by :setting:`STATIC_ROOT`.
4. Deploy those files by configuring your webserver of choice to serve the
files in :setting:`STATIC_ROOT` at :setting:`STATIC_URL`.
4. Deploy those files by configuring your webserver of choice to serve the
files in :setting:`STATIC_ROOT` at :setting:`STATIC_URL`.
:ref:`staticfiles-production` covers some common deployment strategies
for static files.
:ref:`staticfiles-production` covers some common deployment strategies
for static files.
Those are the basics. For more details on common configuration options, read on;
for a detailed reference of the settings, commands, and other bits included with
the framework see :doc:`the staticfiles reference </ref/contrib/staticfiles>`.
Those are the **basics**. For more details on common configuration options,
read on; for a detailed reference of the settings, commands, and other bits
included with the framework see
:doc:`the staticfiles reference </ref/contrib/staticfiles>`.
.. note::
In previous versions of Django, it was common to place static assets in
:setting:`MEDIA_ROOT` along with user-uploaded files, and serve them both at
:setting:`MEDIA_URL`. Part of the purpose of introducing the ``staticfiles``
app is to make it easier to keep static files separate from user-uploaded
files. For this reason, you need to make your :setting:`MEDIA_ROOT` and
:setting:`MEDIA_ROOT` along with user-uploaded files, and serve them both
at :setting:`MEDIA_URL`. Part of the purpose of introducing the
``staticfiles`` app is to make it easier to keep static files separate
from user-uploaded files.
For this reason, you need to make your :setting:`MEDIA_ROOT` and
:setting:`MEDIA_URL` different from your :setting:`STATIC_ROOT` and
:setting:`STATIC_URL`. You will need to arrange for serving of files in
:setting:`MEDIA_ROOT` yourself; ``staticfiles`` does not deal with
user-uploaded files at all. You can, however, use
:func:`~django.views.static.serve` view for serving :setting:`MEDIA_ROOT`
:func:`django.views.static.serve` view for serving :setting:`MEDIA_ROOT`
in development; see :ref:`staticfiles-other-directories`.
.. _staticfiles-in-templates:
@ -133,7 +143,7 @@ A far better way is to use the value of the :setting:`STATIC_URL` setting
directly in your templates. This means that a switch of static files servers
only requires changing that single value. Much better!
``staticfiles`` inludes two built-in ways of getting at this setting in your
``staticfiles`` includes two built-in ways of getting at this setting in your
templates: a context processor and a template tag.
With a context processor
@ -157,7 +167,7 @@ Once that's done, you can refer to :setting:`STATIC_URL` in your templates:
.. code-block:: html+django
<img src="{{ STATIC_URL }}images/hi.jpg />
<img src="{{ STATIC_URL }}images/hi.jpg" />
If ``{{ STATIC_URL }}`` isn't working in your template, you're probably not
using :class:`~django.template.RequestContext` when rendering the template.
@ -166,7 +176,7 @@ As a brief refresher, context processors add variables into the contexts of
every template. However, context processors require that you use
:class:`~django.template.RequestContext` when rendering templates. This happens
automatically if you're using a :doc:`generic view </ref/class-based-views>`,
but in views written by hand you'll need to explicitally use ``RequestContext``
but in views written by hand you'll need to explicitly use ``RequestContext``
To see how that works, and to read more details, check out
:ref:`subclassing-context-requestcontext`.
@ -282,7 +292,7 @@ parameter.
Since it can become a bit cumbersome to define this URL pattern, Django
ships with a small URL helper function
:func:`~django.conf.urls.static.static` that taks as parameters the prefix
:func:`~django.conf.urls.static.static` that takes as parameters the prefix
such as :setting:`MEDIA_URL` and a dotted path to a view, such as
``'django.views.static.serve'``. Any other function parameter will be
transparently passed to the view.
@ -299,7 +309,7 @@ development::
.. note::
The helper function will only be operational in debug mode and if
This helper function will only be operational in debug mode and if
the given prefix is local (e.g. ``/static/``) and not a URL (e.g.
``http://static.example.com/``).
@ -327,7 +337,7 @@ serving your site, the basic outline gets modified to look something like:
* On the server, run :djadmin:`collectstatic` to copy all the static files
into :setting:`STATIC_ROOT`.
* Point your web server at :setting:`STATIC_ROOT`. For example, here's
:ref:`how to do this under Apache and mod_wsgi <serving-media-files>`.
:ref:`how to do this under Apache and mod_wsgi <serving-files>`.
You'll probably want to automate this process, especially if you've got
multiple web servers. There's any number of ways to do this automation, but
@ -435,7 +445,7 @@ For example, if you've written an S3 storage backend in
Once that's done, all you have to do is run :djadmin:`collectstatic` and your
static files would be pushed through your storage package up to S3. If you
later needed to swich to a different storage provider, it could be as simple
later needed to switch to a different storage provider, it could be as simple
as changing your :setting:`STATICFILES_STORAGE` setting.
For details on how you'd write one of these backends,
@ -447,8 +457,8 @@ For details on how you'd write one of these backends,
storage backends for many common file storage APIs (including `S3`__).
__ http://s3.amazonaws.com/
__ http://code.welldev.org/django-storages/
__ http://code.welldev.org/django-storages/wiki/S3Storage
__ http://code.larlet.fr/django-storages/
__ http://django-storages.readthedocs.org/en/latest/backends/amazon-S3.html
Upgrading from ``django-staticfiles``
=====================================

View File

@ -28,7 +28,7 @@ Having trouble? We'd like to help!
.. _archives of the django-users mailing list: http://groups.google.com/group/django-users/
.. _post a question: http://groups.google.com/group/django-users/
.. _#django IRC channel: irc://irc.freenode.net/django
.. _IRC logs: http://botland.oebfare.com/logger/django/
.. _IRC logs: http://django-irc-logs.com/
.. _ticket tracker: http://code.djangoproject.com/
First steps

View File

@ -104,19 +104,19 @@ following actions:
fix is forthcoming. We'll give a rough timeline and ask the reporter
to keep the issue confidential until we announce it.
* Halt all other development as long as is needed to develop a fix,
including patches against the current and two previous releases.
* Focus on developing a fix as quickly as possible and produce patches
against the current and two previous releases.
* Determine a go-public date for announcing the vulnerability and the fix.
To try to mitigate a possible "arms race" between those applying the
patch and those trying to exploit the hole, we will not announce
security problems immediately.
* Pre-notify everyone we know to be running the affected version(s) of
Django. We will send these notifications through private e-mail
which will include documentation of the vulnerability, links to the
relevant patch(es), and a request to keep the vulnerability
confidential until the official go-public date.
* Pre-notify third-party distributors of Django ("vendors"). We will send
these vendor notifications through private email which will include
documentation of the vulnerability, links to the relevant patch(es), and a
request to keep the vulnerability confidential until the official
go-public date.
* Publicly announce the vulnerability and the fix on the pre-determined
go-public date. This will probably mean a new release of Django, but
@ -454,9 +454,8 @@ infrastructure available to Django applications described in the
These translations are contributed by Django users worldwide. If you find an
incorrect translation or want to discuss specific translations, go to the
`translation team`_ page for that language. If you would like to help out
with translating or add a language that isn't yet translated, here's what
to do:
`Django project page`_ on `Transifex`_. If you would like to help out with
translating or add a language that isn't yet translated, here's what to do:
* Join the `Django i18n mailing list`_ and introduce yourself.
@ -464,15 +463,15 @@ to do:
* Signup at `Transifex`_ and visit the `Django project page`_.
* On the "`Translation Teams`_" page, choose the language team you want
to work with, **or** -- in case the language team doesn't exist yet --
request a new team by clicking on the "Request a new team" button
and select the appropriate language.
* On the `Django project page`_ page, choose the language you want
to work on, **or** -- in case the language doesn't exist yet --
request a new language team by clicking on the "Request language"
link and select the appropriate language.
* Then, click the "Join this Team" button to become a member of this team.
* Then, click the "Join Team" button to become a member of this team.
Every team has at least one coordinator who is responsible to review
your membership request. You can of course also contact the team
coordinator to clarify procedual problems and handle the actual
coordinator to clarify procedural problems and handle the actual
translation process.
* Once you are a member of a team choose the translation resource you
@ -499,8 +498,6 @@ to do:
.. _Django i18n mailing list: http://groups.google.com/group/django-i18n/
.. _Transifex: http://www.transifex.net/
.. _Django project page: http://www.transifex.net/projects/p/django/
.. _translation teams: http://www.transifex.net/projects/p/django/teams/
.. _translation team: http://www.transifex.net/projects/p/django/teams/
.. _Transifex Help: http://help.transifex.net/
Submitting javascript patches
@ -539,7 +536,7 @@ binary, so relinking that command may be necessary as well.
Please don't forget to run ``compress.py`` and include the ``diff`` of the
minified scripts when submitting patches for Django's javascript.
.. _Closure Compiler: http://code.google.com/closure/compiler/
.. _Closure Compiler: https://developers.google.com/closure/compiler/
Django conventions
==================
@ -872,7 +869,7 @@ repository:
For the curious: We're using a `Trac post-commit hook`_ for this.
.. _Trac post-commit hook: http://trac.edgewall.org/browser/trunk/contrib/trac-post-commit-hook
.. _Trac post-commit hook: http://trac.edgewall.org/browser/trunk/contrib/trac-svn-post-commit-hook.cmd
* If your commit references a ticket in the Django `ticket tracker`_ but
does *not* close the ticket, include the phrase "Refs #abc", where "abc"

View File

@ -20,7 +20,7 @@ their deprecation, as per the :ref:`Django deprecation policy
* 1.4
* ``CsrfResponseMiddleware``. This has been deprecated since the 1.2
release, in favour of the template tag method for inserting the CSRF
release, in favor of the template tag method for inserting the CSRF
token. ``CsrfMiddleware``, which combines ``CsrfResponseMiddleware``
and ``CsrfViewMiddleware``, is also deprecated.
@ -108,6 +108,12 @@ their deprecation, as per the :ref:`Django deprecation policy
beyond that of a simple ``TextField`` since the removal of oldforms.
All uses of ``XMLField`` can be replaced with ``TextField``.
* ``django.db.models.fields.URLField.verify_exists`` has been
deprecated due to intractable security and performance
issues. Validation behavior has been removed in 1.4, and the
argument will be removed in 1.5.
* 1.5
* The ``mod_python`` request handler has been deprecated since the 1.3
release. The ``mod_wsgi`` handler should be used instead.
@ -126,7 +132,7 @@ their deprecation, as per the :ref:`Django deprecation policy
* The undocumented function
:func:`django.contrib.formtools.utils.security_hash`
is deprecated, in favour of :func:`django.contrib.formtools.utils.form_hmac`
is deprecated, in favor of :func:`django.contrib.formtools.utils.form_hmac`
* The function-based generic views have been deprecated in
favor of their class-based cousins. The following modules
@ -158,7 +164,7 @@ their deprecation, as per the :ref:`Django deprecation policy
a :class:`~django.contrib.gis.geos.GEOSException` when called
on a geometry with no SRID value.
* :class:`~django.http.CompatCookie` will be removed in favour of
* :class:`~django.http.CompatCookie` will be removed in favor of
:class:`~django.http.SimpleCookie`.
* :class:`django.core.context_processors.PermWrapper` and
@ -167,9 +173,15 @@ their deprecation, as per the :ref:`Django deprecation policy
and :class:`django.contrib.auth.context_processors.PermLookupDict`,
respectively.
* The ``MEDIA_URL`` or ``STATIC_URL`` settings are required to end
with a trailing slash to ensure there is a consistent way to
combine paths in templates.
* The :setting:`MEDIA_URL` or :setting:`STATIC_URL` settings are
required to end with a trailing slash to ensure there is a consistent
way to combine paths in templates.
* Translations located under the so-called *project path* will be
ignored during the translation building process performed at runtime.
The :setting:`LOCALE_PATHS` setting can be used for the same task by
including the filesystem path to a ``locale`` directory containing
non-app-specific translations in its value.
* 2.0
* ``django.views.defaults.shortcut()``. This function has been moved

View File

@ -99,6 +99,13 @@ varying levels:
* Security fixes will be applied to the current trunk and the previous two
minor releases.
* Documentation fixes will generally be more freely backported to the last
release branch (at the discretion of the committer), and don't need to meet
the "critical fixes only" bar as it's highly advantageous to have the docs
for the last release be up-to-date and correct, and the downside of
backporting (risk of introducing regressions) is much less of a concern
with doc fixes.
As a concrete example, consider a moment in time halfway between the release of
Django 1.3 and 1.4. At this point in time:
@ -111,6 +118,9 @@ Django 1.3 and 1.4. At this point in time:
``1.2.X`` branch. Security fixes will trigger the release of ``1.3.1``,
``1.2.1``, etc.
* Documentation fixes will be applied to trunk, and if easily backported, to
the ``1.3.X`` branch.
.. _release-process:
Release process

View File

@ -199,7 +199,7 @@ branch ``django/branches/releases/1.0.X`` was created to receive bug
fixes, and shortly after the release of Django 1.1 the branch
``django/branches/releases/1.1.X`` was created.
Prior to the Django 1.0 release, these branches were maintaind within
Prior to the Django 1.0 release, these branches were maintained within
the top-level ``django/branches`` directory, and so the following
branches exist there and provided support for older Django releases:

View File

@ -31,6 +31,6 @@ place: read this material to quickly get up and running.
.. _python: http://python.org/
.. _list of Python resources for non-programmers: http://wiki.python.org/moin/BeginnersGuide/NonProgrammers
.. _dive into python: http://diveintopython.org/
.. _dive into python: http://diveintopython.net/
.. _dead-tree version: http://www.amazon.com/exec/obidos/ASIN/1590593561/ref=nosim/jacobian20
.. _books about Python: http://wiki.python.org/moin/PythonBooks

View File

@ -230,7 +230,7 @@ templates. In your Django settings, you specify a list of directories to check
for templates. If a template doesn't exist in the first directory, it checks the
second, and so on.
Let's say the ``news/article_detail.html`` template was found. Here's what that
Let's say the ``news/year_archive.html`` template was found. Here's what that
might look like:
.. code-block:: html+django

View File

@ -36,8 +36,13 @@ including database configuration, Django-specific options and
application-specific settings.
From the command line, ``cd`` into a directory where you'd like to store your
code, then run the command ``django-admin.py startproject mysite``. This will
create a ``mysite`` directory in your current directory.
code, then run the following command:
.. code-block:: bash
django-admin.py startproject mysite
This will create a ``mysite`` directory in your current directory.
.. admonition:: Script name may differ in distribution packages
@ -54,7 +59,7 @@ create a ``mysite`` directory in your current directory.
can be run as a program. To do this, open Terminal.app and navigate (using
the ``cd`` command) to the directory where :doc:`django-admin.py
</ref/django-admin>` is installed, then run the command
``chmod +x django-admin.py``.
``sudo chmod +x django-admin.py``.
.. note::
@ -168,11 +173,11 @@ module-level variables representing Django settings. Change the
following keys in the :setting:`DATABASES` ``'default'`` item to match
your databases connection settings.
* :setting:`ENGINE` -- Either
* :setting:`ENGINE <DATABASE-ENGINE>` -- Either
``'django.db.backends.postgresql_psycopg2'``,
``'django.db.backends.mysql'`` or
``'django.db.backends.sqlite3'``. Other backends are
:setting:`also available <ENGINE>`.
:setting:`also available <DATABASE-ENGINE>`.
* :setting:`NAME` -- The name of your database. If you're using
SQLite, the database will be a file on your computer; in that
@ -593,7 +598,7 @@ automatically-generated admin.
Unicode string, and ``str(p)`` will return a normal string, with characters
encoded as UTF-8.
If all of this is jibberish to you, just remember to add
If all of this is gibberish to you, just remember to add
:meth:`~django.db.models.Model.__unicode__` methods to your models. With any
luck, things should Just Work for you.
@ -687,10 +692,9 @@ Save these changes and start a new Python interactive shell by running
For more information on model relations, see :doc:`Accessing related objects
</ref/models/relations>`. For more on how to use double underscores to perform
field lookups via the API, see `Field lookups`__. For full details on the
database API, see our :doc:`Database API reference </topics/db/queries>`.
__ http://docs.djangoproject.com/en/1.2/topics/db/queries/#field-lookups
field lookups via the API, see :ref:`Field lookups <field-lookups-intro>`. For
full details on the database API, see our :doc:`Database API reference
</topics/db/queries>`.
When you're comfortable with the API, read :doc:`part 2 of this tutorial
</intro/tutorial02>` to get Django's automatic admin working.

View File

@ -40,22 +40,22 @@ activate the admin site for your installation, do these three things:
.. parsed-literal::
from django.conf.urls.defaults import *
from django.conf.urls.defaults import patterns, include, url
# Uncomment the next two lines to enable the admin:
**from django.contrib import admin**
**admin.autodiscover()**
urlpatterns = patterns('',
# Example:
# (r'^mysite/', include('mysite.foo.urls')),
# Examples:
# url(r'^$', 'mysite.views.home', name='home'),
# url(r'^mysite/', include('mysite.foo.urls')),
# Uncomment the admin/doc line below and add 'django.contrib.admindocs'
# to INSTALLED_APPS to enable admin documentation:
# (r'^admin/doc/', include('django.contrib.admindocs.urls')),
# Uncomment the admin/doc line below to enable admin documentation:
# url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
# Uncomment the next line to enable the admin:
**(r'^admin/', include(admin.site.urls)),**
**url(r'^admin/', include(admin.site.urls)),**
)
(The bold lines are the ones that needed to be uncommented.)
@ -343,9 +343,11 @@ an arbitrary method is not supported. Also note that the column header for
underscores replaced with spaces). But you can change that by giving that
method (in ``models.py``) a ``short_description`` attribute::
def was_published_today(self):
return self.pub_date.date() == datetime.date.today()
was_published_today.short_description = 'Published today?'
class Poll(models.Model):
# ...
def was_published_today(self):
return self.pub_date.date() == datetime.date.today()
was_published_today.short_description = 'Published today?'
Edit your admin.py file again and add an improvement to the Poll change list page: Filters. Add the
following line to ``PollAdmin``::
@ -405,14 +407,14 @@ By default, :setting:`TEMPLATE_DIRS` is empty. So, let's add a line to it, to
tell Django where our templates live::
TEMPLATE_DIRS = (
"/home/my_username/mytemplates", # Change this to your own directory.
'/home/my_username/mytemplates', # Change this to your own directory.
)
Now copy the template ``admin/base_site.html`` from within the default Django
admin template directory in the source code of Django itself
(``django/contrib/admin/templates``) into an ``admin`` subdirectory of
whichever directory you're using in :setting:`TEMPLATE_DIRS`. For example, if
your :setting:`TEMPLATE_DIRS` includes ``"/home/my_username/mytemplates"``, as
your :setting:`TEMPLATE_DIRS` includes ``'/home/my_username/mytemplates'``, as
above, then copy ``django/contrib/admin/templates/admin/base_site.html`` to
``/home/my_username/mytemplates/admin/base_site.html``. Don't forget that
``admin`` subdirectory.

View File

@ -78,17 +78,17 @@ point at that file::
Time for an example. Edit ``mysite/urls.py`` so it looks like this::
from django.conf.urls.defaults import *
from django.conf.urls.defaults import patterns, include, url
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('',
(r'^polls/$', 'polls.views.index'),
(r'^polls/(?P<poll_id>\d+)/$', 'polls.views.detail'),
(r'^polls/(?P<poll_id>\d+)/results/$', 'polls.views.results'),
(r'^polls/(?P<poll_id>\d+)/vote/$', 'polls.views.vote'),
(r'^admin/', include(admin.site.urls)),
url(r'^polls/$', 'polls.views.index'),
url(r'^polls/(?P<poll_id>\d+)/$', 'polls.views.detail'),
url(r'^polls/(?P<poll_id>\d+)/results/$', 'polls.views.results'),
url(r'^polls/(?P<poll_id>\d+)/vote/$', 'polls.views.vote'),
url(r'^admin/', include(admin.site.urls)),
)
This is worth a review. When somebody requests a page from your Web site -- say,
@ -112,7 +112,7 @@ what you can do with them. And there's no need to add URL cruft such as ``.php``
-- unless you have a sick sense of humor, in which case you can do something
like this::
(r'^polls/latest\.php$', 'polls.views.index'),
url(r'^polls/latest\.php$', 'polls.views.index'),
But, don't do that. It's silly.
@ -357,22 +357,23 @@ the list is empty.
Write a 404 (page not found) view
=================================
When you raise :exc:`~django.http.Http404` from within a view, Django will load
a special view devoted to handling 404 errors. It finds it by looking for the
variable ``handler404``, which is a string in Python dotted syntax -- the same
format the normal URLconf callbacks use. A 404 view itself has nothing special:
It's just a normal view.
When you raise :exc:`~django.http.Http404` from within a view, Django
will load a special view devoted to handling 404 errors. It finds it
by looking for the variable ``handler404`` in your root URLconf (and
only in your root URLconf; setting ``handler404`` anywhere else will
have no effect), which is a string in Python dotted syntax -- the same
format the normal URLconf callbacks use. A 404 view itself has nothing
special: It's just a normal view.
You normally won't have to bother with writing 404 views. By default, URLconfs
have the following line up top::
You normally won't have to bother with writing 404 views. If you don't set
``handler404``, the built-in view :func:`django.views.defaults.page_not_found`
is used by default. In this case, you still have one obligation: To create a
``404.html`` template in the root of your template directory. The default 404
view will use that template for all 404 errors. If :setting:`DEBUG` is set to
``False`` (in your settings module) and if you didn't create a ``404.html``
file, an ``Http500`` is raised instead. So remember to create a ``404.html``.
from django.conf.urls.defaults import *
That takes care of setting ``handler404`` in the current module. As you can see
in ``django/conf/urls/defaults.py``, ``handler404`` is set to
:func:`django.views.defaults.page_not_found` by default.
Four more things to note about 404 views:
A couple more things to note about 404 views:
* If :setting:`DEBUG` is set to ``True`` (in your settings module) then your
404 view will never be used (and thus the ``404.html`` template will never
@ -381,21 +382,12 @@ Four more things to note about 404 views:
* The 404 view is also called if Django doesn't find a match after checking
every regular expression in the URLconf.
* If you don't define your own 404 view -- and simply use the default, which
is recommended -- you still have one obligation: To create a ``404.html``
template in the root of your template directory. The default 404 view will
use that template for all 404 errors.
* If :setting:`DEBUG` is set to ``False`` (in your settings module) and if
you didn't create a ``404.html`` file, an ``Http500`` is raised instead.
So remember to create a ``404.html``.
Write a 500 (server error) view
===============================
Similarly, URLconfs may define a ``handler500``, which points to a view to call
in case of server errors. Server errors happen when you have runtime errors in
view code.
Similarly, your root URLconf may define a ``handler500``, which points
to a view to call in case of server errors. Server errors happen when
you have runtime errors in view code.
Use the template system
=======================
@ -432,10 +424,10 @@ Take some time to play around with the views and template system. As you edit
the URLconf, you may notice there's a fair bit of redundancy in it::
urlpatterns = patterns('',
(r'^polls/$', 'polls.views.index'),
(r'^polls/(?P<poll_id>\d+)/$', 'polls.views.detail'),
(r'^polls/(?P<poll_id>\d+)/results/$', 'polls.views.results'),
(r'^polls/(?P<poll_id>\d+)/vote/$', 'polls.views.vote'),
url(r'^polls/$', 'polls.views.index'),
url(r'^polls/(?P<poll_id>\d+)/$', 'polls.views.detail'),
url(r'^polls/(?P<poll_id>\d+)/results/$', 'polls.views.results'),
url(r'^polls/(?P<poll_id>\d+)/vote/$', 'polls.views.vote'),
)
Namely, ``polls.views`` is in every callback.
@ -445,10 +437,10 @@ common prefixes. You can factor out the common prefixes and add them as the
first argument to :func:`~django.conf.urls.defaults.patterns`, like so::
urlpatterns = patterns('polls.views',
(r'^polls/$', 'index'),
(r'^polls/(?P<poll_id>\d+)/$', 'detail'),
(r'^polls/(?P<poll_id>\d+)/results/$', 'results'),
(r'^polls/(?P<poll_id>\d+)/vote/$', 'vote'),
url(r'^polls/$', 'index'),
url(r'^polls/(?P<poll_id>\d+)/$', 'detail'),
url(r'^polls/(?P<poll_id>\d+)/results/$', 'results'),
url(r'^polls/(?P<poll_id>\d+)/vote/$', 'vote'),
)
This is functionally identical to the previous formatting. It's just a bit
@ -459,20 +451,20 @@ callback in your URLconf, you can concatenate multiple
:func:`~django.conf.urls.defaults.patterns`. Your full ``mysite/urls.py`` might
now look like this::
from django.conf.urls.defaults import *
from django.conf.urls.defaults import patterns, include, url
from django.contrib import admin
admin.autodiscover()
urlpatterns = patterns('polls.views',
(r'^polls/$', 'index'),
(r'^polls/(?P<poll_id>\d+)/$', 'detail'),
(r'^polls/(?P<poll_id>\d+)/results/$', 'results'),
(r'^polls/(?P<poll_id>\d+)/vote/$', 'vote'),
url(r'^polls/$', 'index'),
url(r'^polls/(?P<poll_id>\d+)/$', 'detail'),
url(r'^polls/(?P<poll_id>\d+)/results/$', 'results'),
url(r'^polls/(?P<poll_id>\d+)/vote/$', 'vote'),
)
urlpatterns += patterns('',
(r'^admin/', include(admin.site.urls)),
url(r'^admin/', include(admin.site.urls)),
)
Decoupling the URLconfs
@ -502,8 +494,8 @@ Copy the file ``mysite/urls.py`` to ``polls/urls.py``. Then, change
admin.autodiscover()
urlpatterns = patterns('',
(r'^polls/', include('polls.urls')),
(r'^admin/', include(admin.site.urls)),
url(r'^polls/', include('polls.urls')),
url(r'^admin/', include(admin.site.urls)),
)
:func:`~django.conf.urls.defaults.include` simply references another URLconf.
@ -523,16 +515,16 @@ Here's what happens if a user goes to "/polls/34/" in this system:
Now that we've decoupled that, we need to decouple the ``polls.urls``
URLconf by removing the leading "polls/" from each line, and removing the
lines registering the admin site. Your ``polls.urls`` file should now look like
lines registering the admin site. Your ``polls/urls.py`` file should now look like
this::
from django.conf.urls.defaults import *
from django.conf.urls.defaults import patterns, include, url
urlpatterns = patterns('polls.views',
(r'^$', 'index'),
(r'^(?P<poll_id>\d+)/$', 'detail'),
(r'^(?P<poll_id>\d+)/results/$', 'results'),
(r'^(?P<poll_id>\d+)/vote/$', 'vote'),
url(r'^$', 'index'),
url(r'^(?P<poll_id>\d+)/$', 'detail'),
url(r'^(?P<poll_id>\d+)/results/$', 'results'),
url(r'^(?P<poll_id>\d+)/vote/$', 'vote'),
)
The idea behind :func:`~django.conf.urls.defaults.include` and URLconf

View File

@ -218,13 +218,13 @@ Read on for details.
First, open the ``polls/urls.py`` URLconf. It looks like this, according to the
tutorial so far::
from django.conf.urls.defaults import *
from django.conf.urls.defaults import patterns, include, url
urlpatterns = patterns('polls.views',
(r'^$', 'index'),
(r'^(?P<poll_id>\d+)/$', 'detail'),
(r'^(?P<poll_id>\d+)/results/$', 'results'),
(r'^(?P<poll_id>\d+)/vote/$', 'vote'),
url(r'^$', 'index'),
url(r'^(?P<poll_id>\d+)/$', 'detail'),
url(r'^(?P<poll_id>\d+)/results/$', 'results'),
url(r'^(?P<poll_id>\d+)/vote/$', 'vote'),
)
Change it like so::
@ -234,12 +234,12 @@ Change it like so::
from polls.models import Poll
urlpatterns = patterns('',
(r'^$',
url(r'^$',
ListView.as_view(
queryset=Poll.objects.order_by('-pub_date')[:5],
context_object_name='latest_poll_list',
template_name='polls/index.html')),
(r'^(?P<pk>\d+)/$',
url(r'^(?P<pk>\d+)/$',
DetailView.as_view(
model=Poll,
template_name='polls/detail.html')),
@ -248,7 +248,7 @@ Change it like so::
model=Poll,
template_name='polls/results.html'),
name='poll_results'),
(r'^(?P<poll_id>\d+)/vote/$', 'polls.views.vote'),
url(r'^(?P<poll_id>\d+)/vote/$', 'polls.views.vote'),
)
We're using two generic views here:

View File

@ -81,20 +81,20 @@ TemplateResponseMixin
The response class to be returned by ``render_to_response`` method.
Default is
:class:`TemplateResponse <django.template.response.TemplateResponse>`.
The template and context of TemplateResponse instances can be
The template and context of ``TemplateResponse`` instances can be
altered later (e.g. in
:ref:`template response middleware <template-response-middleware>`).
Create TemplateResponse subclass and pass set it to
``template_response_class`` if you need custom template loading or
custom context object instantiation.
If you need custom template loading or custom context object
instantiation, create a ``TemplateResponse`` subclass and assign it to
``response_class``.
.. method:: render_to_response(context, **response_kwargs)
Returns a ``self.template_response_class`` instance.
Returns a ``self.response_class`` instance.
If any keyword arguments are provided, they will be
passed to the constructor of the response instance.
passed to the constructor of the response class.
Calls :meth:`~TemplateResponseMixin.get_template_names()` to obtain the
list of template names that will be searched looking for an existent
@ -431,7 +431,7 @@ FormMixin
.. method:: get_form_kwargs()
Build the keyword arguments requried to instanciate an the form.
Build the keyword arguments required to instantiate the form.
The ``initial`` argument is set to :meth:`.get_initial`. If the
request is a ``POST`` or ``PUT``, the request data (``request.POST``
@ -781,11 +781,11 @@ BaseDateListView
.. method:: get_dated_items():
Returns a 3-tuple containing (``date_list``, ``latest``,
Returns a 3-tuple containing (``date_list``, ``object_list``,
``extra_context``).
``date_list`` is the list of dates for which data is available.
``object_list`` is the list of objects ``extra_context`` is a
``object_list`` is the list of objects. ``extra_context`` is a
dictionary of context data that will be added to any context data
provided by the
:class:`~django.views.generic.list.MultipleObjectMixin`.
@ -1062,8 +1062,8 @@ DeleteView
**Mixins**
* :class:`django.views.generic.edit.ModelFormMixin`
* :class:`django.views.generic.edit.ProcessFormView`
* :class:`django.views.generic.edit.DeletionMixin`
* :class:`django.views.generic.detail.BaseDetailView`
**Notes**

View File

@ -19,8 +19,10 @@ There are six steps in activating the Django admin site:
1. Add ``'django.contrib.admin'`` to your :setting:`INSTALLED_APPS`
setting.
2. Admin has two dependencies - :mod:`django.contrib.auth` and
:mod:`django.contrib.contenttypes`. If these applications are not
2. The admin has four dependencies - :mod:`django.contrib.auth`,
:mod:`django.contrib.contenttypes`,
:mod:`django.contrib.messages` and
:mod:`django.contrib.sessions`. If these applications are not
in your :setting:`INSTALLED_APPS` list, add them.
3. Determine which of your application's models should be editable in the
@ -46,8 +48,8 @@ Other topics
.. seealso::
For information about serving the media files (images, JavaScript, and CSS)
associated with the admin in production, see :ref:`serving-media-files`.
For information about serving the static files (images, JavaScript, and
CSS) associated with the admin in production, see :ref:`serving-files`.
``ModelAdmin`` objects
======================
@ -531,17 +533,19 @@ subclass::
list_display = ('username', 'email', 'first_name', 'last_name', 'is_staff')
list_filter = ('is_staff', 'is_superuser')
Fields in ``list_filter`` can also span relations using the ``__`` lookup::
class UserAdminWithLookup(UserAdmin):
list_filter = ('groups__name')
The above code results in an admin change list page that looks like this:
.. image:: _images/users_changelist.png
(This example also has ``search_fields`` defined. See below.)
.. versionadded:: 1.3
Fields in ``list_filter`` can also span relations using the ``__`` lookup::
class UserAdminWithLookup(UserAdmin):
list_filter = ('groups__name',)
.. attribute:: ModelAdmin.list_per_page
Set ``list_per_page`` to control how many items appear on each paginated
@ -1041,11 +1045,10 @@ provided some extra mapping data that would not otherwise be available::
pass
def change_view(self, request, object_id, extra_context=None):
my_context = {
'osm_data': self.get_osm_info(),
}
extra_context = extra_context or {}
extra_context['osm_data'] = self.get_osm_info()
return super(MyModelAdmin, self).change_view(request, object_id,
extra_context=my_context)
extra_context=extra_context)
``ModelAdmin`` media definitions
--------------------------------
@ -1622,7 +1625,7 @@ In this example, we register the default ``AdminSite`` instance
)
Above we used ``admin.autodiscover()`` to automatically load the
``INSTALLED_APPS`` admin.py modules.
:setting:`INSTALLED_APPS` admin.py modules.
In this example, we register the ``AdminSite`` instance
``myproject.admin.admin_site`` at the URL ``/myadmin/`` ::

View File

@ -103,13 +103,16 @@ But let's look at a simple example::
<!-- A context variable called form is created with the necessary hidden
fields, timestamps and security hashes -->
<table>
<form action="{% comment_form_target %}" method="post">
{{ form }}
<tr>
<td></td>
<td><input type="submit" name="preview" class="submit-post" value="Preview"></td>
</tr>
</form>
<form action="{% comment_form_target %}" method="post">
{% csrf_token %}
{{ form }}
<tr>
<td colspan="2">
<input type="submit" name="submit" value="Post">
<input type="submit" name="preview" value="Preview">
</td>
</tr>
</form>
</table>
Flagging

View File

@ -218,13 +218,18 @@ you can use in the template::
A complete form might look like::
{% get_comment_form for event as form %}
<form action="{% comment_form_target %}" method="post">
{{ form }}
<tr>
<td></td>
<td><input type="submit" name="preview" class="submit-post" value="Preview"></td>
</tr>
</form>
<table>
<form action="{% comment_form_target %}" method="post">
{% csrf_token %}
{{ form }}
<tr>
<td colspan="2">
<input type="submit" name="submit" value="Post">
<input type="submit" name="preview" value="Preview">
</td>
</tr>
</form>
</table>
Be sure to read the `notes on the comment form`_, below, for some special
considerations you'll need to make if you're using this approach.

View File

@ -192,6 +192,15 @@ The ``ContentTypeManager``
:class:`~django.contrib.contenttypes.models.ContentType` instance
representing that model.
.. method:: get_by_natural_key(app_label, model)
Returns the :class:`~django.contrib.contenttypes.models.ContentType`
instance uniquely identified by the given application label and model
name. The primary purpose of this method is to allow
:class:`~django.contrib.contenttypes.models.ContentType` objects to be
referenced via a :ref:`natural key<topics-serialization-natural-keys>`
during deserialization.
The :meth:`~ContentTypeManager.get_for_model()` method is especially
useful when you know you need to work with a
:class:`ContentType <django.contrib.contenttypes.models.ContentType>` but don't
@ -285,6 +294,15 @@ model:
should evaluate the models you expect to be pointing to and determine
which solution will be most effective for your use case.
.. admonition:: Serializing references to ``ContentType`` objects
If you're serializing data (for example, when generating
:class:`~django.test.TestCase.fixtures`) from a model that implements
generic relations, you should probably be using a natural key to uniquely
identify related :class:`~django.contrib.contenttypes.models.ContentType`
objects. See :ref:`natural keys<topics-serialization-natural-keys>` and
:djadminopt:`dumpdata --natural <--natural>` for more information.
This will enable an API similar to the one used for a normal
:class:`~django.db.models.ForeignKey`;
each ``TaggedItem`` will have a ``content_object`` field that returns the
@ -406,7 +424,7 @@ Generic relations in forms and admin
------------------------------------
The :mod:`django.contrib.contenttypes.generic` module provides
:class:`~django.contrib.contenttypes.generic.GenericInlineFormSet`,
:class:`~django.contrib.contenttypes.generic.BaseGenericInlineFormSet`,
:class:`~django.contrib.contenttypes.generic.GenericTabularInline`
and :class:`~django.contrib.contenttypes.generic.GenericStackedInline`
(the last two are subclasses of

Some files were not shown because too many files have changed in this diff Show More