summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorRussell Keith-Magee <russell@keith-magee.com>2007-08-07 13:43:49 +0000
committerRussell Keith-Magee <russell@keith-magee.com>2007-08-07 13:43:49 +0000
commit83861364dd31063d8ff9169514c5f90a0c224482 (patch)
tree6965204a72e3293a8ae6afef1a811dcdc1dc3327 /docs
parenta704a382924eb6d2936e5ac4521acacd485984fe (diff)
Merged revisions 4350-4357,4359-4365,4371-4372,4374-4377,4380-4386,4388,4390-4391,4400-4402,4404-4408,4410,4412-4419,4426-4427,4430-4432,4434,4441,4443-4444,4446-4447,4450,4452-4453,4455-4458,4476,4503,4546,4564-4569,4580-4586,4617,4630,4641-4643,4653-4655,4657,4669,4673-4675,4694-4696,4713-4714,4720-4723,4725-4732,4735-4741,4750,4755,4758,4769-4770,4776-4777,4783-4795,4798,4805-4808,4810,4813-4815,4817,4824,4836,4838-4843,4851-4855,4869,4872,4882-4884,4906,4916,4935-4936,4940-4944,4946-4953,4962-4963,4969,4971-4973,4990,4994-4997,5000-5003,5006-5008,5013-5014,5019-5024,5026-5036,5046-5047,5054-5059,5062,5079,5081-5083,5090,5100-5101,5114,5122-5123,5126,5128,5134-5136,5148-5149,5151,5157,5174,5178,5183-5185,5192-5195,5197-5200,5203,5205,5208,5214,5223-5224,5226-5227,5229-5230,5235-5236,5238-5244,5246-5249,5251,5254-5262,5266-5280,5282-5284,5286,5301,5307,5309-5310,5312,5314-5317,5319-5332,5334-5345,5372-5378,5381-5382,5384,5386,5388-5390,5393-5397,5399-5400,5416,5419-5430,5440-5441,5444-5448,5461-5464,5467,5473-5481,5487-5489,5491-5492,5498-5499,5507-5510,5512,5527,5529,5531-5535,5540-5541,5546,5570,5572-5574,5576-5578,5580-5581,5583-5589,5591,5595-5597,5601-5608,5613,5626-5826 via svnmerge from
http://code.djangoproject.com/svn/django/trunk ........ r5626 | russellm | 2007-07-07 10:16:23 +0800 (Sat, 07 Jul 2007) | 2 lines Added some uncredited authors that worked on the Oracle branch. ........ r5629 | mtredinnick | 2007-07-08 01:15:54 +0800 (Sun, 08 Jul 2007) | 8 lines Changed HttpRequest.path to be a Unicode object. It has already been URL-decoded by the time we see it anyway, so keeping it as a UTF-8 bytestring was causing unnecessary problems. Also added handling for non-ASCII URL fragments in feed creation (the portion that was outside the control of the Feed class was messed up). ........ r5630 | mtredinnick | 2007-07-08 02:24:27 +0800 (Sun, 08 Jul 2007) | 4 lines Fixed #4772 -- Fixed reverse URL creation to work with non-ASCII arguments. Also included a test for non-ASCII strings in URL patterns, although that already worked correctly. ........ r5631 | mtredinnick | 2007-07-08 02:39:23 +0800 (Sun, 08 Jul 2007) | 3 lines Corrected misleading comment from [5619]. Not sure what I was smoking at the time. ........ r5632 | mtredinnick | 2007-07-08 08:39:32 +0800 (Sun, 08 Jul 2007) | 5 lines Fixed reverse URL lookup using functions when the original URL pattern was a string. This is now just as fragile as it was prior to [5609], but works in a few cases that people were relying on, apparently. ........ r5636 | mtredinnick | 2007-07-08 19:22:53 +0800 (Sun, 08 Jul 2007) | 4 lines Fixed #4798-- Made sure that function keyword arguments are strings (for the keywords themselves) when using Unicode URL patterns. ........ r5638 | gwilson | 2007-07-10 10:34:42 +0800 (Tue, 10 Jul 2007) | 2 lines Fixed #4817 -- Removed leading forward slashes from some urlconf examples in the documentation. ........ r5639 | gwilson | 2007-07-10 10:45:11 +0800 (Tue, 10 Jul 2007) | 2 lines Fixed #4814 -- Fixed some whitespace issues in tutorial01, thanks John Shaffer. ........ r5640 | gwilson | 2007-07-10 11:26:26 +0800 (Tue, 10 Jul 2007) | 2 lines Fixed #4812 -- Fixed an octal escape in regular expression that is used in the `isValidEmail` validator, thanks batchman@free.fr. ........ r5641 | mtredinnick | 2007-07-10 20:02:06 +0800 (Tue, 10 Jul 2007) | 3 lines Fixed #4823 -- Fixed a Python 2.3 incompatibility from [5636] (it was even demonstrated by existing tests, so I really screwed this up). ........ r5642 | mtredinnick | 2007-07-10 20:03:36 +0800 (Tue, 10 Jul 2007) | 3 lines Fixed #4804 -- Fixed a problem when validating choice lists with non-ASCII data. Thanks, django@vonposer.de. ........ r5643 | mtredinnick | 2007-07-10 20:33:55 +0800 (Tue, 10 Jul 2007) | 4 lines Fixed #3760 -- Added the ability to manually set feed- and item-level id elements in Atom feeds. This is fully backwards compatible. Based on a patch from spark343@cs.ubc.ca. ........ r5644 | mtredinnick | 2007-07-11 14:55:12 +0800 (Wed, 11 Jul 2007) | 3 lines Fixed #4815 -- Fixed decoding of request parameters when the input encoding is not UTF-8. Thanks, Jordan Dimov. ........ r5645 | mtredinnick | 2007-07-11 15:00:27 +0800 (Wed, 11 Jul 2007) | 3 lines Fixed #4802 -- Updated French translation. Combined contribution from baptiste.goupil@gmail.com and rocherl@club-internet.fr. ........ r5646 | mtredinnick | 2007-07-11 15:12:50 +0800 (Wed, 11 Jul 2007) | 2 lines Fixed #4753 -- Small update to Spanish translation from Mario Gonzalez. ........ r5649 | jacob | 2007-07-12 08:33:44 +0800 (Thu, 12 Jul 2007) | 1 line Fixed #4615: corrected reverse URL resolution examples in tutorial 4. Thanks for the patch, simeonf. ........ r5650 | adrian | 2007-07-12 12:43:29 +0800 (Thu, 12 Jul 2007) | 1 line Added 'New in Django development version' note to docs/syndication_feeds.txt changes from [5643] ........ r5651 | adrian | 2007-07-12 12:44:45 +0800 (Thu, 12 Jul 2007) | 1 line Edited changes to docs/tutorial04.txt from [5649] ........ r5652 | adrian | 2007-07-12 13:23:47 +0800 (Thu, 12 Jul 2007) | 1 line Added helpful error message to SiteManager.get_current() if the user hasn't set SITE_ID ........ r5653 | adrian | 2007-07-12 13:28:04 +0800 (Thu, 12 Jul 2007) | 1 line Added RequestSite class to sites framework ........ r5654 | adrian | 2007-07-12 13:29:32 +0800 (Thu, 12 Jul 2007) | 1 line Improved syndication feed framework to use RequestSite if the sites framework is not installed -- i.e., the sites framework is no longer required to use the syndication feed framework. This is backwards incompatible if anybody has subclassed Feed and overridden __init__(), because the second parameter is now expected to be an HttpRequest object instead of request.path ........ r5658 | russellm | 2007-07-12 15:45:35 +0800 (Thu, 12 Jul 2007) | 2 lines Fixed #4459 -- Added 'raw' argument to save method, to override any pre-save processing, and modified serializers to use a raw-save. This enables serialization of DateFields with auto_now/auto_now_add. Also modified serializers to invoke save() directly on the model baseclass, to avoid any (potentially order-dependent, data modifying) behavior in a custom save() method. ........ r5659 | russellm | 2007-07-12 19:24:16 +0800 (Thu, 12 Jul 2007) | 2 lines Fixed #3770 -- Remove null=True tag from OneToOne serialization test. OneToOne fields can't have a value of null. ........ r5660 | russellm | 2007-07-12 19:27:38 +0800 (Thu, 12 Jul 2007) | 2 lines Fixed #3768 -- Disabled NullBooleanField PK serialization test. We can't and don't test null PK values. ........ r5662 | russellm | 2007-07-12 20:33:24 +0800 (Thu, 12 Jul 2007) | 2 lines Fixed #4837 -- Updated Debian packaging details. Thanks for the suggestion, Yasushi Masuda <whosaysni@gmail.com>. ........ r5663 | russellm | 2007-07-12 20:44:05 +0800 (Thu, 12 Jul 2007) | 2 lines Fixed #4808 -- Added Chilean regions in localflavor. Thanks, Marijn Vriens <marijn@metronomo.cl>. ........ r5664 | russellm | 2007-07-12 20:48:27 +0800 (Thu, 12 Jul 2007) | 2 lines Fixed #4745 -- Updated docs to point out that 0 is not a valid SITE_ID when running the tests. Thanks for the suggestion, Lars Stavholm <stava@telcotec.se>. ........ r5665 | russellm | 2007-07-12 20:50:02 +0800 (Thu, 12 Jul 2007) | 2 lines Fixed #4763 -- Minor typo in cache documentations. Thanks, dan@coffeecode.net. ........ r5666 | russellm | 2007-07-12 20:55:28 +0800 (Thu, 12 Jul 2007) | 2 lines Fixed #4627 -- Added details on MacPorts packaging of Django. Thanks, Paul Bissex. ........ r5667 | russellm | 2007-07-12 21:23:11 +0800 (Thu, 12 Jul 2007) | 2 lines Fixed #4640 -- Fixed import to stringfilter in docs. Proposed solution to move stringfilter into django.template.__init__ introduces a circular import problem. ........ r5668 | russellm | 2007-07-12 21:32:00 +0800 (Thu, 12 Jul 2007) | 2 lines Fixed #4722 -- Clarified discussion about PYTHONPATH in modpython docs. Thanks for the suggestion, Collin Grady <cgrady@the-magi.us>. ........ r5669 | russellm | 2007-07-12 21:37:59 +0800 (Thu, 12 Jul 2007) | 2 lines Fixed #4755 -- Modified newforms MultipleChoiceField to use list comprehension, rather than iteration. ........ r5670 | russellm | 2007-07-12 21:41:27 +0800 (Thu, 12 Jul 2007) | 2 lines Fixed #4764 -- Added reference to Locale middleware in middleware docs. Thanks, dan@coffeecode.net. ........ r5671 | russellm | 2007-07-12 21:55:19 +0800 (Thu, 12 Jul 2007) | 2 lines Fixed #4768 -- Converted timesince and dateformat to use explicit floor division (pre-emptive avoidance of Python 3000 compatibility problem), and removed a redundant millisecond check. Thanks, John Shaffer <jshaffer2112@gmail.com>. ........ r5672 | russellm | 2007-07-12 22:00:13 +0800 (Thu, 12 Jul 2007) | 2 lines Fixed #4775 -- Added some missing Hungarian accents to the urlify.js LATIN_MAP. Thanks, Pistahh <szekeres@iii.hu>. ........ r5673 | russellm | 2007-07-12 22:05:16 +0800 (Thu, 12 Jul 2007) | 2 lines Fixed #4502 -- Clarified reference to view in tutorial. Thanks for the suggestion, Carl Karsten <carl@personnelware.com>. ........ r5674 | russellm | 2007-07-12 22:11:41 +0800 (Thu, 12 Jul 2007) | 2 lines Fixed #4522 -- Clarified the allowed filter arguments on the time and date filters. Thanks for the suggestion, admackin@gmail.com. ........ r5675 | russellm | 2007-07-12 22:21:51 +0800 (Thu, 12 Jul 2007) | 2 lines Fixed #4525 -- Fixed mistaken documentation on arguments to runfcgi. Thanks, Johan Bergstrom <bugs@bergstroem.nu>. ........ r5676 | russellm | 2007-07-12 22:41:32 +0800 (Thu, 12 Jul 2007) | 2 lines Fixed #4538 -- Split the installation instructions to differentiate between installing a distribution package and installing an official release. Thanks to Carl Karsten for the idea, and Paul Bissex for the patch. ........ r5677 | russellm | 2007-07-12 23:26:37 +0800 (Thu, 12 Jul 2007) | 2 lines Fixed #4526 -- Modified the test Client login method to fail when a user is inactive. Thanks, marcin@elksoft.pl. ........ r5678 | russellm | 2007-07-13 13:03:33 +0800 (Fri, 13 Jul 2007) | 2 lines Fixed #3505 -- Added handling for the error raised when the user forgets the comma in a single element tuple when defining AUTHENTICATION_BACKENDS. Thanks for the help identifying this problem, Mario Gonzalez <gonzalemario@gmail.com>. ........ r5679 | mtredinnick | 2007-07-13 16:52:07 +0800 (Fri, 13 Jul 2007) | 3 lines Fixed #2591 -- Fixed a problem with inspectdb with psycopg2 (only). Patch from Gary Wilson. ........ r5680 | mtredinnick | 2007-07-13 17:09:59 +0800 (Fri, 13 Jul 2007) | 3 lines Fixed #4807 -- Fixed a couple of corner cases in decimal form input validation. Based on a suggestion from Chriss Moffit. ........ r5681 | mtredinnick | 2007-07-13 17:14:51 +0800 (Fri, 13 Jul 2007) | 3 lines Fixed #4839 -- Added __repr__ methods to URL classes that show the pattern they contain. Thanks, Thomas G?\195?\188ttler. ........ r5682 | mtredinnick | 2007-07-13 18:56:30 +0800 (Fri, 13 Jul 2007) | 3 lines Fixed #4842 -- Added slightly more robust error reporting. Thanks, Thomas G?\195?\188ttler. ........ r5683 | mtredinnick | 2007-07-13 19:05:01 +0800 (Fri, 13 Jul 2007) | 3 lines Fixed #4846 -- Fixed some Python 2.3 encoding problems in the admin interface. Based on a patch from daybreaker12@gmail.com. ........ r5684 | mtredinnick | 2007-07-13 20:03:20 +0800 (Fri, 13 Jul 2007) | 3 lines Fixed #4861 -- Removed some duplicated logic from the newforms RegexField by making it a subclass of CharField. Thanks, Collin Grady. ........ r5685 | mtredinnick | 2007-07-13 21:15:35 +0800 (Fri, 13 Jul 2007) | 3 lines Fixed #4865 -- Replaced a stray generator comprehension with a list comprehension so that we don't break Python 2.3. ........ r5686 | mtredinnick | 2007-07-13 22:13:35 +0800 (Fri, 13 Jul 2007) | 3 lines Fixed #4469 -- Added slightly more informative error messages to max- and min-length newform validation. Based on a patch from A. Murat Eren. ........ r5687 | mtredinnick | 2007-07-13 22:14:47 +0800 (Fri, 13 Jul 2007) | 2 lines Added author credit for [5686]. Refs #4469. ........ r5688 | mtredinnick | 2007-07-13 22:33:46 +0800 (Fri, 13 Jul 2007) | 3 lines Fixed #4484 -- Fixed APPEND_SLASH handling to handle an empty path value. Thanks, VesselinK. ........ r5689 | mtredinnick | 2007-07-13 22:40:39 +0800 (Fri, 13 Jul 2007) | 2 lines Fixed #4556 -- Stylistic changes to [5500]. Thanks, glin@seznam.cz. ........ r5690 | gwilson | 2007-07-14 04:36:01 +0800 (Sat, 14 Jul 2007) | 2 lines Refs #2591 -- Removed int conversion and try/except since the value in the single-item list is already an int. I overlooked this in my original patch, which was applied in [5679]. ........ r5691 | adrian | 2007-07-14 05:20:07 +0800 (Sat, 14 Jul 2007) | 1 line Documented the 'commit' argument to save() methods on forms created via form_for_model() or form_for_instance() ........ r5692 | mtredinnick | 2007-07-14 13:27:22 +0800 (Sat, 14 Jul 2007) | 3 lines Fixed #4869 -- Added a note that syncdb does not alter existing tables. Thanks, James Bennett. ........ r5693 | mtredinnick | 2007-07-14 20:48:24 +0800 (Sat, 14 Jul 2007) | 3 lines Fixed #4863 -- Removed comment references to a no-longer present link. Pointed out by Thomas G?\195?\188ttler. ........ r5694 | mtredinnick | 2007-07-14 21:14:28 +0800 (Sat, 14 Jul 2007) | 2 lines Fixed #4862 -- Fixed invalid Javascript creation in popup windows in admin. ........ r5695 | mtredinnick | 2007-07-14 21:39:41 +0800 (Sat, 14 Jul 2007) | 2 lines Fixed a problem with translatable strings from [5686]. ........ r5696 | mtredinnick | 2007-07-14 22:47:14 +0800 (Sat, 14 Jul 2007) | 3 lines Fixed #4731 -- Changed management.setup_environ() so that it no longer assumes the settings module is called "settings". Patch from SmileyChris. ........ r5697 | mtredinnick | 2007-07-14 22:50:35 +0800 (Sat, 14 Jul 2007) | 3 lines Fixed #4870 -- Removed unneeded import and fixed a docstring in an example. Thanks, Collin Grady. ........ r5698 | adrian | 2007-07-15 00:58:54 +0800 (Sun, 15 Jul 2007) | 1 line Edited docs/db-api.txt changes from [5658] ........ r5699 | adrian | 2007-07-15 01:04:30 +0800 (Sun, 15 Jul 2007) | 1 line Negligible capitalization fix in test/client.py docstring ........ r5700 | russellm | 2007-07-15 12:41:59 +0800 (Sun, 15 Jul 2007) | 2 lines Clarified the documentation on the steps that happen during a save, and how raw save affects those steps. ........ r5701 | gwilson | 2007-07-15 13:03:28 +0800 (Sun, 15 Jul 2007) | 2 lines Fixed #4310 -- Fixed a regular expression bug in `strip_entities` function and added tests for several `django.utils.html` functions. Based on patch from Brian Harring. ........ r5702 | gwilson | 2007-07-15 13:11:06 +0800 (Sun, 15 Jul 2007) | 2 lines Fixed #4877 -- Fixed typo in testing documentation, patch from John Shaffer. ........ r5703 | gwilson | 2007-07-15 14:24:54 +0800 (Sun, 15 Jul 2007) | 2 lines Fixed #3012 -- Changed the locmem cache backend to use pickle instead of deepcopy to make it compatible with iterators (which cannot be copied). Patch from Sundance. ........ r5704 | gwilson | 2007-07-15 14:29:45 +0800 (Sun, 15 Jul 2007) | 2 lines Changed imports to adhere to PEP 8. ........ r5705 | mtredinnick | 2007-07-15 17:39:13 +0800 (Sun, 15 Jul 2007) | 3 lines Fixed #4880 -- Updated Spanish translation (includes re-encoding to UTF-8). Thanks, Jorge Gajon. ........ r5706 | mtredinnick | 2007-07-15 17:46:42 +0800 (Sun, 15 Jul 2007) | 3 lines Fixed #4882 -- Updated Argentinean Spanish translation (includes re-encoding to UTF-8). Thanks, Ramiro Morales. ........ r5707 | mtredinnick | 2007-07-15 18:08:05 +0800 (Sun, 15 Jul 2007) | 3 lines Re-encoded djangojs.po for French and German locales to UTF-8. These were the last two non-UTF-8 PO files. ........ r5708 | mtredinnick | 2007-07-15 18:10:44 +0800 (Sun, 15 Jul 2007) | 6 lines Fixed #4734 -- Changed message extraction to permit non-ACSII msgid strings. Thanks, krzysiek.pawlik@silvermedia.pl. This is slightly backwards-incompatible for translators: PO files are now assumed to be in UTF-8 encoding. ........ r5709 | adrian | 2007-07-16 03:34:21 +0800 (Mon, 16 Jul 2007) | 1 line Edited docs/db-api.txt changes from [5700] ........ r5710 | adrian | 2007-07-16 05:16:32 +0800 (Mon, 16 Jul 2007) | 1 line Improved docs/templates.txt section on the 'regroup' tag ........ r5711 | mtredinnick | 2007-07-16 11:48:03 +0800 (Mon, 16 Jul 2007) | 2 lines Updated AUTHORS for [5708]. ........ r5712 | mtredinnick | 2007-07-16 11:50:22 +0800 (Mon, 16 Jul 2007) | 3 lines Fixed #4199 -- Changed date formatting in HTTP expires header to be spec compliant. Thanks, Chris Bennett. ........ r5713 | mtredinnick | 2007-07-16 12:45:45 +0800 (Mon, 16 Jul 2007) | 3 lines Fixed #4884 -- Fixed an initialisation problem when assigned to settings before accessing them. Thanks, Noam Raphael. ........ r5714 | mtredinnick | 2007-07-16 12:47:52 +0800 (Mon, 16 Jul 2007) | 2 lines Fixed #4806 -- Updated Simplified Chinese translation. Thanks, limodou. ........ r5715 | mtredinnick | 2007-07-16 12:54:49 +0800 (Mon, 16 Jul 2007) | 3 lines Fixed #4887 -- Fixed another place where template tag arguments are used directly as function keyword args. Thanks, Brian Rosner. ........ r5716 | gwilson | 2007-07-16 13:00:18 +0800 (Mon, 16 Jul 2007) | 2 lines Refs #3012 -- Removed iterator from `test_data_types` cache test that I added in [5703]. Iterators cannot be pickled either. Left the rest of [5703] there though since it fixed another issue that was causing the `test_data_types` cache test to fail with the `locmem` cache backend, the fact that functions cannot be copied. ........ r5717 | gwilson | 2007-07-16 13:28:13 +0800 (Mon, 16 Jul 2007) | 2 lines Cleaned up a couple unused imports and fixed docstrings to follow Python Style Guide. ........ r5718 | mtredinnick | 2007-07-16 17:36:10 +0800 (Mon, 16 Jul 2007) | 3 lines Fixed #4845 -- Fixed some problems with Unicode usage and caching. Thanks, Jeremy Dunck. ........ r5719 | gwilson | 2007-07-16 21:47:43 +0800 (Mon, 16 Jul 2007) | 2 lines Removed unused variable and changed comments about `permalink` decorator into a docstring. ........ r5720 | gwilson | 2007-07-17 06:29:09 +0800 (Tue, 17 Jul 2007) | 2 lines Fixed #4851 -- Fixed description of an example query in `db-api` docs. ........ r5721 | mtredinnick | 2007-07-17 12:22:11 +0800 (Tue, 17 Jul 2007) | 2 lines Fixed #4898 -- Fixed a precendence problem when constructing HTTP Date header. ........ r5722 | mtredinnick | 2007-07-17 18:25:43 +0800 (Tue, 17 Jul 2007) | 3 lines Fixed #4899 -- Fixed a problem with PO file header generation caused by [5708]. Thanks, Ramiro Morales. ........ r5723 | mtredinnick | 2007-07-19 17:23:45 +0800 (Thu, 19 Jul 2007) | 2 lines Fixed #4917 -- Updated Swedish translation. Thanks, Pilip Lindborg. ........ r5724 | mtredinnick | 2007-07-19 17:24:36 +0800 (Thu, 19 Jul 2007) | 2 lines Fixed #3925 -- Added Slovak localflavor items. Thanks, Martin Kos?\195?\173r. ........ r5725 | adrian | 2007-07-20 14:28:56 +0800 (Fri, 20 Jul 2007) | 1 line Added a db_type() method to the database Field class. This is a hook for calculating the database column type for a given Field. Also converted all management.py CREATE TABLE statements to use db_type(), which made that code cleaner. The Field.get_internal_type() hook still exists, but we should consider removing it at some point, because db_type() is more general. Also added docs -- the beginnings of docs on how to create custom database Field classes. This is backwards-compatible. ........ r5726 | adrian | 2007-07-20 14:34:26 +0800 (Fri, 20 Jul 2007) | 1 line Simplified the indent level in management.py _get_sql_model_create() by using a 'continue' statement rather than nesting everything in an 'if' ........ r5727 | russellm | 2007-07-20 20:07:58 +0800 (Fri, 20 Jul 2007) | 2 lines Fixed #4558 -- Modified XML serializer to handle whitespace better around None tags. Thanks to Bill Fenner <fenner@gmail.com> for the report and fix. ........ r5728 | russellm | 2007-07-20 20:15:02 +0800 (Fri, 20 Jul 2007) | 2 lines Fixed #4897 -- Fixed minor typo in doctest comment. ........ r5729 | russellm | 2007-07-20 21:57:49 +0800 (Fri, 20 Jul 2007) | 2 lines Fixed #3782 -- Added support for the suite() method recommended by the Python unittest docs. Thanks for the suggestion, rene.puls@repro-mayr.de. ........ r5730 | russellm | 2007-07-20 22:07:54 +0800 (Fri, 20 Jul 2007) | 2 lines Refs #3782 -- Added documentation note that suite() handling is only in development version. ........ r5731 | russellm | 2007-07-20 22:32:20 +0800 (Fri, 20 Jul 2007) | 2 lines Fixed #4901 -- Modified assertContains to provide a default check of 'any instances of text in content'. Thanks for the suggestion, nis@superlativ.dk. ........ r5732 | russellm | 2007-07-20 22:42:57 +0800 (Fri, 20 Jul 2007) | 2 lines Fixed #4738 -- Modified the prompt that is displayed when a test database cannot be created. The existing prompt was misleading if the issue wasn't a pre-existing database. Thanks for the suggestion, John Shaffer <jshaffer2112@gmail.com>. ........ r5733 | adrian | 2007-07-20 23:40:54 +0800 (Fri, 20 Jul 2007) | 1 line Fixed negligible typo in docstring in tests/regressiontests/test_client_regress/models.py from [5731] ........ r5736 | adrian | 2007-07-21 05:24:30 +0800 (Sat, 21 Jul 2007) | 1 line Added some additional docs to docs/model-api.txt db_type() section ........ r5738 | russellm | 2007-07-21 11:30:38 +0800 (Sat, 21 Jul 2007) | 2 lines Fixed #4304 -- Modified sys.exit to os._exit to make sure development server quits when an error occurs attempting to bind to the requested port (e.g., if another server is already running). Thanks, Mario Gonzalez <gonzalemario@gmail.com>. ........ r5739 | russellm | 2007-07-21 12:36:28 +0800 (Sat, 21 Jul 2007) | 2 lines Minor fix to allow for count=0 in assertContains. ........ r5740 | russellm | 2007-07-21 13:15:19 +0800 (Sat, 21 Jul 2007) | 2 lines Added test cases for change [5739]. ........ r5741 | russellm | 2007-07-21 13:17:20 +0800 (Sat, 21 Jul 2007) | 2 lines Fixed #4402 -- Modified test client to allow multi-valued inputs on GET requests. Thanks for the suggestion, eddymul@gmail.com. ........ r5743 | gwilson | 2007-07-22 10:18:36 +0800 (Sun, 22 Jul 2007) | 2 lines Fixed #4945 -- Removed unused `GET_ITERATOR_CHUNK_SIZE` definition from manager.py. `GET_ITERATOR_CHUNK_SIZE` is already defined in query.py. Thanks zigiDev@mac.com. ........ r5744 | gwilson | 2007-07-22 11:09:24 +0800 (Sun, 22 Jul 2007) | 2 lines Added docstrings to shortcuts module and functions. ........ r5745 | gwilson | 2007-07-22 11:12:50 +0800 (Sun, 22 Jul 2007) | 2 lines Shortcut functions do not accept `QuerySet` objects, yet :) ........ r5746 | gwilson | 2007-07-22 11:41:11 +0800 (Sun, 22 Jul 2007) | 2 lines Fixed #4373 -- Modified the get_object_or_404/get_list_or_404 shortcuts to also accept `QuerySet`s. Thanks SuperJared. ........ r5747 | gwilson | 2007-07-22 11:45:03 +0800 (Sun, 22 Jul 2007) | 2 lines Corrected typo in [5746]. ........ r5750 | gwilson | 2007-07-23 12:45:01 +0800 (Mon, 23 Jul 2007) | 2 lines Fixed #4952 -- Fixed the `get_template_sources` functions of the `app_directories` and `filesystem` template loaders to not return paths outside of given template directories. Both functions now make use of a new `safe_join` utility function. Thanks to SmileyChris for help with the patch. ........ r5752 | russellm | 2007-07-23 20:14:32 +0800 (Mon, 23 Jul 2007) | 2 lines Fixed #3771 -- Modified the test runner to observe the --noinput argument controlling script interactivity. This means that test scripts can now be put in a buildbot environment. This is a backwards incompatible change for anyone that has written a custom test runner. Thanks for the suggestion, moof@metamoof.net. ........ r5753 | russellm | 2007-07-23 21:52:59 +0800 (Mon, 23 Jul 2007) | 2 lines Added documentation for a test runner argument that has always been present, but was undocumented. ........ r5756 | adrian | 2007-07-25 11:12:31 +0800 (Wed, 25 Jul 2007) | 1 line Changed docstring additions from [5744] to use active verbs ('returns' instead of 'return') ........ r5757 | adrian | 2007-07-25 11:15:05 +0800 (Wed, 25 Jul 2007) | 1 line Added 'New in Django development version' to docs/db-api.txt change from [5746] ........ r5758 | adrian | 2007-07-25 11:18:17 +0800 (Wed, 25 Jul 2007) | 1 line Changed safe_join() docstring from [5750] to use active verbs. See also [5756] ........ r5764 | gwilson | 2007-07-26 13:01:53 +0800 (Thu, 26 Jul 2007) | 2 lines Fixed #4971 -- Fixed some escaping and quoting problems in the databrowse contrib app. Based on patch from Johann Queuniet. ........ r5765 | adrian | 2007-07-27 01:16:34 +0800 (Fri, 27 Jul 2007) | 1 line Added section to docs/contributing.txt about docstring coding style ........ r5766 | mtredinnick | 2007-07-27 06:59:34 +0800 (Fri, 27 Jul 2007) | 2 lines Added support for database cache table in test database. ........ r5767 | adrian | 2007-07-28 05:53:02 +0800 (Sat, 28 Jul 2007) | 1 line Added unit test that confirms a bug in ValuesQuerySets that have extra(select) specified. If the select dictionary has several fields, Django assigns the wrong values to the select-field names ........ r5768 | adrian | 2007-07-28 06:07:42 +0800 (Sat, 28 Jul 2007) | 1 line Fixed bug with using values() and extra(select) in the same QuerySet, with a select dictionary containing more than a few elements. This bug was identified in unit test from [5767]. The problem was that we were relying on the dictionary's .items() ordering, which is undefined ........ r5769 | russellm | 2007-07-28 12:02:52 +0800 (Sat, 28 Jul 2007) | 2 lines Fixed #4460 -- Added the ability to be more specific in the test cases that are executed. This is a backwards incompatible change for any user with a custom test runner. See the wiki for details. ........ r5770 | russellm | 2007-07-28 15:27:53 +0800 (Sat, 28 Jul 2007) | 2 lines Fixed #4995 -- Fixed some problems in documentation ReST formatting. Thanks, Simon G. ........ r5771 | simon | 2007-07-29 02:30:40 +0800 (Sun, 29 Jul 2007) | 1 line After discussing with Malcolm, added set_unusable_password() and has_usable_password() methods to the User object, plus tests and updated documentation ........ r5774 | adrian | 2007-07-30 02:21:16 +0800 (Mon, 30 Jul 2007) | 1 line Added 'New in Django development version' to changes in docs/authentication.txt from [5771] ........ r5778 | gwilson | 2007-07-31 01:25:35 +0800 (Tue, 31 Jul 2007) | 4 lines Fixed call to `ugettext`, which is imported as `_`. Changed raise to conform to PEP 3109 and wrapped the long line. Added beginnings of tests for model fields. ........ r5782 | gwilson | 2007-08-01 13:41:32 +0800 (Wed, 01 Aug 2007) | 2 lines Fixed #4228 -- Removed hardcoding of `RadioFieldRenderer` in the `RadioSelect` Widget so that the display of `RadioSelect`s can be more easily customized. `BoundField.__unicode__` also no longer special cases `RadioSelect` since `RadioSelect.render()` now returns a string like every other Widget. ........ r5783 | gwilson | 2007-08-01 13:52:18 +0800 (Wed, 01 Aug 2007) | 2 lines Fixed #5037 -- Fixed use of wrong field type in a db-api docs example, thanks ubernostrum. ........ r5796 | gwilson | 2007-08-04 11:19:14 +0800 (Sat, 04 Aug 2007) | 2 lines Fixed #5078 -- Fixed several broken links to the syndication documentation. ........ r5797 | gwilson | 2007-08-04 11:36:58 +0800 (Sat, 04 Aug 2007) | 2 lines Changed the 0.95 release notes to point to the 0.95 documentation index. ........ r5798 | gwilson | 2007-08-04 11:39:24 +0800 (Sat, 04 Aug 2007) | 2 lines Changed several documentation links to be relative. ........ r5799 | gwilson | 2007-08-04 22:41:49 +0800 (Sat, 04 Aug 2007) | 2 lines Refs #3397 -- Corrected the Exception that is caught when ordering by non-fields (added in [4596]), thanks glin@seznam.cz. ........ r5800 | gwilson | 2007-08-04 22:52:13 +0800 (Sat, 04 Aug 2007) | 2 lines Fixed #5083 -- Fixed typo in newforms documentation, thanks Rik. ........ r5801 | gwilson | 2007-08-05 12:39:52 +0800 (Sun, 05 Aug 2007) | 2 lines Refs #5089 -- Added file name to poll detail template examples in the tutorial. ........ r5802 | gwilson | 2007-08-05 12:42:26 +0800 (Sun, 05 Aug 2007) | 2 lines Changed some more links to be relative in the documentation. I had a couple unsaved files that didn't get in with [5798]. ........ r5803 | gwilson | 2007-08-05 13:14:46 +0800 (Sun, 05 Aug 2007) | 2 lines Fixed #2101 -- Renamed `maxlength` argument to `max_length` for oldforms `FormField`s and db model `Field`s. This is fully backwards compatible at the moment since the legacy `maxlength` argument is still supported. Using `maxlength` will, however, issue a `PendingDeprecationWarning` when used. ........ r5804 | russellm | 2007-08-05 15:39:36 +0800 (Sun, 05 Aug 2007) | 2 lines Fixed #4001 -- Added dynamic save_m2m method() to forms created with form_for_model and form_for_instance on save(commit=False). ........ r5807 | adrian | 2007-08-06 12:36:43 +0800 (Mon, 06 Aug 2007) | 1 line Fixed #5074 -- Added link to audio clip of 'Django' pronunciation ........ r5808 | adrian | 2007-08-06 12:52:14 +0800 (Mon, 06 Aug 2007) | 1 line Edited docs/newforms.txt changes from [5804] ........ r5809 | adrian | 2007-08-06 13:04:27 +0800 (Mon, 06 Aug 2007) | 1 line Fixed #5082 -- Enabled tab completion in 'django-admin.py shell' for objects that were imported into the global namespace at runtime. Thanks, dusk@woofle.net ........ r5810 | adrian | 2007-08-06 13:06:15 +0800 (Mon, 06 Aug 2007) | 1 line Fixed #5077 -- django/utils/encoding.py no longer imports settings, as it doesn't use that module. Thanks, Collin Grady ........ r5811 | adrian | 2007-08-06 13:07:38 +0800 (Mon, 06 Aug 2007) | 1 line Fixed #5071 -- Fixed 'global name ugettext is not defined' error in django.core.validators. Thanks, Marco Bonetti ........ r5812 | adrian | 2007-08-06 13:13:06 +0800 (Mon, 06 Aug 2007) | 1 line Fixed #5064 -- Fixed potentially confusing sentence in docs/authentication.txt. Thanks, Collin Grady ........ r5813 | adrian | 2007-08-06 13:16:35 +0800 (Mon, 06 Aug 2007) | 1 line Fixed #5053 -- Added 'action' attribute to <form> tags that didn't have that attribute in docs/newforms.txt examples. Perfectionism appreciated, trickyb ........ r5814 | adrian | 2007-08-06 13:27:58 +0800 (Mon, 06 Aug 2007) | 1 line Added a closing </p>' to a code example in docs/email.txt ........ r5815 | adrian | 2007-08-06 13:28:45 +0800 (Mon, 06 Aug 2007) | 1 line Fixed #5006 -- Fixed incorrect/outdated docstring for the 'if' template tag. Thanks, Thomas Petazzoni ........ r5816 | adrian | 2007-08-06 13:33:18 +0800 (Mon, 06 Aug 2007) | 1 line Added note to docs/model-api.txt about help_text not being escaped in the admin interface ........ r5817 | adrian | 2007-08-06 13:34:45 +0800 (Mon, 06 Aug 2007) | 1 line Fixed #4985 -- Clarified location of HttpResponse in docs/request_response.txt. Thanks for raising the issue, rainer.mansfeld@romulo.de ........ r5818 | adrian | 2007-08-06 13:37:17 +0800 (Mon, 06 Aug 2007) | 1 line Fixed #4980 -- Removed 'forms' from the 'not considered stable and will be rewritten' section of docs/api_stability.txt. They've already been rewritten. ........ r5819 | russellm | 2007-08-06 21:58:56 +0800 (Mon, 06 Aug 2007) | 2 lines Fixed #3297 -- Implemented FileField and ImageField for newforms. Thanks to the many users that contributed to and tested this patch. ........ r5820 | russellm | 2007-08-06 22:17:10 +0800 (Mon, 06 Aug 2007) | 2 lines Added note that FileField and ImageField are only in development version. There are also some minor backwards compatibility issues with the changes introduced in [5819] - see the wiki for details. ........ r5823 | adrian | 2007-08-07 04:27:04 +0800 (Tue, 07 Aug 2007) | 1 line Fixed British spelling of 'customize' and 'behavior' in Manager.get_query_set() docstring ........ r5824 | adrian | 2007-08-07 10:18:36 +0800 (Tue, 07 Aug 2007) | 1 line Fixed #5105 -- Fixed two ReST errors in docs/newforms.txt. Thanks, Ramiro Morales ........ r5825 | adrian | 2007-08-07 10:33:11 +0800 (Tue, 07 Aug 2007) | 1 line Fixed #5097 -- Made various updates and corrections to the documentation. Thanks, Nicola Larosa ........ r5826 | russellm | 2007-08-07 19:20:15 +0800 (Tue, 07 Aug 2007) | 2 lines Removed a redundant directory join during FileField form saving. Thanks to David Danier's eagle eyes for picking up this one. ........ git-svn-id: http://code.djangoproject.com/svn/django/branches/newforms-admin@5828 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'docs')
-rw-r--r--docs/add_ons.txt2
-rw-r--r--docs/api_stability.txt5
-rw-r--r--docs/authentication.txt26
-rw-r--r--docs/cache.txt2
-rw-r--r--docs/contributing.txt44
-rw-r--r--docs/databases.txt2
-rw-r--r--docs/db-api.txt107
-rw-r--r--docs/distributions.txt24
-rw-r--r--docs/django-admin.txt13
-rw-r--r--docs/email.txt2
-rw-r--r--docs/faq.txt3
-rw-r--r--docs/fastcgi.txt2
-rw-r--r--docs/forms.txt10
-rw-r--r--docs/i18n.txt2
-rw-r--r--docs/install.txt28
-rw-r--r--docs/middleware.txt8
-rw-r--r--docs/model-api.txt245
-rw-r--r--docs/modpython.txt4
-rw-r--r--docs/newforms.txt158
-rw-r--r--docs/overview.txt24
-rw-r--r--docs/release_notes_0.95.txt2
-rw-r--r--docs/request_response.txt2
-rw-r--r--docs/sitemaps.txt2
-rw-r--r--docs/sites.txt28
-rw-r--r--docs/static_files.txt8
-rw-r--r--docs/syndication_feeds.txt50
-rw-r--r--docs/templates.txt101
-rw-r--r--docs/templates_python.txt4
-rw-r--r--docs/testing.txt74
-rw-r--r--docs/tutorial01.txt50
-rw-r--r--docs/tutorial02.txt8
-rw-r--r--docs/tutorial03.txt5
-rw-r--r--docs/tutorial04.txt21
-rw-r--r--docs/url_dispatch.txt8
34 files changed, 828 insertions, 246 deletions
diff --git a/docs/add_ons.txt b/docs/add_ons.txt
index ffc4f7420f..8682208970 100644
--- a/docs/add_ons.txt
+++ b/docs/add_ons.txt
@@ -214,7 +214,7 @@ A framework for generating syndication feeds, in RSS and Atom, quite easily.
See the `syndication documentation`_.
-.. _syndication documentation: ../syndication/
+.. _syndication documentation: ../syndication_feeds/
Other add-ons
=============
diff --git a/docs/api_stability.txt b/docs/api_stability.txt
index cfaffeac6b..5ccf104327 100644
--- a/docs/api_stability.txt
+++ b/docs/api_stability.txt
@@ -82,9 +82,6 @@ that 90% of Django can be considered forwards-compatible at this point.
That said, these APIs should *not* be considered stable, and are likely to
change:
- - `Forms and validation`_ will most likely be completely rewritten to
- deemphasize Manipulators in favor of validation-aware models.
-
- `Serialization`_ is under heavy development; changes are likely.
- The `authentication`_ framework is changing to be far more flexible, and
@@ -114,7 +111,7 @@ change:
.. _sending email: ../email/
.. _sessions: ../sessions/
.. _settings: ../settings/
-.. _syndication: ../syndication/
+.. _syndication: ../syndication_feeds/
.. _template language: ../templates/
.. _transactions: ../transactions/
.. _url dispatch: ../url_dispatch/
diff --git a/docs/authentication.txt b/docs/authentication.txt
index efe4d47513..589e8c9f1b 100644
--- a/docs/authentication.txt
+++ b/docs/authentication.txt
@@ -99,7 +99,7 @@ custom methods:
should prefer using ``is_authenticated()`` to this method.
* ``is_authenticated()`` -- Always returns ``True``. This is a way to
- tell if the user has been authenticated. This does not imply any
+ tell if the user has been authenticated. This does not imply any
permissions, and doesn't check if the user is active - it only indicates
that the user has provided a valid username and password.
@@ -114,6 +114,18 @@ custom methods:
string is the correct password for the user. (This takes care of the
password hashing in making the comparison.)
+ * ``set_unusable_password()`` -- **New in Django development version.**
+ Marks the user as having no password set. This isn't the same as having
+ a blank string for a password. ``check_password()`` for this user will
+ never return ``True``. Doesn't save the ``User`` object.
+
+ You may need this if authentication for your application takes place
+ against an existing external source such as an LDAP directory.
+
+ * ``has_usable_password()`` -- **New in Django development version.**
+ Returns ``False`` if ``set_unusable_password()`` has been called for this
+ user.
+
* ``get_group_permissions()`` -- Returns a list of permission strings that
the user has, through his/her groups.
@@ -126,7 +138,7 @@ custom methods:
* ``has_perms(perm_list)`` -- Returns ``True`` if the user has each of the
specified permissions, where each perm is in the format
- ``"package.codename"``. If the user is inactive, this method will
+ ``"package.codename"``. If the user is inactive, this method will
always return ``False``.
* ``has_module_perms(package_name)`` -- Returns ``True`` if the user has
@@ -152,9 +164,11 @@ Manager functions
The ``User`` model has a custom manager that has the following helper functions:
- * ``create_user(username, email, password)`` -- Creates, saves and returns
- a ``User``. The ``username``, ``email`` and ``password`` are set as
- given, and the ``User`` gets ``is_active=True``.
+ * ``create_user(username, email, password=None)`` -- Creates, saves and
+ returns a ``User``. The ``username``, ``email`` and ``password`` are set
+ as given, and the ``User`` gets ``is_active=True``.
+
+ If no password is provided, ``set_unusable_password()`` will be called.
See _`Creating users` for example usage.
@@ -220,7 +234,7 @@ the setting and checking of these values behind the scenes.
Previous Django versions, such as 0.90, used simple MD5 hashes without password
salts. For backwards compatibility, those are still supported; they'll be
-converted automatically to the new style the first time ``check_password()``
+converted automatically to the new style the first time ``User.check_password()``
works correctly for a given user.
Anonymous users
diff --git a/docs/cache.txt b/docs/cache.txt
index e245e100e7..d13352b025 100644
--- a/docs/cache.txt
+++ b/docs/cache.txt
@@ -543,7 +543,7 @@ Order of MIDDLEWARE_CLASSES
If you use ``CacheMiddleware``, it's important to put it in the right place
within the ``MIDDLEWARE_CLASSES`` setting, because the cache middleware needs
to know which headers by which to vary the cache storage. Middleware always
-adds something the ``Vary`` response header when it can.
+adds something to the ``Vary`` response header when it can.
Put the ``CacheMiddleware`` after any middlewares that might add something to
the ``Vary`` header. The following middlewares do so:
diff --git a/docs/contributing.txt b/docs/contributing.txt
index e58b06881a..61c368d32a 100644
--- a/docs/contributing.txt
+++ b/docs/contributing.txt
@@ -279,6 +279,22 @@ Please follow these coding standards when writing code for inclusion in Django:
* Mark all strings for internationalization; see the `i18n documentation`_
for details.
+ * In docstrings, use "action words," like so::
+
+ def foo():
+ """
+ Calculates something and returns the result.
+ """
+ pass
+
+ Here's an example of what not to do::
+
+ def foo():
+ """
+ Calculate something and return the result.
+ """
+ pass
+
* Please don't put your name in the code you contribute. Our policy is to
keep contributors' names in the ``AUTHORS`` file distributed with Django
-- not scattered throughout the codebase itself. Feel free to include a
@@ -324,14 +340,14 @@ Model style
Do this::
class Person(models.Model):
- first_name = models.CharField(maxlength=20)
- last_name = models.CharField(maxlength=40)
+ first_name = models.CharField(max_length=20)
+ last_name = models.CharField(max_length=40)
Don't do this::
class Person(models.Model):
- FirstName = models.CharField(maxlength=20)
- Last_Name = models.CharField(maxlength=40)
+ FirstName = models.CharField(max_length=20)
+ Last_Name = models.CharField(max_length=40)
* The ``class Meta`` should appear *after* the fields are defined, with
a single blank line separating the fields and the class definition.
@@ -339,8 +355,8 @@ Model style
Do this::
class Person(models.Model):
- first_name = models.CharField(maxlength=20)
- last_name = models.CharField(maxlength=40)
+ first_name = models.CharField(max_length=20)
+ last_name = models.CharField(max_length=40)
class Meta:
verbose_name_plural = 'people'
@@ -348,8 +364,8 @@ Model style
Don't do this::
class Person(models.Model):
- first_name = models.CharField(maxlength=20)
- last_name = models.CharField(maxlength=40)
+ first_name = models.CharField(max_length=20)
+ last_name = models.CharField(max_length=40)
class Meta:
verbose_name_plural = 'people'
@@ -359,8 +375,8 @@ Model style
class Meta:
verbose_name_plural = 'people'
- first_name = models.CharField(maxlength=20)
- last_name = models.CharField(maxlength=40)
+ first_name = models.CharField(max_length=20)
+ last_name = models.CharField(max_length=40)
* The order of model inner classes and standard methods should be as
follows (noting that these are not all required):
@@ -529,11 +545,9 @@ To run the tests, ``cd`` to the ``tests/`` directory and type::
./runtests.py --settings=path.to.django.settings
Yes, the unit tests need a settings module, but only for database connection
-info -- the ``DATABASE_NAME`` (required, but will be ignored),
-``DATABASE_ENGINE``, ``DATABASE_USER`` and ``DATABASE_PASSWORD`` settings. You
-will also need a ``ROOT_URLCONF`` setting (its value is ignored; it just needs
-to be present) and a ``SITE_ID`` setting (any integer value will do) in order
-for all the tests to pass.
+info, with the ``DATABASE_ENGINE`` setting. You will also need a ``ROOT_URLCONF``
+setting (its value is ignored; it just needs to be present) and a ``SITE_ID``
+setting (any non-zero integer value will do) in order for all the tests to pass.
The unit tests will not touch your existing databases; they create a new
database, called ``django_test_db``, which is deleted when the tests are
diff --git a/docs/databases.txt b/docs/databases.txt
index b73f39843c..ed0cb61bc3 100644
--- a/docs/databases.txt
+++ b/docs/databases.txt
@@ -124,7 +124,7 @@ Several other MySQLdb connection options may be useful, such as ``ssl``,
``use_unicode``, ``init_command``, and ``sql_mode``. Consult the
`MySQLdb documentation`_ for more details.
-.. _settings documentation: http://www.djangoproject.com/documentation/settings/#database-engine
+.. _settings documentation: ../settings/#database-engine
.. _MySQL option file: http://dev.mysql.com/doc/refman/5.0/en/option-files.html
.. _MySQLdb documentation: http://mysql-python.sourceforge.net/
diff --git a/docs/db-api.txt b/docs/db-api.txt
index ef3d811189..766a6ae519 100644
--- a/docs/db-api.txt
+++ b/docs/db-api.txt
@@ -12,22 +12,22 @@ Throughout this reference, we'll refer to the following models, which comprise
a weblog application::
class Blog(models.Model):
- name = models.CharField(maxlength=100)
+ name = models.CharField(max_length=100)
tagline = models.TextField()
def __unicode__(self):
return self.name
class Author(models.Model):
- name = models.CharField(maxlength=50)
- email = models.URLField()
+ name = models.CharField(max_length=50)
+ email = models.EmailField()
def __unicode__(self):
return self.name
class Entry(models.Model):
blog = models.ForeignKey(Blog)
- headline = models.CharField(maxlength=255)
+ headline = models.CharField(max_length=255)
body_text = models.TextField()
pub_date = models.DateTimeField()
authors = models.ManyToManyField(Author)
@@ -118,6 +118,79 @@ happens.
Explicitly specifying auto-primary-key values is mostly useful for bulk-saving
objects, when you're confident you won't have primary-key collision.
+What happens when you save?
+---------------------------
+
+When you save an object, Django performs the following steps:
+
+ 1. **Emit a ``pre_save`` signal.** This provides a notification that
+ an object is about to be saved. You can register a listener that
+ will be invoked whenever this signal is emitted. (These signals are
+ not yet documented.)
+
+ 2. **Pre-process the data.** Each field on the object is asked to
+ perform any automated data modification that the field may need
+ to perform.
+
+ Most fields do *no* pre-processing -- the field data is kept as-is.
+ Pre-processing is only used on fields that have special behavior.
+ For example, if your model has a ``DateField`` with ``auto_now=True``,
+ the pre-save phase will alter the data in the object to ensure that
+ the date field contains the current date stamp. (Our documentation
+ doesn't yet include a list of all the fields with this "special
+ behavior.")
+
+ 3. **Prepare the data for the database.** Each field is asked to provide
+ its current value in a data type that can be written to the database.
+
+ Most fields require *no* data preparation. Simple data types, such as
+ integers and strings, are 'ready to write' as a Python object. However,
+ more complex data types often require some modification.
+
+ For example, ``DateFields`` use a Python ``datetime`` object to store
+ data. Databases don't store ``datetime`` objects, so the field value
+ must be converted into an ISO-compliant date string for insertion
+ into the database.
+
+ 4. **Insert the data into the database.** The pre-processed, prepared
+ data is then composed into an SQL statement for insertion into the
+ database.
+
+ 5. **Emit a ``post_save`` signal.** As with the ``pre_save`` signal, this
+ is used to provide notification that an object has been successfully
+ saved. (These signals are not yet documented.)
+
+Raw Saves
+~~~~~~~~~
+
+**New in Django development version**
+
+The pre-processing step (#2 in the previous section) is useful, but it modifies
+the data stored in a field. This can cause problems if you're relying upon the
+data you provide being used as-is.
+
+For example, if you're setting up conditions for a test, you'll want the test
+conditions to be repeatable. If pre-processing is performed, the data used
+to specify test conditions may be modified, changing the conditions for the
+test each time the test is run.
+
+In cases such as this, you need to prevent pre-processing from being performed
+when you save an object. To do this, you can invoke a **raw save** by passing
+``raw=True`` as an argument to the ``save()`` method::
+
+ b4.save(raw=True) # Save object, but do no pre-processing
+
+A raw save skips the usual data pre-processing that is performed during the
+save. All other steps in the save (pre-save signal, data preparation, data
+insertion, and post-save signal) are performed as normal.
+
+.. admonition:: When to use a raw save
+
+ Generally speaking, you shouldn't need to use a raw save. Disabling field
+ pre-processing is an extraordinary measure that should only be required
+ in extraordinary circumstances, such as setting up reliable test
+ conditions.
+
Saving changes to objects
=========================
@@ -140,7 +213,7 @@ object of the right type to the field in question::
joe = Author.objects.create(name="Joe")
entry.author = joe
entry.save()
-
+
Django will complain if you try to assign an object of the wrong type.
How Django knows to UPDATE vs. INSERT
@@ -336,7 +409,7 @@ For example, this returns the first 5 objects (``LIMIT 5``)::
Entry.objects.all()[:5]
-This returns the fifth through tenth objects (``OFFSET 5 LIMIT 5``)::
+This returns the sixth through tenth objects (``OFFSET 5 LIMIT 5``)::
Entry.objects.all()[5:10]
@@ -1430,7 +1503,7 @@ precede the definition of any keyword arguments. For example::
See the `OR lookups examples page`_ for more examples.
-.. _OR lookups examples page: http://www.djangoproject.com/documentation/models/or_lookups/
+.. _OR lookups examples page: ../models/or_lookups/
Related objects
===============
@@ -1733,8 +1806,8 @@ following model::
('F', 'Female'),
)
class Person(models.Model):
- name = models.CharField(maxlength=20)
- gender = models.CharField(maxlength=1, choices=GENDER_CHOICES)
+ name = models.CharField(max_length=20)
+ gender = models.CharField(max_length=1, choices=GENDER_CHOICES)
...each ``Person`` instance will have a ``get_gender_display()`` method. Example::
@@ -1761,7 +1834,7 @@ Note that in the case of identical date values, these methods will use the ID
as a fallback check. This guarantees that no records are skipped or duplicated.
For a full example, see the `lookup API sample model`_.
-.. _lookup API sample model: http://www.djangoproject.com/documentation/models/lookup/
+.. _lookup API sample model: ../models/lookup/
get_FOO_filename()
------------------
@@ -1818,8 +1891,8 @@ get_object_or_404()
One common idiom to use ``get()`` and raise ``Http404`` if the
object doesn't exist. This idiom is captured by ``get_object_or_404()``.
This function takes a Django model as its first argument and an
-arbitrary number of keyword arguments, which it passes to the manager's
-``get()`` function. It raises ``Http404`` if the object doesn't
+arbitrary number of keyword arguments, which it passes to the default
+manager's ``get()`` function. It raises ``Http404`` if the object doesn't
exist. For example::
# Get the Entry with a primary key of 3
@@ -1828,7 +1901,7 @@ exist. For example::
When you provide a model to this shortcut function, the default manager
is used to execute the underlying ``get()`` query. If you don't want to
use the default manager, or if you want to search a list of related objects,
-you can provide ``get_object_or_404()`` with a manager object instead.
+you can provide ``get_object_or_404()`` with a ``Manager`` object instead.
For example::
# Get the author of blog instance e with a name of 'Fred'
@@ -1838,6 +1911,14 @@ For example::
# entry with a primary key of 3
e = get_object_or_404(Entry.recent_entries, pk=3)
+**New in Django development version:** The first argument to
+``get_object_or_404()`` can be a ``QuerySet`` object. This is useful in cases
+where you've defined a custom manager method. For example::
+
+ # Use a QuerySet returned from a 'published' method of a custom manager
+ # in the search for an entry with primary key of 5
+ e = get_object_or_404(Entry.objects.published(), pk=5)
+
get_list_or_404()
-----------------
diff --git a/docs/distributions.txt b/docs/distributions.txt
index 4ec265f93c..f9b9cbe9f8 100644
--- a/docs/distributions.txt
+++ b/docs/distributions.txt
@@ -21,16 +21,17 @@ Linux distributions
Debian
------
-A `packaged version of Django`_ is available for `Debian GNU/Linux`_, and can be
-installed from either the "testing" or the "unstable" repositories by typing
-``apt-get install python-django``.
+A `packaged version of Django`_ is available for `Debian GNU/Linux`_. Version
+0.95.1 is available in the "stable" repository; Version 0.96 is available in
+the "testing" and "unstable" repositories. Regardless of your chosen repository,
+you can install Django by typing ``apt-get install python-django``.
When you install this package, ``apt`` will recommend installing a database
adapter; you should select and install the adapter for whichever database you
plan to use with Django.
.. _Debian GNU/Linux: http://www.debian.org/
-.. _packaged version of Django: http://packages.debian.org/testing/python/python-django
+.. _packaged version of Django: http://packages.debian.org/stable/python/python-django
Ubuntu
------
@@ -64,11 +65,24 @@ The `current Gentoo build`_ can be installed by typing ``emerge django``.
.. _Gentoo Linux: http://www.gentoo.org/
.. _current Gentoo build: http://packages.gentoo.org/packages/?category=dev-python;name=django
+Mac OS X
+========
+
+MacPorts
+--------
+
+Django 0.96 can be installed via the `MacPorts`_ system. If you're using Python 2.4,
+type ``sudo port install py-django-devel``. For Python 2.5, type ``sudo port
+install py25-django-devel``. MacPorts can also be used to install a database,
+and the Python interface to your chosen database.
+
+.. _MacPorts: http://www.macports.org/
+
For distributors
================
If you'd like to package Django for distribution, we'd be happy to help out!
-Please join the `django-developers mailing list`_ and introduce yourself.
+Please join the `django-developers mailing list`_ and introduce yourself.
We also encourage all distributors to subscribe to the `django-announce mailing
list`_, which is a (very) low-traffic list for announcing new releases of Django
diff --git a/docs/django-admin.txt b/docs/django-admin.txt
index 75c2738543..ad17907b5e 100644
--- a/docs/django-admin.txt
+++ b/docs/django-admin.txt
@@ -400,6 +400,19 @@ install them in the database. This includes any apps shipped with Django that
might be in ``INSTALLED_APPS`` by default. When you start a new project, run
this command to install the default apps.
+.. admonition:: Syncdb will not alter existing tables
+
+ ``syncdb`` will only create tables for models which have not yet been
+ installed. It will *never* issue ``ALTER TABLE`` statements to match
+ changes made to a model class after installation. Changes to model classes
+ and database schemas often involve some form of ambiguity and, in those
+ cases, Django would have to guess at the correct changes to make. There is
+ a risk that critical data would be lost in the process.
+
+ If you have made changes to a model and wish to alter the database tables
+ to match, use the ``sql`` command to display the new SQL structure and
+ compare that to your existing table schema to work out the changes.
+
If you're installing the ``django.contrib.auth`` application, ``syncdb`` will
give you the option of creating a superuser immediately.
diff --git a/docs/email.txt b/docs/email.txt
index 50dafaf8df..97bdec0037 100644
--- a/docs/email.txt
+++ b/docs/email.txt
@@ -314,7 +314,7 @@ To send a text and HTML combination, you could write::
subject, from_email, to = 'hello', 'from@example.com', 'to@example.com'
text_content = 'This is an important message.'
- html_content = '<p>This is an <strong>important</strong> message.'
+ html_content = '<p>This is an <strong>important</strong> message.</p>'
msg = EmailMultiAlternatives(subject, text_content, from_email, to)
msg.attach_alternative(html_content, "text/html")
msg.send()
diff --git a/docs/faq.txt b/docs/faq.txt
index 67ed8a49a5..844ea77809 100644
--- a/docs/faq.txt
+++ b/docs/faq.txt
@@ -42,7 +42,10 @@ Listen to his music. You'll like it.
Django is pronounced **JANG**-oh. Rhymes with FANG-oh. The "D" is silent.
+We've also recorded an `audio clip of the pronunciation`_.
+
.. _Django Reinhardt: http://en.wikipedia.org/wiki/Django_Reinhardt
+.. _audio clip of the pronunciation: http://red-bean.com/~adrian/django_pronunciation.mp3
Is Django stable?
-----------------
diff --git a/docs/fastcgi.txt b/docs/fastcgi.txt
index 81888bba76..dff1689905 100644
--- a/docs/fastcgi.txt
+++ b/docs/fastcgi.txt
@@ -93,7 +93,7 @@ protocol by using the ``protocol=<protocol_name>`` option with
``./manage.py runfcgi`` -- where ``<protocol_name>`` may be one of: ``fcgi``
(the default), ``scgi`` or ``ajp``. For example::
- ./manage.py runfcgi --protocol=scgi
+ ./manage.py runfcgi protocol=scgi
.. _flup: http://www.saddi.com/software/flup/
.. _fastcgi: http://www.fastcgi.com/
diff --git a/docs/forms.txt b/docs/forms.txt
index 18d3d3fcbe..18d322a8eb 100644
--- a/docs/forms.txt
+++ b/docs/forms.txt
@@ -37,11 +37,11 @@ this document, we'll be working with the following model, a "place" object::
)
class Place(models.Model):
- name = models.CharField(maxlength=100)
- address = models.CharField(maxlength=100, blank=True)
- city = models.CharField(maxlength=50, blank=True)
+ name = models.CharField(max_length=100)
+ address = models.CharField(max_length=100, blank=True)
+ city = models.CharField(max_length=50, blank=True)
state = models.USStateField()
- zip_code = models.CharField(maxlength=5, blank=True)
+ zip_code = models.CharField(max_length=5, blank=True)
place_type = models.IntegerField(choices=PLACE_TYPES)
class Admin:
@@ -388,7 +388,7 @@ for a "contact" form on a website::
def __init__(self):
self.fields = (
forms.EmailField(field_name="from", is_required=True),
- forms.TextField(field_name="subject", length=30, maxlength=200, is_required=True),
+ forms.TextField(field_name="subject", length=30, max_length=200, is_required=True),
forms.SelectField(field_name="urgency", choices=urgency_choices),
forms.LargeTextField(field_name="contents", is_required=True),
)
diff --git a/docs/i18n.txt b/docs/i18n.txt
index 9fe02c0342..38252edeb1 100644
--- a/docs/i18n.txt
+++ b/docs/i18n.txt
@@ -263,7 +263,7 @@ To pluralize, specify both the singular and plural forms with the
Internally, all block and inline translations use the appropriate
``ugettext`` / ``ungettext`` call.
-Each ``RequestContext`` has access to two translation-specific variables:
+Each ``RequestContext`` has access to three translation-specific variables:
* ``LANGUAGES`` is a list of tuples in which the first element is the
language code and the second is the language name (in that language).
diff --git a/docs/install.txt b/docs/install.txt
index e850e48955..1b2919f1bc 100644
--- a/docs/install.txt
+++ b/docs/install.txt
@@ -109,25 +109,29 @@ Install the Django code
=======================
Installation instructions are slightly different depending on whether you're
-using the latest official version or the latest development version.
+installing a distribution-specific package, downloading the the latest official
+release, or fetching the latest development version.
-It's easy either way.
+It's easy, no matter which way you choose.
-Installing the official version
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Installing a distribution-specific package
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- 1. Check the `distribution specific notes`_ to see if your
- platform/distribution provides official Django packages/installers.
- Distribution-provided packages will typically allow for automatic
- installation of dependancies and easy upgrade paths.
+Check the `distribution specific notes`_ to see if your
+platform/distribution provides official Django packages/installers.
+Distribution-provided packages will typically allow for automatic
+installation of dependancies and easy upgrade paths.
- 2. Download the latest release from our `download page`_.
+Installing an official release
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- 3. Untar the downloaded file (e.g. ``tar xzvf Django-NNN.tar.gz``).
+ 1. Download the latest release from our `download page`_.
- 4. Change into the downloaded directory (e.g. ``cd Django-NNN``).
+ 2. Untar the downloaded file (e.g. ``tar xzvf Django-NNN.tar.gz``).
- 5. Run ``sudo python setup.py install``.
+ 3. Change into the downloaded directory (e.g. ``cd Django-NNN``).
+
+ 4. Run ``sudo python setup.py install``.
The command will install Django in your Python installation's ``site-packages``
directory.
diff --git a/docs/middleware.txt b/docs/middleware.txt
index 0d533443d3..533f1ccede 100644
--- a/docs/middleware.txt
+++ b/docs/middleware.txt
@@ -116,6 +116,14 @@ not use this middleware. Anybody can spoof the value of
``HTTP_X_FORWARDED_FOR``, that means anybody can "fake" their IP address. Only
use this when you can absolutely trust the value of ``HTTP_X_FORWARDED_FOR``.
+django.middleware.locale.LocaleMiddleware
+-----------------------------------------
+
+Enables language selection based on data from the request. It customizes content
+for each user. See the `internationalization documentation`_.
+
+.. _`internationalization documentation`: ../i18n/
+
django.contrib.sessions.middleware.SessionMiddleware
----------------------------------------------------
diff --git a/docs/model-api.txt b/docs/model-api.txt
index 4b0bc0d238..ddeb481206 100644
--- a/docs/model-api.txt
+++ b/docs/model-api.txt
@@ -22,7 +22,7 @@ A companion to this document is the `official repository of model examples`_.
``tests/modeltests`` directory.)
.. _Database API reference: ../db-api/
-.. _official repository of model examples: http://www.djangoproject.com/documentation/models/
+.. _official repository of model examples: ../models/
Quick example
=============
@@ -33,8 +33,8 @@ This example model defines a ``Person``, which has a ``first_name`` and
from django.db import models
class Person(models.Model):
- first_name = models.CharField(maxlength=30)
- last_name = models.CharField(maxlength=30)
+ first_name = models.CharField(max_length=30)
+ last_name = models.CharField(max_length=30)
``first_name`` and ``last_name`` are *fields* of the model. Each field is
specified as a class attribute, and each attribute maps to a database column.
@@ -69,13 +69,13 @@ attributes.
Example::
class Musician(models.Model):
- first_name = models.CharField(maxlength=50)
- last_name = models.CharField(maxlength=50)
- instrument = models.CharField(maxlength=100)
+ first_name = models.CharField(max_length=50)
+ last_name = models.CharField(max_length=50)
+ instrument = models.CharField(max_length=100)
class Album(models.Model):
artist = models.ForeignKey(Musician)
- name = models.CharField(maxlength=100)
+ name = models.CharField(max_length=100)
release_date = models.DateField()
num_stars = models.IntegerField()
@@ -142,14 +142,18 @@ For large amounts of text, use ``TextField``.
The admin represents this as an ``<input type="text">`` (a single-line input).
-``CharField`` has an extra required argument, ``maxlength``, the maximum length
-(in characters) of the field. The maxlength is enforced at the database level
+``CharField`` has an extra required argument, ``max_length``, the maximum length
+(in characters) of the field. The max_length is enforced at the database level
and in Django's validation.
+Django veterans: Note that the argument is now called ``max_length`` to
+provide consistency throughout Django. There is full legacy support for
+the old ``maxlength`` argument, but ``max_length`` is prefered.
+
``CommaSeparatedIntegerField``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-A field of integers separated by commas. As in ``CharField``, the ``maxlength``
+A field of integers separated by commas. As in ``CharField``, the ``max_length``
argument is required.
``DateField``
@@ -217,7 +221,7 @@ The admin represents this as an ``<input type="text">`` (a single-line input).
~~~~~~~~~~~~~~
A ``CharField`` that checks that the value is a valid e-mail address.
-This doesn't accept ``maxlength``; its ``maxlength`` is automatically set to
+This doesn't accept ``max_length``; its ``max_length`` is automatically set to
75.
``FileField``
@@ -400,7 +404,7 @@ Like a ``PositiveIntegerField``, but only allows values under a certain
containing only letters, numbers, underscores or hyphens. They're generally
used in URLs.
-Like a CharField, you can specify ``maxlength``. If ``maxlength`` is
+Like a CharField, you can specify ``max_length``. If ``max_length`` is
not specified, Django will use a default length of 50.
Implies ``db_index=True``.
@@ -447,9 +451,9 @@ and doesn't give a 404 response).
The admin represents this as an ``<input type="text">`` (a single-line input).
-``URLField`` takes an optional argument, ``maxlength``, the maximum length (in
-characters) of the field. The maxlength is enforced at the database level and
-in Django's validation. If you don't specify ``maxlength``, a default of 200
+``URLField`` takes an optional argument, ``max_length``, the maximum length (in
+characters) of the field. The maximum length is enforced at the database level and
+in Django's validation. If you don't specify ``max_length``, a default of 200
is used.
``USStateField``
@@ -536,7 +540,7 @@ The choices list can be defined either as part of your model class::
('M', 'Male'),
('F', 'Female'),
)
- gender = models.CharField(maxlength=1, choices=GENDER_CHOICES)
+ gender = models.CharField(max_length=1, choices=GENDER_CHOICES)
or outside your model class altogether::
@@ -545,7 +549,7 @@ or outside your model class altogether::
('F', 'Female'),
)
class Foo(models.Model):
- gender = models.CharField(maxlength=1, choices=GENDER_CHOICES)
+ gender = models.CharField(max_length=1, choices=GENDER_CHOICES)
For each model field that has ``choices`` set, Django will add a method to
retrieve the human-readable name for the field's current value. See
@@ -620,6 +624,12 @@ Extra "help" text to be displayed under the field on the object's admin
form. It's useful for documentation even if your object doesn't have an
admin form.
+Note that this value is *not* HTML-escaped when it's displayed in the admin
+interface. This lets you include HTML in ``help_text`` if you so desire. For
+example::
+
+ help_text="Please use the following format: <em>YYYY-MM-DD</em>."
+
``primary_key``
~~~~~~~~~~~~~~~
@@ -698,11 +708,11 @@ it using the field's attribute name, converting underscores to spaces.
In this example, the verbose name is ``"Person's first name"``::
- first_name = models.CharField("Person's first name", maxlength=30)
+ first_name = models.CharField("Person's first name", max_length=30)
In this example, the verbose name is ``"first name"``::
- first_name = models.CharField(maxlength=30)
+ first_name = models.CharField(max_length=30)
``ForeignKey``, ``ManyToManyField`` and ``OneToOneField`` require the first
argument to be a model class, so use the ``verbose_name`` keyword argument::
@@ -727,7 +737,7 @@ Many-to-one relationships
To define a many-to-one relationship, use ``ForeignKey``. You use it just like
any other ``Field`` type: by including it as a class attribute of your model.
-``ForeignKey`` requires a positional argument: The class to which the model is
+``ForeignKey`` requires a positional argument: the class to which the model is
related.
For example, if a ``Car`` model has a ``Manufacturer`` -- that is, a
@@ -775,7 +785,7 @@ You can, of course, call the field whatever you want. For example::
See the `Many-to-one relationship model example`_ for a full example.
-.. _Many-to-one relationship model example: http://www.djangoproject.com/documentation/models/many_to_one/
+.. _Many-to-one relationship model example: ../models/many_to_one/
``ForeignKey`` fields take a number of extra arguments for defining how the
relationship should work. All are optional:
@@ -862,7 +872,7 @@ To define a many-to-many relationship, use ``ManyToManyField``. You use it just
like any other ``Field`` type: by including it as a class attribute of your
model.
-``ManyToManyField`` requires a positional argument: The class to which the
+``ManyToManyField`` requires a positional argument: the class to which the
model is related.
For example, if a ``Pizza`` has multiple ``Topping`` objects -- that is, a
@@ -902,7 +912,7 @@ set up above, the ``Pizza`` admin form would let users select the toppings.
See the `Many-to-many relationship model example`_ for a full example.
-.. _Many-to-many relationship model example: http://www.djangoproject.com/documentation/models/many_to_many/
+.. _Many-to-many relationship model example: ../models/many_to_many/
``ManyToManyField`` objects take a number of extra arguments for defining how
the relationship should work. All are optional:
@@ -959,7 +969,7 @@ model.
This is most useful on the primary key of an object when that object "extends"
another object in some way.
-``OneToOneField`` requires a positional argument: The class to which the
+``OneToOneField`` requires a positional argument: the class to which the
model is related.
For example, if you're building a database of "places", you would build pretty
@@ -979,7 +989,116 @@ as a read-only field when you edit an object in the admin interface:
See the `One-to-one relationship model example`_ for a full example.
-.. _One-to-one relationship model example: http://www.djangoproject.com/documentation/models/one_to_one/
+.. _One-to-one relationship model example: ../models/one_to_one/
+
+Custom field types
+------------------
+
+**New in Django development version**
+
+Django's built-in field types don't cover every possible database column type --
+only the common types, such as ``VARCHAR`` and ``INTEGER``. For more obscure
+column types, such as geographic polygons or even user-created types such as
+`PostgreSQL custom types`_, you can define your own Django ``Field`` subclasses.
+
+.. _PostgreSQL custom types: http://www.postgresql.org/docs/8.2/interactive/sql-createtype.html
+
+.. admonition:: Experimental territory
+
+ This is an area of Django that traditionally has not been documented, but
+ we're starting to include bits of documentation, one feature at a time.
+ Please forgive the sparseness of this section.
+
+ If you like living on the edge and are comfortable with the risk of
+ unstable, undocumented APIs, see the code for the core ``Field`` class
+ in ``django/db/models/fields/__init__.py`` -- but if/when the innards
+ change, don't say we didn't warn you.
+
+To create a custom field type, simply subclass ``django.db.models.Field``.
+Here is an incomplete list of the methods you should implement:
+
+``db_type()``
+~~~~~~~~~~~~~
+
+Returns the database column data type for the ``Field``, taking into account
+the current ``DATABASE_ENGINE`` setting.
+
+Say you've created a PostgreSQL custom type called ``mytype``. You can use this
+field with Django by subclassing ``Field`` and implementing the ``db_type()``
+method, like so::
+
+ from django.db import models
+
+ class MytypeField(models.Field):
+ def db_type(self):
+ return 'mytype'
+
+Once you have ``MytypeField``, you can use it in any model, just like any other
+``Field`` type::
+
+ class Person(models.Model):
+ name = models.CharField(max_length=80)
+ gender = models.CharField(max_length=1)
+ something_else = MytypeField()
+
+If you aim to build a database-agnostic application, you should account for
+differences in database column types. For example, the date/time column type
+in PostgreSQL is called ``timestamp``, while the same column in MySQL is called
+``datetime``. The simplest way to handle this in a ``db_type()`` method is to
+import the Django settings module and check the ``DATABASE_ENGINE`` setting.
+For example::
+
+ class MyDateField(models.Field):
+ def db_type(self):
+ from django.conf import settings
+ if settings.DATABASE_ENGINE == 'mysql':
+ return 'datetime'
+ else:
+ return 'timestamp'
+
+The ``db_type()`` method is only called by Django when the framework constructs
+the ``CREATE TABLE`` statements for your application -- that is, when you first
+create your tables. It's not called at any other time, so it can afford to
+execute slightly complex code, such as the ``DATABASE_ENGINE`` check in the
+above example.
+
+Some database column types accept parameters, such as ``CHAR(25)``, where the
+parameter ``25`` represents the maximum column length. In cases like these,
+it's more flexible if the parameter is specified in the model rather than being
+hard-coded in the ``db_type()`` method. For example, it wouldn't make much
+sense to have a ``CharMaxlength25Field``, shown here::
+
+ # This is a silly example of hard-coded parameters.
+ class CharMaxlength25Field(models.Field):
+ def db_type(self):
+ return 'char(25)'
+
+ # In the model:
+ class MyModel(models.Model):
+ # ...
+ my_field = CharMaxlength25Field()
+
+The better way of doing this would be to make the parameter specifiable at run
+time -- i.e., when the class is instantiated. To do that, just implement
+``__init__()``, like so::
+
+ # This is a much more flexible example.
+ class BetterCharField(models.Field):
+ def __init__(self, max_length, *args, **kwargs):
+ self.max_length = max_length
+ super(BetterCharField, self).__init__(*args, **kwargs)
+
+ def db_type(self):
+ return 'char(%s)' % self.max_length
+
+ # In the model:
+ class MyModel(models.Model):
+ # ...
+ my_field = BetterCharField(25)
+
+Note that if you implement ``__init__()`` on a ``Field`` subclass, it's
+important to call ``Field.__init__()`` -- i.e., the parent class'
+``__init__()`` method.
Meta options
============
@@ -987,7 +1106,7 @@ Meta options
Give your model metadata by using an inner ``class Meta``, like so::
class Foo(models.Model):
- bar = models.CharField(maxlength=30)
+ bar = models.CharField(max_length=30)
class Meta:
# ...
@@ -1077,7 +1196,7 @@ See `Specifying ordering`_ for more examples.
Note that, regardless of how many fields are in ``ordering``, the admin
site uses only the first field.
-.. _Specifying ordering: http://www.djangoproject.com/documentation/models/ordering/
+.. _Specifying ordering: ../models/ordering/
``permissions``
---------------
@@ -1161,8 +1280,8 @@ If you want your model to be visible to Django's admin site, give your model an
inner ``"class Admin"``, like so::
class Person(models.Model):
- first_name = models.CharField(maxlength=30)
- last_name = models.CharField(maxlength=30)
+ first_name = models.CharField(max_length=30)
+ last_name = models.CharField(max_length=30)
class Admin:
# Admin options go here
@@ -1302,8 +1421,8 @@ that displays the ``__str__()`` representation of each object.
A few special cases to note about ``list_display``:
- * If the field is a ``ForeignKey``, Django will display the ``__str__()``
- of the related object.
+ * If the field is a ``ForeignKey``, Django will display the
+ ``__unicode__()`` of the related object.
* ``ManyToManyField`` fields aren't supported, because that would entail
executing a separate SQL statement for each row in the table. If you
@@ -1321,7 +1440,7 @@ A few special cases to note about ``list_display``:
Here's a full example model::
class Person(models.Model):
- name = models.CharField(maxlength=50)
+ name = models.CharField(max_length=50)
birthday = models.DateField()
class Admin:
@@ -1338,9 +1457,9 @@ A few special cases to note about ``list_display``:
Here's a full example model::
class Person(models.Model):
- first_name = models.CharField(maxlength=50)
- last_name = models.CharField(maxlength=50)
- color_code = models.CharField(maxlength=6)
+ first_name = models.CharField(max_length=50)
+ last_name = models.CharField(max_length=50)
+ color_code = models.CharField(max_length=6)
class Admin:
list_display = ('first_name', 'last_name', 'colored_name')
@@ -1356,7 +1475,7 @@ A few special cases to note about ``list_display``:
Here's a full example model::
class Person(models.Model):
- first_name = models.CharField(maxlength=50)
+ first_name = models.CharField(max_length=50)
birthday = models.DateField()
class Admin:
@@ -1384,8 +1503,8 @@ A few special cases to note about ``list_display``:
For example::
class Person(models.Model):
- first_name = models.CharField(maxlength=50)
- color_code = models.CharField(maxlength=6)
+ first_name = models.CharField(max_length=50)
+ color_code = models.CharField(max_length=6)
class Admin:
list_display = ('first_name', 'colored_first_name')
@@ -1553,7 +1672,7 @@ with an operator:
AND (first_name ILIKE 'lennon' OR last_name ILIKE 'lennon')
Note that the query input is split by spaces, so, following this example,
- it's not currently not possible to search for all records in which
+ it's currently not possible to search for all records in which
``first_name`` is exactly ``'john winston'`` (containing a space).
``@``
@@ -1635,13 +1754,13 @@ returns a list of all ``OpinionPoll`` objects, each with an extra
return result_list
class OpinionPoll(models.Model):
- question = models.CharField(maxlength=200)
+ question = models.CharField(max_length=200)
poll_date = models.DateField()
objects = PollManager()
class Response(models.Model):
poll = models.ForeignKey(Poll)
- person_name = models.CharField(maxlength=50)
+ person_name = models.CharField(max_length=50)
response = models.TextField()
With this example, you'd use ``OpinionPoll.objects.with_counts()`` to return
@@ -1657,8 +1776,8 @@ A ``Manager``'s base ``QuerySet`` returns all objects in the system. For
example, using this model::
class Book(models.Model):
- title = models.CharField(maxlength=100)
- author = models.CharField(maxlength=50)
+ title = models.CharField(max_length=100)
+ author = models.CharField(max_length=50)
...the statement ``Book.objects.all()`` will return all books in the database.
@@ -1676,8 +1795,8 @@ all objects, and one that returns only the books by Roald Dahl::
# Then hook it into the Book model explicitly.
class Book(models.Model):
- title = models.CharField(maxlength=100)
- author = models.CharField(maxlength=50)
+ title = models.CharField(max_length=100)
+ author = models.CharField(max_length=50)
objects = models.Manager() # The default manager.
dahl_objects = DahlBookManager() # The Dahl-specific manager.
@@ -1710,9 +1829,9 @@ For example::
return super(FemaleManager, self).get_query_set().filter(sex='F')
class Person(models.Model):
- first_name = models.CharField(maxlength=50)
- last_name = models.CharField(maxlength=50)
- sex = models.CharField(maxlength=1, choices=(('M', 'Male'), ('F', 'Female')))
+ first_name = models.CharField(max_length=50)
+ last_name = models.CharField(max_length=50)
+ sex = models.CharField(max_length=1, choices=(('M', 'Male'), ('F', 'Female')))
people = models.Manager()
men = MaleManager()
women = FemaleManager()
@@ -1742,11 +1861,11 @@ model.
For example, this model has a few custom methods::
class Person(models.Model):
- first_name = models.CharField(maxlength=50)
- last_name = models.CharField(maxlength=50)
+ first_name = models.CharField(max_length=50)
+ last_name = models.CharField(max_length=50)
birth_date = models.DateField()
- address = models.CharField(maxlength=100)
- city = models.CharField(maxlength=50)
+ address = models.CharField(max_length=100)
+ city = models.CharField(max_length=50)
state = models.USStateField() # Yes, this is America-centric...
def baby_boomer_status(self):
@@ -1788,8 +1907,8 @@ Although this isn't required, it's strongly encouraged (see the description of
For example::
class Person(models.Model):
- first_name = models.CharField(maxlength=50)
- last_name = models.CharField(maxlength=50)
+ first_name = models.CharField(max_length=50)
+ last_name = models.CharField(max_length=50)
def __str__(self):
# Note use of django.utils.encoding.smart_str() here because
@@ -1806,8 +1925,8 @@ method for your model. The example in the previous section could be written
more simply as::
class Person(models.Model):
- first_name = models.CharField(maxlength=50)
- last_name = models.CharField(maxlength=50)
+ first_name = models.CharField(max_length=50)
+ last_name = models.CharField(max_length=50)
def __unicode__(self):
return u'%s %s' % (self.first_name, self.last_name)
@@ -1833,10 +1952,12 @@ Django uses this in its admin interface. If an object defines
link that will jump you directly to the object's public view, according to
``get_absolute_url()``.
-Also, a couple of other bits of Django, such as the syndication-feed framework,
+Also, a couple of other bits of Django, such as the `syndication feed framework`_,
use ``get_absolute_url()`` as a convenience to reward people who've defined the
method.
+.. _syndication feed framework: ../syndication_feeds/
+
It's good practice to use ``get_absolute_url()`` in templates, instead of
hard-coding your objects' URLs. For example, this template code is bad::
@@ -1871,7 +1992,7 @@ works out the correct full URL path using the URLconf, substituting the
parameters you have given into the URL. For example, if your URLconf
contained a line such as::
- (r'^/people/(\d+)/$', 'people.views.details'),
+ (r'^people/(\d+)/$', 'people.views.details'),
...your model could have a ``get_absolute_url`` method that looked like this::
@@ -1894,8 +2015,8 @@ Similarly, if you had a URLconf entry that looked like::
'day': self.created.day})
get_absolute_url = permalink(get_absolute_url)
-Notice that we specify an empty sequence for the second argument in this case,
-because we only want to pass keyword arguments, not named arguments.
+Notice that we specify an empty sequence for the second parameter in this case,
+because we only want to pass keyword parameters, not positional ones.
In this way, you're tying the model's absolute URL to the view that is used
to display it, without repeating the URL information anywhere. You can still
@@ -1947,7 +2068,7 @@ A classic use-case for overriding the built-in methods is if you want something
to happen whenever you save an object. For example::
class Blog(models.Model):
- name = models.CharField(maxlength=100)
+ name = models.CharField(max_length=100)
tagline = models.TextField()
def save(self):
@@ -1958,7 +2079,7 @@ to happen whenever you save an object. For example::
You can also prevent saving::
class Blog(models.Model):
- name = models.CharField(maxlength=100)
+ name = models.CharField(max_length=100)
tagline = models.TextField()
def save(self):
diff --git a/docs/modpython.txt b/docs/modpython.txt
index 388a6168f3..676aab19ac 100644
--- a/docs/modpython.txt
+++ b/docs/modpython.txt
@@ -50,8 +50,8 @@ directive. The latter is used for pointing at places on your filesystem,
whereas ``<Location>`` points at places in the URL structure of a Web site.
``<Directory>`` would be meaningless here.
-Also, if you've manually altered your ``PYTHONPATH`` to put your Django project
-on it, you'll need to tell mod_python:
+Also, if your Django project is not on the default ``PYTHONPATH`` for your
+computer, you'll have to tell mod_python where your project can be found:
.. parsed-literal::
diff --git a/docs/newforms.txt b/docs/newforms.txt
index c2e08c63b9..acc28604df 100644
--- a/docs/newforms.txt
+++ b/docs/newforms.txt
@@ -641,7 +641,7 @@ the "Outputting forms as HTML" section above.
The simplest way to display a form's HTML is to use the variable on its own,
like this::
- <form method="post">
+ <form method="post" action="">
<table>{{ form }}</table>
<input type="submit" />
</form>
@@ -653,7 +653,7 @@ class' ``__str__()`` method calls its ``as_table()`` method.
The following is equivalent but a bit more explicit::
- <form method="post">
+ <form method="post" action="">
<table>{{ form.as_table }}</table>
<input type="submit" />
</form>
@@ -675,7 +675,7 @@ individual fields for complete template control over the form's design.
The easiest way is to iterate over the form's fields, with
``{% for field in form %}``. For example::
- <form method="post">
+ <form method="post" action="">
<dl>
{% for field in form %}
<dt>{{ field.label }}</dt>
@@ -696,7 +696,7 @@ Alternatively, you can arrange the form's fields explicitly, by name. Do that
by accessing ``{{ form.fieldname }}``, where ``fieldname`` is the field's name.
For example::
- <form method="post">
+ <form method="post" action="">
<ul class="myformclass">
<li>{{ form.sender.label }} {{ form.sender }}</li>
<li class="helptext">{{ form.sender.help_text }}</li>
@@ -710,6 +710,49 @@ For example::
</ul>
</form>
+Binding uploaded files to a form
+--------------------------------
+
+**New in Django development version**
+
+Dealing with forms that have ``FileField`` and ``ImageField`` fields
+is a little more complicated than a normal form.
+
+Firstly, in order to upload files, you'll need to make sure that your
+``<form>`` element correctly defines the ``enctype`` as
+``"multipart/form-data"``::
+
+ <form enctype="multipart/form-data" method="post" action="/foo/">
+
+Secondly, when you use the form, you need to bind the file data. File
+data is handled separately to normal form data, so when your form
+contains a ``FileField`` and ``ImageField``, you will need to specify
+a second argument when you bind your form. So if we extend our
+ContactForm to include an ``ImageField`` called ``mugshot``, we
+need to bind the file data containing the mugshot image::
+
+ # Bound form with an image field
+ >>> data = {'subject': 'hello',
+ ... 'message': 'Hi there',
+ ... 'sender': 'foo@example.com',
+ ... 'cc_myself': True}
+ >>> file_data = {'mugshot': {'filename':'face.jpg'
+ ... 'content': <file data>}}
+ >>> f = ContactFormWithMugshot(data, file_data)
+
+In practice, you will usually specify ``request.FILES`` as the source
+of file data (just like you use ``request.POST`` as the source of
+form data)::
+
+ # Bound form with an image field, data from the request
+ >>> f = ContactFormWithMugshot(request.POST, request.FILES)
+
+Constructing an unbound form is the same as always -- just omit both
+form data *and* file data::
+
+ # Unbound form with a image field
+ >>> f = ContactFormWithMugshot()
+
Subclassing forms
-----------------
@@ -1099,6 +1142,54 @@ Has two optional arguments for validation, ``max_length`` and ``min_length``.
If provided, these arguments ensure that the string is at most or at least the
given length.
+``FileField``
+~~~~~~~~~~~~~
+
+**New in Django development version**
+
+ * Default widget: ``FileInput``
+ * Empty value: ``None``
+ * Normalizes to: An ``UploadedFile`` object that wraps the file content
+ and file name into a single object.
+ * Validates that non-empty file data has been bound to the form.
+
+An ``UploadedFile`` object has two attributes:
+
+ ====================== =====================================================
+ Argument Description
+ ====================== =====================================================
+ ``filename`` The name of the file, provided by the uploading
+ client.
+ ``content`` The array of bytes comprising the file content.
+ ====================== =====================================================
+
+The string representation of an ``UploadedFile`` is the same as the filename
+attribute.
+
+When you use a ``FileField`` on a form, you must also remember to
+`bind the file data to the form`_.
+
+.. _`bind the file data to the form`: `Binding uploaded files to a form`_
+
+``ImageField``
+~~~~~~~~~~~~~~
+
+**New in Django development version**
+
+ * Default widget: ``FileInput``
+ * Empty value: ``None``
+ * Normalizes to: An ``UploadedFile`` object that wraps the file content
+ and file name into a single object.
+ * Validates that file data has been bound to the form, and that the
+ file is of an image format understood by PIL.
+
+Using an ImageField requires that the `Python Imaging Library`_ is installed.
+
+When you use a ``FileField`` on a form, you must also remember to
+`bind the file data to the form`_.
+
+.. _Python Imaging Library: http://www.pythonware.com/products/pil/
+
``IntegerField``
~~~~~~~~~~~~~~~~
@@ -1222,7 +1313,7 @@ Custom form and field validation
Form validation happens when the data is cleaned. If you want to customise
this process, there are various places you can change, each one serving a
-different purpose. Thee types of cleaning methods are run during form
+different purpose. Three types of cleaning methods are run during form
processing. These are normally executed when you call the ``is_valid()``
method on a form. There are other things that can trigger cleaning and
validation (accessing the ``errors`` attribute or calling ``full_clean()``
@@ -1372,17 +1463,17 @@ the full list of conversions:
``AutoField`` Not represented in the form
``BooleanField`` ``BooleanField``
``CharField`` ``CharField`` with ``max_length`` set to
- the model field's ``maxlength``
+ the model field's ``max_length``
``CommaSeparatedIntegerField`` ``CharField``
``DateField`` ``DateField``
``DateTimeField`` ``DateTimeField``
``DecimalField`` ``DecimalField``
``EmailField`` ``EmailField``
- ``FileField`` ``CharField``
+ ``FileField`` ``FileField``
``FilePathField`` ``CharField``
``FloatField`` ``FloatField``
``ForeignKey`` ``ModelChoiceField`` (see below)
- ``ImageField`` ``CharField``
+ ``ImageField`` ``ImageField``
``IntegerField`` ``IntegerField``
``IPAddressField`` ``CharField``
``ManyToManyField`` ``ModelMultipleChoiceField`` (see
@@ -1452,15 +1543,15 @@ Consider this set of models::
)
class Author(models.Model):
- name = models.CharField(maxlength=100)
- title = models.CharField(maxlength=3, choices=TITLE_CHOICES)
+ name = models.CharField(max_length=100)
+ title = models.CharField(max_length=3, choices=TITLE_CHOICES)
birth_date = models.DateField(blank=True, null=True)
def __unicode__(self):
return self.name
class Book(models.Model):
- name = models.CharField(maxlength=100)
+ name = models.CharField(max_length=100)
authors = models.ManyToManyField(Author)
With these models, a call to ``form_for_model(Author)`` would return a ``Form``
@@ -1495,6 +1586,51 @@ example::
Note that ``save()`` will raise a ``ValueError`` if the data in the form
doesn't validate -- i.e., ``if form.errors``.
+This ``save()`` method accepts an optional ``commit`` keyword argument, which
+accepts either ``True`` or ``False``. If you call ``save()`` with
+``commit=False``, then it will return an object that hasn't yet been saved to
+the database. In this case, it's up to you to call ``save()`` on the resulting
+model instance. This is useful if you want to do custom processing on the
+object before saving it. ``commit`` is ``True`` by default.
+
+Another side effect of using ``commit=False`` is seen when your model has
+a many-to-many relation with another model. If your model has a many-to-many
+relation and you specify ``commit=False`` when you save a form, Django cannot
+immediately save the form data for the many-to-many relation. This is because
+it isn't possible to save many-to-many data for an instance until the instance
+exists in the database.
+
+To work around this problem, every time you save a form using ``commit=False``,
+Django adds a ``save_m2m()`` method to the form created by ``form_for_model``.
+After you've manually saved the instance produced by the form, you can invoke
+``save_m2m()`` to save the many-to-many form data. For example::
+
+ # Create a form instance with POST data.
+ >>> f = AuthorForm(request.POST)
+
+ # Create, but don't save the new author instance.
+ >>> new_author = f.save(commit=False)
+
+ # Modify the author in some way.
+ >>> new_author.some_field = 'some_value'
+
+ # Save the new instance.
+ >>> new_author.save()
+
+ # Now, save the many-to-many data for the form.
+ >>> f.save_m2m()
+
+Calling ``save_m2m()`` is only required if you use ``save(commit=False)``.
+When you use a simple ``save()`` on a form, all data -- including
+many-to-many data -- is saved without the need for any additional method calls.
+For example::
+
+ # Create a form instance with POST data.
+ >>> f = AuthorForm(request.POST)
+
+ # Create and save the new author instance. There's no need to do anything else.
+ >>> new_author = f.save()
+
Using an alternate base class
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/docs/overview.txt b/docs/overview.txt
index 041ad152c7..0fd1be5c85 100644
--- a/docs/overview.txt
+++ b/docs/overview.txt
@@ -25,14 +25,14 @@ far, it's been solving two years' worth of database-schema problems. Here's a
quick example::
class Reporter(models.Model):
- full_name = models.CharField(maxlength=70)
+ full_name = models.CharField(max_length=70)
def __unicode__(self):
return self.full_name
class Article(models.Model):
pub_date = models.DateTimeField()
- headline = models.CharField(maxlength=200)
+ headline = models.CharField(max_length=200)
article = models.TextField()
reporter = models.ForeignKey(Reporter)
@@ -54,7 +54,7 @@ Enjoy the free API
==================
With that, you've got a free, and rich, Python API to access your data. The API
-is created on the fly: No code generation necessary::
+is created on the fly, no code generation necessary::
>>> from mysite.models import Reporter, Article
@@ -124,7 +124,7 @@ is created on the fly: No code generation necessary::
# Delete an object with delete().
>>> r.delete()
-A dynamic admin interface: It's not just scaffolding -- it's the whole house
+A dynamic admin interface: it's not just scaffolding -- it's the whole house
============================================================================
Once your models are defined, Django can automatically create a professional,
@@ -134,7 +134,7 @@ your model classes::
class Article(models.Model):
pub_date = models.DateTimeField()
- headline = models.CharField(maxlength=200)
+ headline = models.CharField(max_length=200)
article = models.TextField()
reporter = models.ForeignKey(Reporter)
class Admin: pass
@@ -165,9 +165,9 @@ example above::
from django.conf.urls.defaults import *
urlpatterns = patterns('',
- (r'^/articles/(\d{4})/$', 'mysite.views.year_archive'),
- (r'^/articles/(\d{4})/(\d{2})/$', 'mysite.views.month_archive'),
- (r'^/articles/(\d{4})/(\d{2})/(\d+)/$', 'mysite.views.article_detail'),
+ (r'^articles/(\d{4})/$', 'mysite.views.year_archive'),
+ (r'^articles/(\d{4})/(\d{2})/$', 'mysite.views.month_archive'),
+ (r'^articles/(\d{4})/(\d{2})/(\d+)/$', 'mysite.views.article_detail'),
)
The code above maps URLs, as simple regular expressions, to the location of
@@ -250,7 +250,7 @@ Finally, Django uses the concept of "template inheritance": That's what the
``{% extends "base.html" %}`` does. It means "First load the template called
'base', which has defined a bunch of blocks, and fill the blocks with the
following blocks." In short, that lets you dramatically cut down on redundancy
-in templates: Each template has to define only what's unique to that template.
+in templates: each template has to define only what's unique to that template.
Here's what the "base.html" template might look like::
@@ -288,14 +288,16 @@ This has been only a quick overview of Django's functionality. Some more useful
features:
* A caching framework that integrates with memcached or other backends.
- * A syndication framework that makes creating RSS and Atom feeds as easy as
+ * A `syndication framework`_ that makes creating RSS and Atom feeds as easy as
writing a small Python class.
* More sexy automatically-generated admin features -- this overview barely
scratched the surface.
+.. _syndication framework: ../syndication_feeds/
+
The next obvious steps are for you to `download Django`_, read `the tutorial`_
and join `the community`_. Thanks for your interest!
.. _download Django: http://www.djangoproject.com/download/
-.. _the tutorial: http://www.djangoproject.com/documentation/tutorial01/
+.. _the tutorial: ../tutorial01/
.. _the community: http://www.djangoproject.com/community/
diff --git a/docs/release_notes_0.95.txt b/docs/release_notes_0.95.txt
index 3709cacf5a..f2ecbb66e6 100644
--- a/docs/release_notes_0.95.txt
+++ b/docs/release_notes_0.95.txt
@@ -114,7 +114,7 @@ there's a #django channel on irc.freenode.net that is regularly populated by
Django users and developers from around the world. Friendly people are usually
available at any hour of the day -- to help, or just to chat.
-.. _online: http://www.djangoproject.com/documentation/
+.. _online: http://www.djangoproject.com/documentation/0.95/
.. _Django website: http://www.djangoproject.com/
.. _FAQ: http://www.djangoproject.com/documentation/faq/
.. _django-users: http://groups.google.com/group/django-users
diff --git a/docs/request_response.txt b/docs/request_response.txt
index 0b985d563b..a17a60ff17 100644
--- a/docs/request_response.txt
+++ b/docs/request_response.txt
@@ -297,7 +297,7 @@ In contrast to ``HttpRequest`` objects, which are created automatically by
Django, ``HttpResponse`` objects are your responsibility. Each view you write
is responsible for instantiating, populating and returning an ``HttpResponse``.
-The ``HttpResponse`` class lives at ``django.http.HttpResponse``.
+The ``HttpResponse`` class lives in the ``django.http`` module.
Usage
-----
diff --git a/docs/sitemaps.txt b/docs/sitemaps.txt
index 550f448de1..1d4fba2626 100644
--- a/docs/sitemaps.txt
+++ b/docs/sitemaps.txt
@@ -21,7 +21,7 @@ you express this information in Python code.
It works much like Django's `syndication framework`_. To create a sitemap, just
write a ``Sitemap`` class and point to it in your URLconf_.
-.. _syndication framework: ../syndication/
+.. _syndication framework: ../syndication_feeds/
.. _URLconf: ../url_dispatch/
Installation
diff --git a/docs/sites.txt b/docs/sites.txt
index 12259b04c3..90a9d0f90f 100644
--- a/docs/sites.txt
+++ b/docs/sites.txt
@@ -46,7 +46,7 @@ that's represented by a ``ManyToManyField`` in the ``Article`` model::
from django.contrib.sites.models import Site
class Article(models.Model):
- headline = models.CharField(maxlength=200)
+ headline = models.CharField(max_length=200)
# ...
sites = models.ManyToManyField(Site)
@@ -87,7 +87,7 @@ like this::
from django.contrib.sites.models import Site
class Article(models.Model):
- headline = models.CharField(maxlength=200)
+ headline = models.CharField(max_length=200)
# ...
site = models.ForeignKey(Site)
@@ -229,7 +229,7 @@ Use ``CurrentSiteManager`` by adding it to your model explicitly. For example::
class Photo(models.Model):
photo = models.FileField(upload_to='/home/photos')
- photographer_name = models.CharField(maxlength=100)
+ photographer_name = models.CharField(max_length=100)
pub_date = models.DateField()
site = models.ForeignKey(Site)
objects = models.Manager()
@@ -257,7 +257,7 @@ this::
class Photo(models.Model):
photo = models.FileField(upload_to='/home/photos')
- photographer_name = models.CharField(maxlength=100)
+ photographer_name = models.CharField(max_length=100)
pub_date = models.DateField()
publish_on = models.ForeignKey(Site)
objects = models.Manager()
@@ -318,5 +318,23 @@ Here's how Django uses the sites framework:
.. _redirects framework: ../redirects/
.. _flatpages framework: ../flatpages/
-.. _syndication framework: ../syndication/
+.. _syndication framework: ../syndication_feeds/
.. _authentication framework: ../authentication/
+
+``RequestSite`` objects
+=======================
+
+**New in Django development version**
+
+Some ``django.contrib`` applications take advantage of the sites framework but
+are architected in a way that doesn't *require* the sites framework to be
+installed in your database. (Some people don't want to, or just aren't *able*
+to install the extra database table that the sites framework requires.) For
+those cases, the framework provides a ``RequestSite`` class, which can be used
+as a fallback when the database-backed sites framework is not available.
+
+A ``RequestSite`` object has a similar interface to a normal ``Site`` object,
+except its ``__init__()`` method takes an ``HttpRequest`` object. It's able to
+deduce the ``domain`` and ``name`` by looking at the request's domain. It has
+``save()`` and ``delete()`` methods to match the interface of ``Site``, but
+the methods raise ``NotImplementedError``.
diff --git a/docs/static_files.txt b/docs/static_files.txt
index b6a1d278fd..846c3eb56b 100644
--- a/docs/static_files.txt
+++ b/docs/static_files.txt
@@ -103,10 +103,10 @@ Do this by wrapping an ``if DEBUG`` statement around the
from django.conf import settings
urlpatterns = patterns('',
- (r'^/articles/2003/$', 'news.views.special_case_2003'),
- (r'^/articles/(?P<year>\d{4})/$', 'news.views.year_archive'),
- (r'^/articles/(?P<year>\d{4})/(?P<month>\d{2})/$', 'news.views.month_archive'),
- (r'^/articles/(?P<year>\d{4})/(?P<month>\d{2})/(?P<day>\d+)/$', 'news.views.article_detail'),
+ (r'^articles/2003/$', 'news.views.special_case_2003'),
+ (r'^articles/(?P<year>\d{4})/$', 'news.views.year_archive'),
+ (r'^articles/(?P<year>\d{4})/(?P<month>\d{2})/$', 'news.views.month_archive'),
+ (r'^articles/(?P<year>\d{4})/(?P<month>\d{2})/(?P<day>\d+)/$', 'news.views.article_detail'),
)
if settings.DEBUG:
diff --git a/docs/syndication_feeds.txt b/docs/syndication_feeds.txt
index 2a03e6d5a6..393572f3e2 100644
--- a/docs/syndication_feeds.txt
+++ b/docs/syndication_feeds.txt
@@ -31,6 +31,12 @@ To create a feed, just write a ``Feed`` class and point to it in your URLconf_.
Initialization
--------------
+If you're not using the latest Django development version, you'll need to make
+sure Django's sites framework is installed -- including its database table.
+(See the `sites framework documentation`_ for more information.) This has
+changed in the Django development version; the syndication feed framework no
+longer requires the sites framework.
+
To activate syndication feeds on your Django site, add this line to your
URLconf_::
@@ -72,6 +78,7 @@ The above example registers two feeds:
Once that's set up, you just need to define the ``Feed`` classes themselves.
+.. _sites framework documentation: ../sites/
.. _URLconf: ../url_dispatch/
.. _settings file: ../settings/
@@ -131,9 +138,14 @@ put into those elements.
* ``{{ obj }}`` -- The current object (one of whichever objects you
returned in ``items()``).
- * ``{{ site }}`` -- A ``django.models.core.sites.Site`` object
+ * ``{{ site }}`` -- A ``django.contrib.sites.models.Site`` object
representing the current site. This is useful for
- ``{{ site.domain }}`` or ``{{ site.name }}``.
+ ``{{ site.domain }}`` or ``{{ site.name }}``. Note that if you're
+ using the latest Django development version and do *not* have the
+ Django sites framework installed, this will be set to a
+ ``django.contrib.sites.models.RequestSite`` object. See the
+ `RequestSite section of the sites framework documentation`_ for
+ more.
If you don't create a template for either the title or description, the
framework will use the template ``"{{ obj }}"`` by default -- that is,
@@ -164,6 +176,7 @@ put into those elements.
.. _chicagocrime.org: http://www.chicagocrime.org/
.. _object-relational mapper: ../db-api/
.. _Django templates: ../templates/
+.. _RequestSite section of the sites framework documentation: ../sites/#requestsite-objects
A complex example
-----------------
@@ -416,6 +429,26 @@ This example illustrates all possible attributes and methods for a ``Feed`` clas
link = '/foo/bar/' # Hard-coded link.
+ # GUID -- One of the following three is optional. The framework looks
+ # for them in this order. This property is only used for Atom feeds
+ # (where it is the feed-level ID element). If not provided, the feed
+ # link is used as the ID.
+ #
+ # (New in Django development version)
+
+ def feed_guid(self, obj):
+ """
+ Takes the object returned by get_object() and returns the globally
+ unique ID for the feed as a normal Python string.
+ """
+
+ def feed_guid(self):
+ """
+ Returns the feed's globally unique ID as a normal Python string.
+ """
+
+ feed_guid = '/foo/bar/1234' # Hard-coded guid.
+
# DESCRIPTION -- One of the following three is required. The framework
# looks for them in this order.
@@ -556,7 +589,18 @@ This example illustrates all possible attributes and methods for a ``Feed`` clas
Returns the URL for every item in the feed.
"""
- # ITEM AUTHOR NAME --One of the following three is optional. The
+ # ITEM_GUID -- The following method is optional. This property is
+ # only used for Atom feeds (it is the ID element for an item in an
+ # Atom feed). If not provided, the item's link is used by default.
+ #
+ # (New in Django development version)
+
+ def item_guid(self, obj):
+ """
+ Takes an item, as return by items(), and returns the item's ID.
+ """
+
+ # ITEM AUTHOR NAME -- One of the following three is optional. The
# framework looks for them in this order.
def item_author_name(self, item):
diff --git a/docs/templates.txt b/docs/templates.txt
index f5ed1fe74b..0d53c281d1 100644
--- a/docs/templates.txt
+++ b/docs/templates.txt
@@ -741,8 +741,19 @@ regroup
Regroup a list of alike objects by a common attribute.
This complex tag is best illustrated by use of an example: say that ``people``
-is a list of ``Person`` objects that have ``first_name``, ``last_name``, and
-``gender`` attributes, and you'd like to display a list that looks like:
+is a list of people represented by dictionaries with ``first_name``,
+``last_name``, and ``gender`` keys::
+
+ people = [
+ {'first_name': 'George', 'last_name': 'Bush', 'gender': 'Male'},
+ {'first_name': 'Bill', 'last_name': 'Clinton', 'gender': 'Male'},
+ {'first_name': 'Margaret', 'last_name': 'Thatcher', 'gender': 'Female'},
+ {'first_name': 'Condoleezza', 'last_name': 'Rice', 'gender': 'Female'},
+ {'first_name': 'Pat', 'last_name': 'Smith', 'gender': 'Unknown'},
+ ]
+
+...and you'd like to display a hierarchical list that is ordered by gender,
+like this:
* Male:
* George Bush
@@ -753,33 +764,72 @@ is a list of ``Person`` objects that have ``first_name``, ``last_name``, and
* Unknown:
* Pat Smith
-The following snippet of template code would accomplish this dubious task::
+You can use the ``{% regroup %}`` tag to group the list of people by gender.
+The following snippet of template code would accomplish this::
+
+ {% regroup people by gender as gender_list %}
- {% regroup people by gender as grouped %}
<ul>
- {% for group in grouped %}
- <li>{{ group.grouper }}
+ {% for gender in gender_list %}
+ <li>{{ gender.grouper }}
<ul>
- {% for item in group.list %}
- <li>{{ item }}</li>
+ {% for item in gender.list %}
+ <li>{{ item.first_name }} {{ item.last_name }}</li>
{% endfor %}
</ul>
</li>
{% endfor %}
</ul>
-As you can see, ``{% regroup %}`` populates a variable with a list of objects
-with ``grouper`` and ``list`` attributes. ``grouper`` contains the item that
-was grouped by; ``list`` contains the list of objects that share that
-``grouper``. In this case, ``grouper`` would be ``Male``, ``Female`` and
-``Unknown``, and ``list`` is the list of people with those genders.
+Let's walk through this example. ``{% regroup %}`` takes three arguments: the
+list you want to regroup, the attribute to group by, and the name of the
+resulting list. Here, we're regrouping the ``people`` list by the ``gender``
+attribute and calling the result ``gender_list``.
+
+``{% regroup %}`` produces a list (in this case, ``gender_list``) of
+**group objects**. Each group object has two attributes:
+
+ * ``grouper`` -- the item that was grouped by (e.g., the string "Male" or
+ "Female").
+ * ``list`` -- a list of all items in this group (e.g., a list of all people
+ with gender='Male').
+
+Note that ``{% regroup %}`` does not order its input! Our example relies on
+the fact that the ``people`` list was ordered by ``gender`` in the first place.
+If the ``people`` list did *not* order its members by ``gender``, the regrouping
+would naively display more than one group for a single gender. For example,
+say the ``people`` list was set to this (note that the males are not grouped
+together)::
+
+ people = [
+ {'first_name': 'Bill', 'last_name': 'Clinton', 'gender': 'Male'},
+ {'first_name': 'Pat', 'last_name': 'Smith', 'gender': 'Unknown'},
+ {'first_name': 'Margaret', 'last_name': 'Thatcher', 'gender': 'Female'},
+ {'first_name': 'George', 'last_name': 'Bush', 'gender': 'Male'},
+ {'first_name': 'Condoleezza', 'last_name': 'Rice', 'gender': 'Female'},
+ ]
+
+With this input for ``people``, the example ``{% regroup %}`` template code
+above would result in the following output:
+
+ * Male:
+ * Bill Clinton
+ * Unknown:
+ * Pat Smith
+ * Female:
+ * Margaret Thatcher
+ * Male:
+ * George Bush
+ * Female:
+ * Condoleezza Rice
+
+The easiest solution to this gotcha is to make sure in your view code that the
+data is ordered according to how you want to display it.
-Note that ``{% regroup %}`` does not work when the list to be grouped is not
-sorted by the key you are grouping by! This means that if your list of people
-was not sorted by gender, you'd need to make sure it is sorted before using it,
-i.e.::
+Another solution is to sort the data in the template using the ``dictsort``
+filter, if your data is in a list of dictionaries::
- {% regroup people|dictsort:"gender" by gender as grouped %}
+ {% regroup people|dictsort:"gender" by gender as gender_list %}
spaceless
~~~~~~~~~
@@ -950,7 +1000,7 @@ Removes all values of arg from the given string.
date
~~~~
-Formats a date according to the given format (same as the ``now`` tag).
+Formats a date according to the given format (same as the `now`_ tag).
default
~~~~~~~
@@ -965,14 +1015,14 @@ If value is ``None``, use given default.
dictsort
~~~~~~~~
-Takes a list of dicts, returns that list sorted by the property given in the
-argument.
+Takes a list of dictionaries, returns that list sorted by the key given in
+the argument.
dictsortreversed
~~~~~~~~~~~~~~~~
-Takes a list of dicts, returns that list sorted in reverse order by the
-property given in the argument.
+Takes a list of dictionaries, returns that list sorted in reverse order by the
+key given in the argument.
divisibleby
~~~~~~~~~~~
@@ -1189,7 +1239,10 @@ Strips all [X]HTML tags.
time
~~~~
-Formats a time according to the given format (same as the ``now`` tag).
+Formats a time according to the given format (same as the `now`_ tag).
+The time filter will only accept parameters in the format string that relate
+to the time of day, not the date (for obvious reasons). If you need to
+format a date, use the `date`_ filter.
timesince
~~~~~~~~~
diff --git a/docs/templates_python.txt b/docs/templates_python.txt
index 821f40fd8d..117656762f 100644
--- a/docs/templates_python.txt
+++ b/docs/templates_python.txt
@@ -674,9 +674,9 @@ If you are writing a template filter which only expects a string as the first
argument, you should use the included decorator ``stringfilter`` which will convert
an object to it's string value before being passed to your function::
- from django import template
+ from django.template.defaultfilters import stringfilter
- @template.stringfilter
+ @stringfilter
def lower(value):
return value.lower()
diff --git a/docs/testing.txt b/docs/testing.txt
index b326e0099d..52285f5e8e 100644
--- a/docs/testing.txt
+++ b/docs/testing.txt
@@ -62,7 +62,7 @@ model-level doctests in the docstring for each model.
For example::
- from django.db import model
+ from django.db import models
class Animal(models.Model):
"""
@@ -79,8 +79,8 @@ For example::
'The cat says "meow"'
"""
- name = models.CharField(maxlength=20)
- sound = models.CharField(maxlength=20)
+ name = models.CharField(max_length=20)
+ sound = models.CharField(max_length=20)
def speak(self):
return 'The %s says "%s"' % (self.name, self.sound)
@@ -118,10 +118,18 @@ An equivalent unittest test case for the above example would look like::
self.assertEquals(self.lion.speak(), 'The lion says "roar"')
self.assertEquals(self.cat.speak(), 'The cat says "meow"')
-When you `run your tests`_, the test utility will find all the test cases
-(that is, subclasses of ``unittest.TestCase``) in ``models.py`` and
-``tests.py``, automatically build a test suite out of those test cases,
-and run that suite.
+When you `run your tests`_, the default behavior of the test utility is
+to find all the test cases (that is, subclasses of ``unittest.TestCase``)
+in ``models.py`` and ``tests.py``, automatically build a test suite out of
+those test cases, and run that suite.
+
+**New in Django development version**
+
+However, if you define a method called ``suite()`` in either ``models.py`` or
+``tests.py``, that method will be used to construct the test suite for that
+module. This follows the `suggested organization`_ for unit tests. See the
+Python documentation for more details on how to construct a complex test
+suite.
For more details about ``unittest``, see the `standard library unittest
documentation`_.
@@ -129,6 +137,7 @@ documentation`_.
.. _unittest: http://docs.python.org/lib/module-unittest.html
.. _standard library unittest documentation: unittest_
.. _run your tests: `Running tests`_
+.. _suggested organization: http://docs.python.org/lib/organizing-tests.html
Which should I use?
-------------------
@@ -441,6 +450,9 @@ look like::
def setUp(self):
# test definitions as before
+ def testFluffyAnimals(self):
+ # A test that uses the fixtures
+
At the start of each test case, before ``setUp()`` is run, Django will
flush the database, returning the database the state it was in directly
after ``syncdb`` was called. Then, all the named fixtures are installed.
@@ -472,10 +484,11 @@ Normal Python unit tests have a wide range of assertions, such as
``django.TestCase`` adds to these, providing some assertions
that can be useful in testing the behavior of web sites.
-``assertContains(response, text, count=1, status_code=200)``
+``assertContains(response, text, count=None, status_code=200)``
Assert that a response indicates that a page could be retrieved and
- produced the nominated status code, and that ``text`` occurs ``count``
- times in the content of the response.
+ produced the nominated status code, and that ``text`` in the content
+ of the response. If ``count`` is provided, ``text`` must occur exactly
+ ``count`` times in the response.
``assertFormError(response, form, field, errors)``
Assert that a field on a form raised the provided list of errors when
@@ -561,6 +574,18 @@ but you only want to run the animals unit tests, run::
$ ./manage.py test animals
+**New in Django development version:** If you use unit tests, you can be more
+specific in the tests that are executed. To run a single test case in an
+application (for example, the AnimalTestCase described previously), add the
+name of the test case to the label on the command line::
+
+ $ ./manage.py test animals.AnimalTestCase
+
+**New in Django development version:** To run a single test method inside a
+test case, add the name of the test method to the label::
+
+ $ ./manage.py test animals.AnimalTestCase.testFluffyAnimals
+
When you run your tests, you'll see a bunch of text flow by as the test
database is created and models are initialized. This test database is
created from scratch every time you run your tests.
@@ -652,17 +677,36 @@ framework that can be executed from Python code.
Defining a test runner
----------------------
By convention, a test runner should be called ``run_tests``; however, you
-can call it anything you want. The only requirement is that it accept two
-arguments:
+can call it anything you want. The only requirement is that it has the
+same arguments as the Django test runner:
+
+``run_tests(test_labels, verbosity=1, interactive=True, extra_tests=[])``
+
+ **New in Django development version:** ``test_labels`` is a list of
+ strings describing the tests to be run. A test label can take one of
+ three forms:
-``run_tests(module_list, verbosity=1)``
- The module list is the list of Python modules that contain the models to be
- tested. This is the same format returned by ``django.db.models.get_apps()``
+ * ``app.TestCase.test_method`` - Run a single test method in a test case
+ * ``app.TestCase`` - Run all the test methods in a test case
+ * ``app`` - Search for and run all tests in the named application.
+
+ If ``test_labels`` has a value of ``None``, the test runner should run
+ search for tests in all the applications in ``INSTALLED_APPS``.
Verbosity determines the amount of notification and debug information that
will be printed to the console; ``0`` is no output, ``1`` is normal output,
and ``2`` is verbose output.
+ **New in Django development version:** If ``interactive`` is ``True``, the
+ test suite may ask the user for instructions when the test suite is
+ executed. An example of this behavior would be asking for permission to
+ delete an existing test database. If ``interactive`` is ``False``, the
+ test suite must be able to run without any manual intervention.
+
+ ``extra_tests`` is a list of extra ``TestCase`` instances to add to the
+ suite that is executed by the test runner. These extra tests are run
+ in addition to those discovered in the modules listed in ``module_list``.
+
This method should return the number of tests that failed.
Testing utilities
diff --git a/docs/tutorial01.txt b/docs/tutorial01.txt
index aea3af6922..4f39fb4141 100644
--- a/docs/tutorial01.txt
+++ b/docs/tutorial01.txt
@@ -22,10 +22,10 @@ installed.
.. admonition:: Where to get help:
If you're having trouble going through this tutorial, please post a message
- to `django-users`_ or drop by `#django`_ on ``irc.freenode.net`` and we'll
+ to `django-users`_ or drop by `#django`_ on ``irc.freenode.net`` and we'll
try to help.
-.. _django-users: http://groups.google.com/group/django-users
+.. _django-users: http://groups.google.com/group/django-users
.. _#django: irc://irc.freenode.net/django
Creating a project
@@ -42,7 +42,7 @@ code, then run the command ``django-admin.py startproject mysite``. This
will create a ``mysite`` directory in your current directory.
.. note::
-
+
You'll need to avoid naming projects after built-in Python or Django
components. In particular, this means you should avoid using names like
``django`` (which will conflict with Django itself) or ``site`` (which
@@ -251,12 +251,12 @@ These concepts are represented by simple Python classes. Edit the
from django.db import models
class Poll(models.Model):
- question = models.CharField(maxlength=200)
+ question = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
class Choice(models.Model):
poll = models.ForeignKey(Poll)
- choice = models.CharField(maxlength=200)
+ choice = models.CharField(max_length=200)
votes = models.IntegerField()
The code is straightforward. Each model is represented by a class that
@@ -279,7 +279,7 @@ name for ``Poll.pub_date``. For all other fields in this model, the field's
machine-readable name will suffice as its human-readable name.
Some ``Field`` classes have required elements. ``CharField``, for example,
-requires that you give it a ``maxlength``. That's used not only in the database
+requires that you give it a ``max_length``. That's used not only in the database
schema, but in validation, as we'll soon see.
Finally, note a relationship is defined, using ``models.ForeignKey``. That tells
@@ -321,7 +321,7 @@ Now Django knows ``mysite`` includes the ``polls`` app. Let's run another comman
python manage.py sql polls
-You should see something similar to the following (the CREATE TABLE SQL statements
+You should see something similar to the following (the CREATE TABLE SQL statements
for the polls app)::
BEGIN;
@@ -341,7 +341,7 @@ for the polls app)::
Note the following:
* The exact output will vary depending on the database you are using.
-
+
* Table names are automatically generated by combining the name of the app
(``polls``) and the lowercase name of the model -- ``poll`` and
``choice``. (You can override this behavior.)
@@ -371,8 +371,8 @@ If you're interested, also run the following commands:
construction of your models.
* ``python manage.py sqlcustom polls`` -- Outputs any custom SQL statements
- (such as table modifications or constraints) that are defined for the
- application.
+ (such as table modifications or constraints) that are defined for the
+ application.
* ``python manage.py sqlclear polls`` -- Outputs the necessary ``DROP
TABLE`` statements for this app, according to which tables already exist
@@ -461,10 +461,10 @@ Once you're in the shell, explore the database API::
>>> p.question
"What's up?"
>>> p.pub_date
- datetime.datetime(2005, 7, 15, 12, 00, 53)
+ datetime.datetime(2007, 7, 15, 12, 00, 53)
# Change values by changing the attributes, then calling save().
- >>> p.pub_date = datetime(2005, 4, 1, 0, 0)
+ >>> p.pub_date = datetime(2007, 4, 1, 0, 0)
>>> p.save()
# objects.all() displays all the polls in the database.
@@ -494,19 +494,19 @@ admin.
.. admonition:: Why ``__unicode__()`` and not ``__str__()``?
- If you're familiar with Python, you might be in the habit of adding
- ``__str__()`` methods to your classes, not ``__unicode__()`` methods.
+ If you're familiar with Python, you might be in the habit of adding
+ ``__str__()`` methods to your classes, not ``__unicode__()`` methods.
We use ``__unicode__()`` here because Django models deal with Unicode by
default. All data stored in your database is converted to Unicode when it's
returned.
- Django models have a default ``__str__()`` method that calls ``__unicode__()``
- and converts the result to a UTF-8 bytestring. This means that ``unicode(p)``
- will return a Unicode string, and ``str(p)`` will return a normal string,
- with characters encoded as UTF-8.
+ Django models have a default ``__str__()`` method that calls
+ ``__unicode__()`` and converts the result to a UTF-8 bytestring. This means
+ that ``unicode(p)`` will return a 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 ``__unicode__()``
- methods to your models. With any luck, things should Just Work for you.
+ If all of this is jibberish to you, just remember to add ``__unicode__()``
+ methods to your models. With any luck, things should Just Work for you.
Note these are normal Python methods. Let's add a custom method, just for
demonstration::
@@ -537,9 +537,9 @@ Let's jump back into the Python interactive shell by running
>>> Poll.objects.filter(question__startswith='What')
[<Poll: What's up?>]
- # Get the poll whose year is 2005. Of course, if you're going through this
+ # Get the poll whose year is 2007. Of course, if you're going through this
# tutorial in another year, change as appropriate.
- >>> Poll.objects.get(pub_date__year=2005)
+ >>> Poll.objects.get(pub_date__year=2007)
<Poll: What's up?>
>>> Poll.objects.get(id=2)
@@ -580,9 +580,9 @@ Let's jump back into the Python interactive shell by running
# The API automatically follows relationships as far as you need.
# Use double underscores to separate relationships.
- # This works as many levels deep as you want. There's no limit.
- # Find all Choices for any poll whose pub_date is in 2005.
- >>> Choice.objects.filter(poll__pub_date__year=2005)
+ # This works as many levels deep as you want; there's no limit.
+ # Find all Choices for any poll whose pub_date is in 2007.
+ >>> Choice.objects.filter(poll__pub_date__year=2007)
[<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]
# Let's delete one of the choices. Use delete() for that.
diff --git a/docs/tutorial02.txt b/docs/tutorial02.txt
index 99f586b4a1..d96c38f2bd 100644
--- a/docs/tutorial02.txt
+++ b/docs/tutorial02.txt
@@ -240,7 +240,7 @@ default, provide enough fields for 3 Choices."
Then change the other fields in ``Choice`` to give them ``core=True``::
- choice = models.CharField(maxlength=200, core=True)
+ choice = models.CharField(max_length=200, core=True)
votes = models.IntegerField(core=True)
This tells Django: "When you edit a Choice on the Poll admin page, the 'choice'
@@ -362,8 +362,8 @@ think they should.
Customize the admin look and feel
=================================
-Clearly, having "Django administration" and "example.com" at the top of each
-admin page is ridiculous. It's just placeholder text.
+Clearly, having "Django administration" at the top of each admin page is
+ridiculous. It's just placeholder text.
That's easy to change, though, using Django's template system. The Django admin
is powered by Django itself, and its interfaces use Django's own template
@@ -389,7 +389,7 @@ as above, then copy ``django/contrib/admin/templates/admin/base_site.html`` to
``admin`` subdirectory.
Then, just edit the file and replace the generic Django text with your own
-site's name and URL as you see fit.
+site's name as you see fit.
Note that any of Django's default admin templates can be overridden. To
override a template, just do the same thing you did with ``base_site.html`` --
diff --git a/docs/tutorial03.txt b/docs/tutorial03.txt
index 41febe021d..d49a417dcf 100644
--- a/docs/tutorial03.txt
+++ b/docs/tutorial03.txt
@@ -355,8 +355,9 @@ view code.
Use the template system
=======================
-Back to our ``polls.detail`` view. Given the context variable ``poll``, here's
-what the template might look like::
+Back to the ``detail()`` view for our poll application. Given the context
+variable ``poll``, here's what the "polls/detail.html" template might look
+like::
<h1>{{ poll.question }}</h1>
<ul>
diff --git a/docs/tutorial04.txt b/docs/tutorial04.txt
index 5cc12c445d..553a76e9b1 100644
--- a/docs/tutorial04.txt
+++ b/docs/tutorial04.txt
@@ -8,8 +8,8 @@ application and will focus on simple form processing and cutting down our code.
Write a simple form
===================
-Let's update our poll detail template from the last tutorial, so that the
-template contains an HTML ``<form>`` element::
+Let's update our poll detail template ("polls/detail.html") from the last
+tutorial, so that the template contains an HTML ``<form>`` element::
<h1>{{ poll.question }}</h1>
@@ -193,7 +193,7 @@ Change it like so::
urlpatterns = patterns('',
(r'^$', 'django.views.generic.list_detail.object_list', info_dict),
(r'^(?P<object_id>\d+)/$', 'django.views.generic.list_detail.object_detail', info_dict),
- (r'^(?P<object_id>\d+)/results/$', 'django.views.generic.list_detail.object_detail', dict(info_dict, template_name='polls/results.html')),
+ (r'^(?P<object_id>\d+)/results/$', 'django.views.generic.list_detail.object_detail', dict(info_dict, template_name='polls/results.html'), 'poll_results'),
(r'^(?P<poll_id>\d+)/vote/$', 'mysite.polls.views.vote'),
)
@@ -209,6 +209,12 @@ objects" and "display a detail page for a particular type of object."
from the URL to be called ``"object_id"``, so we've changed ``poll_id`` to
``object_id`` for the generic views.
+ * We've added a name, ``poll_results``, to the results view so that we have
+ a way to refer to its URL later on (see `naming URL patterns`_ for more on
+ named patterns).
+
+.. _naming URL patterns: ../url_dispatch/#naming-url-patterns
+
By default, the ``object_detail`` generic view uses a template called
``<app name>/<model name>_detail.html``. In our case, it'll use the template
``"polls/poll_detail.html"``. Thus, rename your ``polls/detail.html`` template to
@@ -255,6 +261,15 @@ the new templates and context variables. Change the template call from
``polls/detail.html`` to ``polls/poll_detail.html``, and pass ``object`` in the
context instead of ``poll``.
+The last thing to do is fix the URL handling to account for the use of generic
+views. In the vote view above, we used the ``reverse()`` function to avoid
+hard-coding our URLs. Now that we've switched to a generic view, we'll need to
+change the ``reverse()`` call to point back to our new generic view. We can't
+simply use the view function anymore -- generic views can be (and are) used
+multiple times -- but we can use the name we've given::
+
+ return HttpResponseRedirect(reverse('poll_results', args=(p.id,)))
+
Run the server, and use your new polling app based on generic views.
For full details on generic views, see the `generic views documentation`_.
diff --git a/docs/url_dispatch.txt b/docs/url_dispatch.txt
index 402b1200b5..f9723a6a89 100644
--- a/docs/url_dispatch.txt
+++ b/docs/url_dispatch.txt
@@ -317,7 +317,7 @@ Old::
from django.conf.urls.defaults import *
urlpatterns = patterns('',
- (r'^/?$', 'django.views.generic.date_based.archive_index'),
+ (r'^$', 'django.views.generic.date_based.archive_index'),
(r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/$', 'django.views.generic.date_based.archive_month'),
(r'^tag/(?P<tag>\w+)/$', 'weblog.views.tag'),
)
@@ -327,7 +327,7 @@ New::
from django.conf.urls.defaults import *
urlpatterns = patterns('django.views.generic.date_based',
- (r'^/?$', 'archive_index'),
+ (r'^$', 'archive_index'),
(r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/$','archive_month'),
)
@@ -392,7 +392,7 @@ dictionary of extra keyword arguments to pass to the view function.
For example::
urlpatterns = patterns('blog.views',
- (r'^/blog/(?P<year>\d{4})/$', 'year_archive', {'foo': 'bar'}),
+ (r'^blog/(?P<year>\d{4})/$', 'year_archive', {'foo': 'bar'}),
)
In this example, for a request to ``/blog/2005/``, Django will call the
@@ -404,7 +404,7 @@ This technique is used in `generic views`_ and in the `syndication framework`_
to pass metadata and options to views.
.. _generic views: ../generic_views/
-.. _syndication framework: ../syndication/
+.. _syndication framework: ../syndication_feeds/
.. admonition:: Dealing with conflicts