Browse Source

Massive reorganization of the docs. See the new docs online at http://docs.djangoproject.com/.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@8506 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Jacob Kaplan-Moss 16 years ago
parent
commit
97cb07c3a1
100 changed files with 4010 additions and 14364 deletions
  1. 1 0
      AUTHORS
  2. 10 8
      docs/Makefile
  3. 88 0
      docs/_ext/applyxrefs.py
  4. 146 0
      docs/_ext/djangodocs.py
  5. 171 0
      docs/_ext/literals_to_xrefs.py
  6. 3 0
      docs/_static/default.css
  7. 126 0
      docs/_static/djangodocs.css
  8. BIN
      docs/_static/docicons-behindscenes.gif
  9. BIN
      docs/_static/docicons-note.gif
  10. BIN
      docs/_static/docicons-philosophy.gif
  11. 22 0
      docs/_static/homepage.css
  12. 7 0
      docs/_static/reset-fonts-grids.css
  13. 4 0
      docs/_templates/genindex.html
  14. 87 0
      docs/_templates/layout.html
  15. 3 0
      docs/_templates/modindex.html
  16. 3 0
      docs/_templates/search.html
  17. 0 119
      docs/api_stability.txt
  18. 0 1173
      docs/authentication.txt
  19. 22 9
      docs/conf.py
  20. 36 0
      docs/contents.txt
  21. 0 297
      docs/contenttypes.txt
  22. 0 2421
      docs/db-api.txt
  23. 0 138
      docs/documentation.txt
  24. 0 744
      docs/faq.txt
  25. 103 0
      docs/faq/admin.txt
  26. 30 0
      docs/faq/contributing.txt
  27. 256 0
      docs/faq/general.txt
  28. 75 0
      docs/faq/help.txt
  29. 16 0
      docs/faq/index.txt
  30. 108 0
      docs/faq/install.txt
  31. 94 0
      docs/faq/models.txt
  32. 65 0
      docs/faq/usage.txt
  33. 0 388
      docs/files.txt
  34. 0 95
      docs/form_preview.txt
  35. 0 304
      docs/form_wizard.txt
  36. 0 2468
      docs/forms.txt
  37. 0 1273
      docs/generic_views.txt
  38. 80 0
      docs/glossary.txt
  39. 15 9
      docs/howto/apache-auth.txt
  40. 78 0
      docs/howto/custom-file-storage.txt
  41. 33 0
      docs/howto/custom-management-commands.txt
  42. 196 174
      docs/howto/custom-model-fields.txt
  43. 78 664
      docs/howto/custom-template-tags.txt
  44. 49 34
      docs/howto/deployment/fastcgi.txt
  45. 33 0
      docs/howto/deployment/index.txt
  46. 52 40
      docs/howto/deployment/modpython.txt
  47. 65 0
      docs/howto/error-reporting.txt
  48. 33 0
      docs/howto/index.txt
  49. 140 0
      docs/howto/initial-data.txt
  50. 67 0
      docs/howto/legacy-databases.txt
  51. 27 30
      docs/howto/outputting-csv.txt
  52. 20 16
      docs/howto/outputting-pdf.txt
  53. 29 23
      docs/howto/static-files.txt
  54. 143 115
      docs/index.txt
  55. BIN
      docs/internals/_images/djangotickets.png
  56. 39 23
      docs/internals/contributing.txt
  57. 204 0
      docs/internals/documentation.txt
  58. 22 0
      docs/internals/index.txt
  59. BIN
      docs/intro/_images/admin01.png
  60. BIN
      docs/intro/_images/admin02.png
  61. BIN
      docs/intro/_images/admin02t.png
  62. BIN
      docs/intro/_images/admin03.png
  63. BIN
      docs/intro/_images/admin03t.png
  64. BIN
      docs/intro/_images/admin04.png
  65. BIN
      docs/intro/_images/admin04t.png
  66. BIN
      docs/intro/_images/admin05.png
  67. BIN
      docs/intro/_images/admin05t.png
  68. BIN
      docs/intro/_images/admin06.png
  69. BIN
      docs/intro/_images/admin06t.png
  70. BIN
      docs/intro/_images/admin07.png
  71. BIN
      docs/intro/_images/admin08.png
  72. BIN
      docs/intro/_images/admin08t.png
  73. BIN
      docs/intro/_images/admin09.png
  74. BIN
      docs/intro/_images/admin10.png
  75. BIN
      docs/intro/_images/admin11.png
  76. BIN
      docs/intro/_images/admin11t.png
  77. BIN
      docs/intro/_images/admin12.png
  78. BIN
      docs/intro/_images/admin13.png
  79. BIN
      docs/intro/_images/admin13t.png
  80. BIN
      docs/intro/_images/admin14.png
  81. BIN
      docs/intro/_images/admin14t.png
  82. 38 0
      docs/intro/index.txt
  83. 75 0
      docs/intro/install.txt
  84. 44 33
      docs/intro/overview.txt
  85. 252 210
      docs/intro/tutorial01.txt
  86. 86 90
      docs/intro/tutorial02.txt
  87. 133 111
      docs/intro/tutorial03.txt
  88. 117 110
      docs/intro/tutorial04.txt
  89. 235 0
      docs/intro/whatsnext.txt
  90. 0 69
      docs/legacy_databases.txt
  91. 0 733
      docs/localflavor.txt
  92. 1 2
      docs/man/django-admin.1
  93. 0 288
      docs/middleware.txt
  94. 95 0
      docs/misc/api-stability.txt
  95. 37 4
      docs/misc/design-philosophies.txt
  96. 4 4
      docs/misc/distributions.txt
  97. 14 0
      docs/misc/index.txt
  98. 0 2145
      docs/model-api.txt
  99. BIN
      docs/obsolete/_images/formrow.gif
  100. BIN
      docs/obsolete/_images/module.gif

+ 1 - 0
AUTHORS

@@ -67,6 +67,7 @@ answer newbie questions, and generally made Django that much better:
     Jiri Barton
     Ned Batchelder <http://www.nedbatchelder.com/>
     batiste@dosimple.ch
+    Batman
     Shannon -jj Behrens <http://jjinux.blogspot.com/>
     Esdras Beleza <linux@esdrasbeleza.com>
     Chris Bennett <chrisrbennett@yahoo.com>

+ 10 - 8
docs/Makefile

@@ -11,12 +11,12 @@ PAPEROPT_a4     = -D latex_paper_size=a4
 PAPEROPT_letter = -D latex_paper_size=letter
 ALLSPHINXOPTS   = -d _build/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
 
-.PHONY: help clean html web htmlhelp latex changes linkcheck
+.PHONY: help clean html web pickle htmlhelp latex changes linkcheck
 
 help:
 	@echo "Please use \`make <target>' where <target> is one of"
 	@echo "  html      to make standalone HTML files"
-	@echo "  web       to make files usable by Sphinx.web"
+	@echo "  pickle    to make pickle files (usable by e.g. sphinx-web)"
 	@echo "  htmlhelp  to make HTML files and a HTML help project"
 	@echo "  latex     to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
 	@echo "  changes   to make an overview over all changed/added/deprecated items"
@@ -31,13 +31,15 @@ html:
 	@echo
 	@echo "Build finished. The HTML pages are in _build/html."
 
-web:
-	mkdir -p _build/web _build/doctrees
-	$(SPHINXBUILD) -b web $(ALLSPHINXOPTS) _build/web
+pickle:
+	mkdir -p _build/pickle _build/doctrees
+	$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) _build/pickle
 	@echo
-	@echo "Build finished; now you can run"
-	@echo "  python -m sphinx.web _build/web"
-	@echo "to start the server."
+	@echo "Build finished; now you can process the pickle files or run"
+	@echo "  sphinx-web _build/pickle"
+	@echo "to start the sphinx-web server."
+
+web: pickle
 
 htmlhelp:
 	mkdir -p _build/htmlhelp _build/doctrees

+ 88 - 0
docs/_ext/applyxrefs.py

@@ -0,0 +1,88 @@
+"""Adds xref targets to the top of files."""
+
+import sys
+import os
+
+testing = False
+
+DONT_TOUCH = (
+        './index.txt',
+        )
+
+def target_name(fn):
+    if fn.endswith('.txt'):
+        fn = fn[:-4]
+    return '_' + fn.lstrip('./').replace('/', '-')
+
+def process_file(fn, lines):
+    lines.insert(0, '\n')
+    lines.insert(0, '.. %s:\n' % target_name(fn))
+    try:
+        f = open(fn, 'w')
+    except IOError:
+        print("Can't open %s for writing. Not touching it." % fn)
+        return
+    try:
+        f.writelines(lines)
+    except IOError:
+        print("Can't write to %s. Not touching it." % fn)
+    finally:
+        f.close()
+
+def has_target(fn):
+    try:
+        f = open(fn, 'r')
+    except IOError:
+        print("Can't open %s. Not touching it." % fn)
+        return (True, None)
+    readok = True
+    try:
+        lines = f.readlines()
+    except IOError:
+        print("Can't read %s. Not touching it." % fn)
+        readok = False
+    finally:
+        f.close()
+        if not readok:
+            return (True, None)
+
+    #print fn, len(lines)
+    if len(lines) < 1:
+        print("Not touching empty file %s." % fn)
+        return (True, None)
+    if lines[0].startswith('.. _'):
+        return (True, None)
+    return (False, lines)
+
+def main(argv=None):
+    if argv is None:
+        argv = sys.argv
+
+    if len(argv) == 1:
+        argv.extend('.')
+
+    files = []
+    for root in argv[1:]:
+        for (dirpath, dirnames, filenames) in os.walk(root):
+            files.extend([(dirpath, f) for f in filenames])
+    files.sort()
+    files = [os.path.join(p, fn) for p, fn in files if fn.endswith('.txt')]
+    #print files
+
+    for fn in files:
+        if fn in DONT_TOUCH:
+            print("Skipping blacklisted file %s." % fn)
+            continue
+
+        target_found, lines = has_target(fn)
+        if not target_found:
+            if testing:
+                print '%s: %s' % (fn, lines[0]),
+            else:
+                print "Adding xref to %s" % fn
+                process_file(fn, lines)
+        else:
+            print "Skipping %s: already has a xref" % fn
+
+if __name__ == '__main__':
+    sys.exit(main())

+ 146 - 0
docs/_ext/djangodocs.py

@@ -0,0 +1,146 @@
+"""
+Sphinx plugins for Django documentation.
+"""
+
+import docutils.nodes
+import docutils.transforms
+import sphinx
+import sphinx.addnodes
+import sphinx.builder
+import sphinx.directives
+import sphinx.environment
+import sphinx.htmlwriter
+
+def setup(app):
+    app.add_crossref_type(
+        directivename = "setting",
+        rolename      = "setting",
+        indextemplate = "pair: %s; setting",
+    )
+    app.add_crossref_type(
+        directivename = "templatetag",
+        rolename      = "ttag",
+        indextemplate = "pair: %s; template tag"
+    )
+    app.add_crossref_type(
+        directivename = "templatefilter",
+        rolename      = "tfilter",
+        indextemplate = "pair: %s; template filter"
+    )
+    app.add_crossref_type(
+        directivename = "fieldlookup",
+        rolename      = "lookup",
+        indextemplate = "pair: %s, field lookup type",
+    )
+    app.add_description_unit(
+        directivename = "django-admin",
+        rolename      = "djadmin",
+        indextemplate = "pair: %s; django-admin command",
+        parse_node    = parse_django_admin_node,
+    )
+    app.add_description_unit(
+        directivename = "django-admin-option",
+        rolename      = "djadminopt",
+        indextemplate = "pair: %s; django-admin command-line option",
+        parse_node    = lambda env, sig, signode: sphinx.directives.parse_option_desc(signode, sig),
+    )
+    app.add_transform(SuppressBlockquotes)
+    
+    # Monkeypatch PickleHTMLBuilder so that it doesn't die in Sphinx 0.4.2
+    if sphinx.__version__ == '0.4.2':
+        monkeypatch_pickle_builder()
+                
+class SuppressBlockquotes(docutils.transforms.Transform):
+    """
+    Remove the default blockquotes that encase indented list, tables, etc.
+    """
+    default_priority = 300
+    
+    suppress_blockquote_child_nodes = (
+        docutils.nodes.bullet_list, 
+        docutils.nodes.enumerated_list, 
+        docutils.nodes.definition_list,
+        docutils.nodes.literal_block, 
+        docutils.nodes.doctest_block, 
+        docutils.nodes.line_block, 
+        docutils.nodes.table
+    )
+    
+    def apply(self):
+        for node in self.document.traverse(docutils.nodes.block_quote):
+            if len(node.children) == 1 and isinstance(node.children[0], self.suppress_blockquote_child_nodes):
+                node.replace_self(node.children[0])
+
+class DjangoHTMLTranslator(sphinx.htmlwriter.SmartyPantsHTMLTranslator):
+    """
+    Django-specific reST to HTML tweaks.
+    """
+
+    # Don't use border=1, which docutils does by default.
+    def visit_table(self, node):
+        self.body.append(self.starttag(node, 'table', CLASS='docutils'))
+        
+    # Give each section a unique ID -- nice for custom CSS hooks
+    # This is different on docutils 0.5 vs. 0.4...
+    
+    # The docutils 0.4 override.
+    if hasattr(sphinx.htmlwriter.SmartyPantsHTMLTranslator, 'start_tag_with_title'):
+        def start_tag_with_title(self, node, tagname, **atts):
+            node = {
+                'classes': node.get('classes', []), 
+                'ids': ['s-%s' % i for i in node.get('ids', [])]
+            }
+            return self.starttag(node, tagname, **atts)
+            
+    # The docutils 0.5 override.
+    else:        
+        def visit_section(self, node):
+            old_ids = node.get('ids', [])
+            node['ids'] = ['s-' + i for i in old_ids]
+            sphinx.htmlwriter.SmartyPantsHTMLTranslator.visit_section(self, node)
+            node['ids'] = old_ids
+
+def parse_django_admin_node(env, sig, signode):
+    command = sig.split(' ')[0]
+    env._django_curr_admin_command = command
+    title = "django-admin.py %s" % sig
+    signode += sphinx.addnodes.desc_name(title, title)
+    return sig
+
+def monkeypatch_pickle_builder():
+    import shutil
+    from os import path
+    try:
+        import cPickle as pickle
+    except ImportError:
+        import pickle
+    from sphinx.util.console import bold
+    
+    def handle_finish(self):
+        # dump the global context
+        outfilename = path.join(self.outdir, 'globalcontext.pickle')
+        f = open(outfilename, 'wb')
+        try:
+            pickle.dump(self.globalcontext, f, 2)
+        finally:
+            f.close()
+
+        self.info(bold('dumping search index...'))
+        self.indexer.prune(self.env.all_docs)
+        f = open(path.join(self.outdir, 'searchindex.pickle'), 'wb')
+        try:
+            self.indexer.dump(f, 'pickle')
+        finally:
+            f.close()
+
+        # copy the environment file from the doctree dir to the output dir
+        # as needed by the web app
+        shutil.copyfile(path.join(self.doctreedir, sphinx.builder.ENV_PICKLE_FILENAME),
+                        path.join(self.outdir, sphinx.builder.ENV_PICKLE_FILENAME))
+
+        # touch 'last build' file, used by the web application to determine
+        # when to reload its environment and clear the cache
+        open(path.join(self.outdir, sphinx.builder.LAST_BUILD_FILENAME), 'w').close()
+
+    sphinx.builder.PickleHTMLBuilder.handle_finish = handle_finish
+    

+ 171 - 0
docs/_ext/literals_to_xrefs.py

@@ -0,0 +1,171 @@
+"""
+Runs through a reST file looking for old-style literals, and helps replace them
+with new-style references.
+"""
+
+import re
+import sys
+import shelve
+
+refre = re.compile(r'``([^`\s]+?)``')
+
+ROLES = (
+    'attr',
+    'class',
+    "djadmin",
+    'data',
+    'exc',
+    'file',
+    'func',
+    'lookup',
+    'meth',
+    'mod' ,
+    "djadminopt",
+    "ref",
+    "setting",
+    "term",
+    "tfilter",
+    "ttag",
+    
+    # special
+    "skip"
+)
+
+ALWAYS_SKIP = [
+    "NULL",
+    "True",
+    "False",
+]
+
+def fixliterals(fname):
+    data = open(fname).read()
+    
+    last = 0
+    new = []
+    storage = shelve.open("/tmp/literals_to_xref.shelve")
+    lastvalues = storage.get("lastvalues", {})
+    
+    for m in refre.finditer(data):
+        
+        new.append(data[last:m.start()])
+        last = m.end()
+        
+        line_start = data.rfind("\n", 0, m.start())
+        line_end = data.find("\n", m.end())
+        prev_start = data.rfind("\n", 0, line_start)
+        next_end = data.find("\n", line_end + 1)
+        
+        # Skip always-skip stuff
+        if m.group(1) in ALWAYS_SKIP:
+            new.append(m.group(0))
+            continue
+            
+        # skip when the next line is a title
+        next_line = data[m.end():next_end].strip()
+        if next_line[0] in "!-/:-@[-`{-~" and all(c == next_line[0] for c in next_line):
+            new.append(m.group(0))
+            continue
+        
+        sys.stdout.write("\n"+"-"*80+"\n")
+        sys.stdout.write(data[prev_start+1:m.start()])
+        sys.stdout.write(colorize(m.group(0), fg="red"))
+        sys.stdout.write(data[m.end():next_end])
+        sys.stdout.write("\n\n")
+        
+        replace_type = None
+        while replace_type is None:
+            replace_type = raw_input(
+                colorize("Replace role: ", fg="yellow")
+            ).strip().lower()
+            if replace_type and replace_type not in ROLES:
+                replace_type = None
+        
+        if replace_type == "":
+            new.append(m.group(0))
+            continue
+            
+        if replace_type == "skip":
+            new.append(m.group(0))
+            ALWAYS_SKIP.append(m.group(1))
+            continue
+        
+        default = lastvalues.get(m.group(1), m.group(1))
+        if default.endswith("()") and replace_type in ("class", "func", "meth"):
+            default = default[:-2]        
+        replace_value = raw_input(
+            colorize("Text <target> [", fg="yellow") + default + colorize("]: ", fg="yellow")
+        ).strip()
+        if not replace_value: 
+            replace_value = default
+        new.append(":%s:`%s`" % (replace_type, replace_value))
+        lastvalues[m.group(1)] = replace_value
+    
+    new.append(data[last:])
+    open(fname, "w").write("".join(new))
+    
+    storage["lastvalues"] = lastvalues
+    storage.close()
+    
+#
+# The following is taken from django.utils.termcolors and is copied here to
+# avoid the dependancy.
+#
+
+
+def colorize(text='', opts=(), **kwargs):
+    """
+    Returns your text, enclosed in ANSI graphics codes.
+
+    Depends on the keyword arguments 'fg' and 'bg', and the contents of
+    the opts tuple/list.
+
+    Returns the RESET code if no parameters are given.
+
+    Valid colors:
+        'black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white'
+
+    Valid options:
+        'bold'
+        'underscore'
+        'blink'
+        'reverse'
+        'conceal'
+        'noreset' - string will not be auto-terminated with the RESET code
+
+    Examples:
+        colorize('hello', fg='red', bg='blue', opts=('blink',))
+        colorize()
+        colorize('goodbye', opts=('underscore',))
+        print colorize('first line', fg='red', opts=('noreset',))
+        print 'this should be red too'
+        print colorize('and so should this')
+        print 'this should not be red'
+    """
+    color_names = ('black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white')
+    foreground = dict([(color_names[x], '3%s' % x) for x in range(8)])
+    background = dict([(color_names[x], '4%s' % x) for x in range(8)])
+
+    RESET = '0'
+    opt_dict = {'bold': '1', 'underscore': '4', 'blink': '5', 'reverse': '7', 'conceal': '8'}
+
+    text = str(text)
+    code_list = []
+    if text == '' and len(opts) == 1 and opts[0] == 'reset':
+        return '\x1b[%sm' % RESET
+    for k, v in kwargs.iteritems():
+        if k == 'fg':
+            code_list.append(foreground[v])
+        elif k == 'bg':
+            code_list.append(background[v])
+    for o in opts:
+        if o in opt_dict:
+            code_list.append(opt_dict[o])
+    if 'noreset' not in opts:
+        text = text + '\x1b[%sm' % RESET
+    return ('\x1b[%sm' % ';'.join(code_list)) + text
+
+if __name__ == '__main__':
+    try:
+        fixliterals(sys.argv[1])
+    except (KeyboardInterrupt, SystemExit):
+        print

+ 3 - 0
docs/_static/default.css

@@ -0,0 +1,3 @@
+@import url(reset-fonts-grids.css);
+@import url(djangodocs.css);
+@import url(homepage.css);

+ 126 - 0
docs/_static/djangodocs.css

@@ -0,0 +1,126 @@
+/*** setup ***/
+html { background:#092e20;}
+body { font:12px/1.5 Verdana,sans-serif; background:#092e20; color: white;}
+#custom-doc { width:76.54em;*width:74.69em;min-width:995px; max-width:100em; margin:auto; text-align:left; padding-top:16px; margin-top:0;} 
+#hd { padding: 4px 0 12px 0; }
+#bd { background:#234F32; }
+#ft { color:#487858; font-size:90%; padding-bottom: 2em; }
+
+/*** links ***/
+a {text-decoration: none;}
+a img {border: none;}
+a:link, a:visited { color:#ffc757; }
+#bd a:link, #bd a:visited { color:#ab5603; text-decoration:underline; }
+#bd #sidebar a:link, #bd #sidebar a:visited { color:#ffc757; text-decoration:none; }
+a:hover { color:#ffe761; }
+#bd a:hover { background-color:#E0FFB8; color:#234f32; text-decoration:none; }
+#bd #sidebar a:hover { color:#ffe761; background:none; }
+h2 a, h3 a, h4 a { text-decoration:none !important; }
+a.reference em { font-style: normal; }
+
+/*** sidebar ***/
+#sidebar div.sphinxsidebarwrapper { font-size:92%; margin-right: 14px; }
+#sidebar h3, #sidebar h4 { color: white; font-size: 125%; }
+#sidebar a { color: white; }
+#sidebar ul ul { margin-top:0; margin-bottom:0; }
+#sidebar li { margin-top: 0.2em; margin-bottom: 0.2em; }
+
+/*** nav ***/
+div.nav { margin: 0; font-size: 11px; text-align: right; color: #487858;}
+#hd div.nav { margin-top: -27px; }
+#ft div.nav { margin-bottom: -18px; }
+#hd h1 a { color: white; }
+#global-nav { position:absolute; top:5px; margin-left: -5px; padding:7px 0; color:#263E2B; }
+#global-nav a:link, #global-nav a:visited {color:#487858;}
+#global-nav a {padding:0 4px;}
+#global-nav a.about {padding-left:0;}
+#global-nav:hover {color:#fff;}
+#global-nav:hover a:link, #global-nav:hover a:visited  { color:#ffc757; }
+
+/*** content ***/
+#yui-main div.yui-b { position: relative; }
+#yui-main div.yui-b { margin: 0 0 0 20px; background: white; color: black; padding: 0.3em 2em 1em 2em; }
+
+/*** basic styles ***/
+dd { margin-left:15px; }
+h1,h2,h3,h4 { margin-top:1em; font-family:"Trebuchet MS",sans-serif; font-weight:normal; }
+h1 { font-size:218%; margin-top:0.6em; margin-bottom:.4em; line-height:1.1em; }
+h2 { font-size:175%; margin-bottom:.6em; line-height:1.2em; color:#092e20; }
+h3 { font-size:150%; font-weight:bold; margin-bottom:.2em; color:#487858; }
+h4 { font-size:125%; font-weight:bold; margin-top:1.5em; margin-bottom:3px; }
+div.figure { text-align: center; }
+div.figure p.caption { font-size:1em; margin-top:0; margin-bottom:1.5em; color: #555;}
+hr { color:#ccc; background-color:#ccc; height:1px; border:0; }
+p, ul, dl { margin-top:.6em; margin-bottom:1em; padding-bottom: 0.1em;}
+#yui-main div.yui-b img { max-width: 50em; margin-left: auto; margin-right: auto; display: block; }
+caption { font-size:1em; font-weight:bold; margin-top:0.5em; margin-bottom:0.5em; margin-left: 2px; text-align: center; }
+blockquote { padding: 0 1em; margin: 1em 0; font:125%/1.2em "Trebuchet MS", sans-serif; color:#234f32; border-left:2px solid #94da3a; } 
+strong { font-weight: bold; }
+em { font-style: italic; }
+ins { font-weight: bold; text-decoration: none; }
+
+/*** lists ***/
+ul { padding-left:30px; }
+ol { padding-left:30px; }
+ol.arabic { list-style-type: decimal; }
+ul li { list-style-type:square; margin-bottom:.4em; }
+ol li { margin-bottom: .4em; }
+ul ul { padding-left:1.2em; }
+ul ul ul { padding-left:1em; }
+ul.linklist, ul.toc { padding-left:0; }
+ul.toc ul { margin-left:.6em; }
+ul.toc ul li { list-style-type:square; }
+ul.toc ul ul li { list-style-type:disc; }
+ul.linklist li, ul.toc li { list-style-type:none; }
+dt { font-weight:bold; margin-top:.5em; font-size:1.1em; }
+dd { margin-bottom:.8em; }
+ol.toc { margin-bottom: 2em; }
+ol.toc li { font-size:125%; padding: .5em; line-height:1.2em; clear: right; }
+ol.toc li.b { background-color: #E0FFB8; }
+ol.toc li a:hover { background-color: transparent !important; text-decoration: underline !important; }
+ol.toc span.release-date { color:#487858; float: right; font-size: 85%; padding-right: .5em; }
+ol.toc span.comment-count { font-size: 75%; color: #999; }
+
+/*** tables ***/
+table { color:#000; margin-bottom: 1em; width: 100%; }
+table.docutils td p { margin-top:0; margin-bottom:.5em; }
+table.docutils td, table.docutils th { border-bottom:1px solid #dfdfdf; padding:4px 2px;}
+table.docutils thead th { border-bottom:2px solid #dfdfdf; text-align:left; font-weight: bold; white-space: nowrap; }
+table.docutils thead th p { margin: 0; padding: 0; }
+table.docutils { border-collapse:collapse; }
+
+/*** code blocks ***/
+.literal { white-space:nowrap; }
+.literal { color:#234f32; }
+#sidebar .literal { color:white; background:transparent; font-size:11px; }
+h4 .literal { color: #234f32; font-size: 13px; }
+pre { font-size:small; background:#E0FFB8; border:1px solid #94da3a; border-width:1px 0; margin: 1em 0; padding: .3em .4em; overflow: hidden; line-height: 1.3em;}
+dt .literal, table .literal { background:none; }
+#bd a.reference { text-decoration: none; }
+#bd a.reference tt.literal { border-bottom: 1px #234f32 dotted; }
+ 
+/*** notes & admonitions ***/
+.note, .admonition { padding:.8em 1em .8em; margin: 1em 0; border:1px solid #94da3a; }
+.admonition-title { font-weight:bold; margin-top:0 !important; margin-bottom:0 !important;}
+.admonition .last { margin-bottom:0 !important; }
+.note, .admonition { padding-left:65px; background:url(docicons-note.gif) .8em .8em no-repeat;}
+div.admonition-philosophy { padding-left:65px; background:url(docicons-philosophy.gif) .8em .8em no-repeat;}
+div.admonition-behind-the-scenes { padding-left:65px; background:url(docicons-behindscenes.gif) .8em .8em no-repeat;}
+
+/*** p-links ***/
+a.headerlink { color: #c60f0f; font-size: 0.8em; padding: 0 4px 0 4px; text-decoration: none; visibility: hidden; }
+h1:hover > a.headerlink, h2:hover > a.headerlink, h3:hover > a.headerlink, h4:hover > a.headerlink, h5:hover > a.headerlink, h6:hover > a.headerlink, dt:hover > a.headerlink { visibility: visible; }
+
+/*** index ***/
+table.indextable td { text-align: left; vertical-align: top;}
+table.indextable dl, table.indextable dd { margin-top: 0; margin-bottom: 0; }
+table.indextable tr.pcap { height: 10px; }
+table.indextable tr.cap { margin-top: 10px; background-color: #f2f2f2;}
+
+/*** page-specific overrides ***/
+div#contents ul { margin-bottom: 0;}
+div#contents ul li { margin-bottom: 0;}
+div#contents ul ul li { margin-top: 0.3em;}
+
+/*** IE hacks ***/
+* pre { width: 100%; }

BIN
docs/_static/docicons-behindscenes.gif


BIN
docs/_static/docicons-note.gif


BIN
docs/_static/docicons-philosophy.gif


+ 22 - 0
docs/_static/homepage.css

@@ -0,0 +1,22 @@
+#index p.rubric { font-size:150%; font-weight:normal; margin-bottom:.2em; color:#487858; }
+
+#index div.section dt { font-weight: normal; }
+
+#index #s-getting-help { float: right; width: 35em; background: #E1ECE2; padding: 1em; margin: 2em 0 2em 2em; }
+#index #s-getting-help h2 { margin: 0; }
+
+#index #s-django-documentation div.section div.section h3 { margin: 0; }
+#index #s-django-documentation div.section div.section { background: #E1ECE2; padding: 1em; margin: 2em 0 2em 40.3em; }
+#index #s-django-documentation div.section div.section a.reference { white-space: nowrap; }
+
+#index #s-using-django dl,
+#index #s-add-on-contrib-applications dl,
+#index #s-solving-specific-problems dl,
+#index #s-reference dl
+    { float: left; width: 41em; }
+
+#index #s-add-on-contrib-applications,
+#index #s-solving-specific-problems,
+#index #s-reference,
+#index #s-and-all-the-rest
+    { clear: left; }

File diff suppressed because it is too large
+ 7 - 0
docs/_static/reset-fonts-grids.css


+ 4 - 0
docs/_templates/genindex.html

@@ -0,0 +1,4 @@
+{% extends "!genindex.html" %}
+
+{% block bodyclass %}{% endblock %}
+{% block sidebarwrapper %}{% endblock %}

+ 87 - 0
docs/_templates/layout.html

@@ -0,0 +1,87 @@
+{% extends "!layout.html" %}
+
+{%- macro secondnav %}
+  {%- if prev %}
+    &laquo; <a href="{{ prev.link|e }}" title="{{ prev.title|e }}">previous</a> 
+    {{ reldelim2 }}
+  {%- endif %}
+  {%- if parents %}
+    <a href="{{ parents.0.link|e }}" title="{{ parents.0.title|e }}" accesskey="U">up</a> 
+  {%- else %}
+    <a title="{{ docstitle }}" href="{{ pathto('index') }}" accesskey="U">up</a> 
+  {%- endif %}
+  {%- if next %}
+  {{ reldelim2 }}
+    <a href="{{ next.link|e }}" title="{{ next.title|e }}">next</a> &raquo;
+  {%- endif %}
+{%- endmacro %}
+
+{% block document %}
+  <div id="custom-doc" class="{% block bodyclass %}{{ 'yui-t6' if pagename != 'index' else '' }}{% endblock %}">
+    <div id="hd">
+      <h1><a href="{{ pathto('index') }}">{{ docstitle }}</a></h1>
+      <div id="global-nav">
+        <a title="Home page" href="{{ pathto('index') }}">Home</a> {{ reldelim2 }}
+        <a title="Table of contents" href="{{ pathto('contents') }}">Table of contents</a> {{ reldelim2 }}
+        <a title="Global index" href="{{ pathto('genindex') }}">Index</a> {{ reldelim2 }}
+        <a title="Search" href="{{ pathto('modindex') }}">Modules</a>
+      </div>
+      <div class="nav">{{ secondnav() }}</div>
+    </div>
+    
+    <div id="bd">
+      <div id="yui-main">
+        <div class="yui-b">
+          <div class="yui-g" id="{{ pagename|replace('/', '-') }}">
+            {% block body %}{% endblock %}
+          </div>         
+        </div>
+      </div>
+      {% block sidebarwrapper %}
+        {% if pagename != 'index' %}
+          <div class="yui-b" id="sidebar">
+            {{ sidebar() }}
+            {%- if last_updated %}
+              <h3>Last update:</h3>
+              <p class="topless">{{ last_updated }}</p>
+            {%- endif %}
+          </div> 
+        {% endif %}
+      {% endblock %}
+    </div>
+    
+    <div id="ft">
+      <div class="nav">{{ secondnav() }}</div>
+    </div>
+  </div>
+{% endblock %}
+
+{% block sidebarrel %}
+  <h3>Browse</h3>
+  <ul>
+    {% if prev %}
+      <li>Prev: <a href="{{ prev.link }}">{{ prev.title }}</a></li>
+    {% endif %}
+    {% if next %}
+      <li>Next: <a href="{{ next.link }}">{{ next.title }}</a></li>
+    {% endif %}
+  </ul>
+  <h3>You are here:</h3>
+  <ul>
+      <li>
+        <a href="{{ pathto('index') }}">{{ docstitle }}</a>
+        {% for p in parents %}
+          <ul><li><a href="{{ p.link }}">{{ p.title }}</a>
+        {% endfor %}
+        <ul><li>{{ title }}</li></ul>
+        {% for p in parents %}</li></ul>{% endfor %}
+      </li>
+  </ul>  
+{% endblock %}
+
+{# Empty some default blocks out #}
+{% block relbar1 %}{% endblock %}
+{% block relbar2 %}{% endblock %}
+{% block sidebar1 %}{% endblock %}
+{% block sidebar2 %}{% endblock %}
+{% block footer %}{% endblock %}

+ 3 - 0
docs/_templates/modindex.html

@@ -0,0 +1,3 @@
+{% extends "!modindex.html" %}
+{% block bodyclass %}{% endblock %}
+{% block sidebarwrapper %}{% endblock %}

+ 3 - 0
docs/_templates/search.html

@@ -0,0 +1,3 @@
+{% extends "!search.html" %}
+{% block bodyclass %}{% endblock %}
+{% block sidebarwrapper %}{% endblock %}

+ 0 - 119
docs/api_stability.txt

@@ -1,119 +0,0 @@
-=============
-API stability
-=============
-
-Although Django has not reached a 1.0 release, the bulk of Django's public APIs are
-stable as of the 0.95 release. This document explains which APIs will and will not
-change before the 1.0 release.
-
-What "stable" means
-===================
-
-In this context, stable means:
-
-   - All the public APIs -- everything documented in the linked documents, and
-     all methods that don't begin with an underscore -- will not be moved or
-     renamed without providing backwards-compatible aliases.
-     
-   - If new features are added to these APIs -- which is quite possible --
-     they will not break or change the meaning of existing methods. In other
-     words, "stable" does not (necessarily) mean "complete."
-     
-   - If, for some reason, an API declared stable must be removed or replaced, it
-     will be declared deprecated but will remain in the API until at least
-     version 1.1. Warnings will be issued when the deprecated method is
-     called.
-     
-   - We'll only break backwards compatibility of these APIs if a bug or
-     security hole makes it completely unavoidable.
-
-Stable APIs
-===========
-
-These APIs are stable:
-
-   - `Caching`_.
-   
-   - `Custom template tags and libraries`_ (with the possible exception for a
-     small change in the way templates are registered and loaded).
-     
-   - `Database lookup`_ (with the exception of validation; see below).
-   
-   - `django-admin utility`_.
-   
-   - `FastCGI integration`_.
-   
-   - `Flatpages`_.
-   
-   - `Generic views`_.
-   
-   - `Internationalization`_.
-   
-   - `Legacy database integration`_.
-   
-   - `Model definition`_ (with the exception of generic relations; see below).
-   
-   - `mod_python integration`_.
-   
-   - `Redirects`_.
-   
-   - `Request/response objects`_.
-   
-   - `Sending e-mail`_.
-   
-   - `Sessions`_.
-   
-   - `Settings`_.
-   
-   - `Syndication`_.
-   
-   - `Template language`_ (with the exception of some possible disambiguation
-     of how tag arguments are passed to tags and filters).
-   
-   - `Transactions`_.
-   
-   - `URL dispatch`_.   
-   
-You'll notice that this list comprises the bulk of Django's APIs. That's right
--- most of the changes planned between now and Django 1.0 are either under the
-hood, feature additions, or changes to a few select bits. A good estimate is
-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:
-
-   - `Serialization`_ is under heavy development; changes are likely.
-
-   - The `authentication`_ framework is changing to be far more flexible, and
-     API changes may be necessary.
-
-   - Generic relations will most likely be moved out of core and into the
-     content-types contrib package to avoid core dependencies on optional
-     components.
-
-   - The comments framework, which is yet undocumented, will likely get a complete
-     rewrite before Django 1.0. Even if the change isn't quite that drastic,
-     there will at least be moderate changes.
-     
-.. _caching: ../cache/
-.. _custom template tags and libraries: ../templates_python/
-.. _database lookup: ../db-api/
-.. _django-admin utility: ../django-admin/
-.. _fastcgi integration: ../fastcgi/
-.. _flatpages: ../flatpages/
-.. _generic views: ../generic_views/
-.. _internationalization: ../i18n/
-.. _legacy database integration: ../legacy_databases/
-.. _model definition: ../model-api/
-.. _mod_python integration: ../modpython/
-.. _redirects: ../redirects/
-.. _request/response objects: ../request_response/
-.. _sending e-mail: ../email/
-.. _sessions: ../sessions/
-.. _settings: ../settings/
-.. _syndication: ../syndication_feeds/
-.. _template language: ../templates/
-.. _transactions: ../transactions/
-.. _url dispatch: ../url_dispatch/
-.. _serialization: ../serialization/
-.. _authentication: ../authentication/

+ 0 - 1173
docs/authentication.txt

@@ -1,1173 +0,0 @@
-=============================
-User authentication in Django
-=============================
-
-Django comes with a user authentication system. It handles user accounts,
-groups, permissions and cookie-based user sessions. This document explains how
-things work.
-
-Overview
-========
-
-The auth system consists of:
-
-    * Users
-    * Permissions: Binary (yes/no) flags designating whether a user may perform
-      a certain task.
-    * Groups: A generic way of applying labels and permissions to more than one
-      user.
-    * Messages: A simple way to queue messages for given users.
-
-Installation
-============
-
-Authentication support is bundled as a Django application in
-``django.contrib.auth``. To install it, do the following:
-
-    1. Put ``'django.contrib.auth'`` in your ``INSTALLED_APPS`` setting.
-    2. Run the command ``manage.py syncdb``.
-
-Note that the default ``settings.py`` file created by
-``django-admin.py startproject`` includes ``'django.contrib.auth'`` in
-``INSTALLED_APPS`` for convenience. If your ``INSTALLED_APPS`` already contains
-``'django.contrib.auth'``, feel free to run ``manage.py syncdb`` again; you
-can run that command as many times as you'd like, and each time it'll only
-install what's needed.
-
-The ``syncdb`` command creates the necessary database tables, creates
-permission objects for all installed apps that need 'em, and prompts you to
-create a superuser account the first time you run it.
-
-Once you've taken those steps, that's it.
-
-Users
-=====
-
-Users are represented by a standard Django model, which lives in
-`django/contrib/auth/models.py`_.
-
-.. _django/contrib/auth/models.py: http://code.djangoproject.com/browser/django/trunk/django/contrib/auth/models.py
-
-API reference
--------------
-
-Fields
-~~~~~~
-
-``User`` objects have the following fields:
-
-    * ``username`` -- Required. 30 characters or fewer. Alphanumeric characters
-      only (letters, digits and underscores).
-    * ``first_name`` -- Optional. 30 characters or fewer.
-    * ``last_name`` -- Optional. 30 characters or fewer.
-    * ``email`` -- Optional. E-mail address.
-    * ``password`` -- Required. A hash of, and metadata about, the password.
-      (Django doesn't store the raw password.) Raw passwords can be arbitrarily
-      long and can contain any character. See the "Passwords" section below.
-    * ``is_staff`` -- Boolean. Designates whether this user can access the
-      admin site.
-    * ``is_active`` -- Boolean. Designates whether this account can be used
-      to log in. Set this flag to ``False`` instead of deleting accounts.
-    * ``is_superuser`` -- Boolean. Designates that this user has all permissions
-      without explicitly assigning them.
-    * ``last_login`` -- A datetime of the user's last login. Is set to the
-      current date/time by default.
-    * ``date_joined`` -- A datetime designating when the account was created.
-      Is set to the current date/time by default when the account is created.
-
-Methods
-~~~~~~~
-
-``User`` objects have two many-to-many fields: ``groups`` and
-``user_permissions``. ``User`` objects can access their related
-objects in the same way as any other `Django model`_::
-
-    myuser.groups = [group_list]
-    myuser.groups.add(group, group, ...)
-    myuser.groups.remove(group, group, ...)
-    myuser.groups.clear()
-    myuser.user_permissions = [permission_list]
-    myuser.user_permissions.add(permission, permission, ...)
-    myuser.user_permissions.remove(permission, permission, ...)
-    myuser.user_permissions.clear()
-
-In addition to those automatic API methods, ``User`` objects have the following
-custom methods:
-
-    * ``is_anonymous()`` -- Always returns ``False``. This is a way of
-      differentiating ``User`` and ``AnonymousUser`` objects. Generally, you
-      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
-      permissions, and doesn't check if the user is active - it only indicates
-      that the user has provided a valid username and password.
-
-    * ``get_full_name()`` -- Returns the ``first_name`` plus the ``last_name``,
-      with a space in between.
-
-    * ``set_password(raw_password)`` -- Sets the user's password to the given
-      raw string, taking care of the password hashing. Doesn't save the
-      ``User`` object.
-
-    * ``check_password(raw_password)`` -- Returns ``True`` if the given raw
-      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.
-
-    * ``get_all_permissions()`` -- Returns a list of permission strings that
-      the user has, both through group and user permissions.
-
-    * ``has_perm(perm)`` -- Returns ``True`` if the user has the specified
-      permission, where perm is in the format ``"package.codename"``.
-      If the user is inactive, this method will always return ``False``.
-
-    * ``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
-      always return ``False``.
-
-    * ``has_module_perms(package_name)`` -- Returns ``True`` if the user has
-      any permissions in the given package (the Django app label).
-      If the user is inactive, this method will always return ``False``.
-
-    * ``get_and_delete_messages()`` -- Returns a list of ``Message`` objects in
-      the user's queue and deletes the messages from the queue.
-
-    * ``email_user(subject, message, from_email=None)`` -- Sends an e-mail to
-      the user. If ``from_email`` is ``None``, Django uses the
-      `DEFAULT_FROM_EMAIL`_ setting.
-
-    * ``get_profile()`` -- Returns a site-specific profile for this user.
-      Raises ``django.contrib.auth.models.SiteProfileNotAvailable`` if the current site
-      doesn't allow profiles. For information on how to define a
-      site-specific user profile, see the section on `storing additional
-      user information`_ below.
-
-.. _Django model: ../model-api/
-.. _DEFAULT_FROM_EMAIL: ../settings/#default-from-email
-.. _storing additional user information: #storing-additional-information-about-users
-
-Manager functions
-~~~~~~~~~~~~~~~~~
-
-The ``User`` model has a custom manager that has the following helper functions:
-
-    * ``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.
-
-    * ``make_random_password(length=10, allowed_chars='abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789')``
-      Returns a random password with the given length and given string of
-      allowed characters. (Note that the default value of ``allowed_chars``
-      doesn't contain letters that can cause user confusion, including
-      ``1``, ``I`` and ``0``).
-
-Basic usage
------------
-
-Creating users
-~~~~~~~~~~~~~~
-
-The most basic way to create users is to use the ``create_user`` helper
-function that comes with Django::
-
-    >>> from django.contrib.auth.models import User
-    >>> user = User.objects.create_user('john', 'lennon@thebeatles.com', 'johnpassword')
-
-    # At this point, user is a User object that has already been saved
-    # to the database. You can continue to change its attributes
-    # if you want to change other fields.
-    >>> user.is_staff = True
-    >>> user.save()
-
-Changing passwords
-~~~~~~~~~~~~~~~~~~
-
-Change a password with ``set_password()``::
-
-    >>> from django.contrib.auth.models import User
-    >>> u = User.objects.get(username__exact='john')
-    >>> u.set_password('new password')
-    >>> u.save()
-
-Don't set the ``password`` attribute directly unless you know what you're
-doing. This is explained in the next section.
-
-Passwords
----------
-
-The ``password`` attribute of a ``User`` object is a string in this format::
-
-    hashtype$salt$hash
-
-That's hashtype, salt and hash, separated by the dollar-sign character.
-
-Hashtype is either ``sha1`` (default), ``md5`` or ``crypt`` -- the algorithm
-used to perform a one-way hash of the password. Salt is a random string used
-to salt the raw password to create the hash. Note that the ``crypt`` method is
-only supported on platforms that have the standard Python ``crypt`` module
-available, and ``crypt`` support is only available in the Django development
-version.
-
-For example::
-
-    sha1$a1976$a36cc8cbf81742a8fb52e221aaeab48ed7f58ab4
-
-The ``User.set_password()`` and ``User.check_password()`` functions handle
-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 ``User.check_password()``
-works correctly for a given user.
-
-Anonymous users
----------------
-
-``django.contrib.auth.models.AnonymousUser`` is a class that implements
-the ``django.contrib.auth.models.User`` interface, with these differences:
-
-    * ``id`` is always ``None``.
-    * ``is_staff`` and ``is_superuser`` are always ``False``.
-    * ``is_active`` is always ``False``.
-    * ``groups`` and ``user_permissions`` are always empty.
-    * ``is_anonymous()`` returns ``True`` instead of ``False``.
-    * ``is_authenticated()`` returns ``False`` instead of ``True``.
-    * ``has_perm()`` always returns ``False``.
-    * ``set_password()``, ``check_password()``, ``save()``, ``delete()``,
-      ``set_groups()`` and ``set_permissions()`` raise ``NotImplementedError``.
-
-In practice, you probably won't need to use ``AnonymousUser`` objects on your
-own, but they're used by Web requests, as explained in the next section.
-
-Creating superusers
--------------------
-
-``manage.py syncdb`` prompts you to create a superuser the first time you run
-it after adding ``'django.contrib.auth'`` to your ``INSTALLED_APPS``. If you need
-to create a superuser at a later date, you can use a command line utility.
-
-**New in Django development version.**::
-
-    manage.py createsuperuser --username=joe --email=joe@example.com
-
-You will be prompted for a password. After you enter one, the user will be
-created immediately. If you leave off the ``--username`` or the ``--email``
-options, it will prompt you for those values.
-
-If you're using an older release of Django, the old way of creating a superuser
-on the command line still works::
-
-    python /path/to/django/contrib/auth/create_superuser.py
-
-...where ``/path/to`` is the path to the Django codebase on your filesystem. The
-``manage.py`` command is preferred because it figures out the correct path and
-environment for you.
-
-Storing additional information about users
-------------------------------------------
-
-If you'd like to store additional information related to your users,
-Django provides a method to specify a site-specific related model --
-termed a "user profile" -- for this purpose.
-
-To make use of this feature, define a model with fields for the
-additional information you'd like to store, or additional methods
-you'd like to have available, and also add a ``ForeignKey`` from your
-model to the ``User`` model, specified with ``unique=True`` to ensure
-only one instance of your model can be created for each ``User``.
-
-To indicate that this model is the user profile model for a given
-site, fill in the setting ``AUTH_PROFILE_MODULE`` with a string
-consisting of the following items, separated by a dot:
-
-1. The (normalized to lower-case) name of the application in which the
-   user profile model is defined (in other words, an all-lowercase
-   version of the name which was passed to ``manage.py startapp`` to
-   create the application).
-
-2. The (normalized to lower-case) name of the model class.
-
-For example, if the profile model was a class named ``UserProfile``
-and was defined inside an application named ``accounts``, the
-appropriate setting would be::
-
-    AUTH_PROFILE_MODULE = 'accounts.userprofile'
-
-When a user profile model has been defined and specified in this
-manner, each ``User`` object will have a method -- ``get_profile()``
--- which returns the instance of the user profile model associated
-with that ``User``.
-
-For more information, see `Chapter 12 of the Django book`_.
-
-.. _Chapter 12 of the Django book: http://www.djangobook.com/en/1.0/chapter12/#cn222
-
-Authentication in Web requests
-==============================
-
-Until now, this document has dealt with the low-level APIs for manipulating
-authentication-related objects. On a higher level, Django can hook this
-authentication framework into its system of `request objects`_.
-
-First, install the ``SessionMiddleware`` and ``AuthenticationMiddleware``
-middlewares by adding them to your ``MIDDLEWARE_CLASSES`` setting. See the
-`session documentation`_ for more information.
-
-Once you have those middlewares installed, you'll be able to access
-``request.user`` in views. ``request.user`` will give you a ``User`` object
-representing the currently logged-in user. If a user isn't currently logged in,
-``request.user`` will be set to an instance of ``AnonymousUser`` (see the
-previous section). You can tell them apart with ``is_authenticated()``, like so::
-
-    if request.user.is_authenticated():
-        # Do something for authenticated users.
-    else:
-        # Do something for anonymous users.
-
-.. _request objects: ../request_response/#httprequest-objects
-.. _session documentation: ../sessions/
-
-How to log a user in
---------------------
-
-Django provides two functions in ``django.contrib.auth``: ``authenticate()``
-and ``login()``.
-
-To authenticate a given username and password, use ``authenticate()``. It
-takes two keyword arguments, ``username`` and ``password``, and it returns
-a ``User`` object if the password is valid for the given username. If the
-password is invalid, ``authenticate()`` returns ``None``. Example::
-
-    from django.contrib.auth import authenticate
-    user = authenticate(username='john', password='secret')
-    if user is not None:
-        if user.is_active:
-            print "You provided a correct username and password!"
-        else:
-            print "Your account has been disabled!"
-    else:
-        print "Your username and password were incorrect."
-
-To log a user in, in a view, use ``login()``. It takes an ``HttpRequest``
-object and a ``User`` object. ``login()`` saves the user's ID in the session,
-using Django's session framework, so, as mentioned above, you'll need to make
-sure to have the session middleware installed.
-
-This example shows how you might use both ``authenticate()`` and ``login()``::
-
-    from django.contrib.auth import authenticate, login
-
-    def my_view(request):
-        username = request.POST['username']
-        password = request.POST['password']
-        user = authenticate(username=username, password=password)
-        if user is not None:
-            if user.is_active:
-                login(request, user)
-                # Redirect to a success page.
-            else:
-                # Return a 'disabled account' error message
-        else:
-            # Return an 'invalid login' error message.
-
-.. admonition:: Calling ``authenticate()`` first
-
-    When you're manually logging a user in, you *must* call
-    ``authenticate()`` before you call ``login()``. ``authenticate()``
-    sets an attribute on the ``User`` noting which authentication
-    backend successfully authenticated that user (see the `backends
-    documentation`_ for details), and this information is needed later
-    during the login process.
-
-.. _backends documentation: #other-authentication-sources
-
-Manually checking a user's password
------------------------------------
-
-If you'd like to manually authenticate a user by comparing a
-plain-text password to the hashed password in the database, use the
-convenience function ``django.contrib.auth.models.check_password``. It
-takes two arguments: the plain-text password to check, and the full
-value of a user's ``password`` field in the database to check against,
-and returns ``True`` if they match, ``False`` otherwise.
-
-How to log a user out
----------------------
-
-To log out a user who has been logged in via ``django.contrib.auth.login()``,
-use ``django.contrib.auth.logout()`` within your view. It takes an
-``HttpRequest`` object and has no return value. Example::
-
-    from django.contrib.auth import logout
-
-    def logout_view(request):
-        logout(request)
-        # Redirect to a success page.
-
-Note that ``logout()`` doesn't throw any errors if the user wasn't logged in.
-
-**New in Django development version:** When you call ``logout()``, the session
-data for the current request is completely cleaned out. All existing data is
-removed. This is to prevent another person from using the same web browser to
-log in and have access to the previous user's session data. If you want to put
-anything into the session that will be available to the user immediately after
-logging out, do that *after* calling ``django.contrib.auth.logout()``.
-
-Limiting access to logged-in users
-----------------------------------
-
-The raw way
-~~~~~~~~~~~
-
-The simple, raw way to limit access to pages is to check
-``request.user.is_authenticated()`` and either redirect to a login page::
-
-    from django.http import HttpResponseRedirect
-
-    def my_view(request):
-        if not request.user.is_authenticated():
-            return HttpResponseRedirect('/login/?next=%s' % request.path)
-        # ...
-
-...or display an error message::
-
-    def my_view(request):
-        if not request.user.is_authenticated():
-            return render_to_response('myapp/login_error.html')
-        # ...
-
-The login_required decorator
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-As a shortcut, you can use the convenient ``login_required`` decorator::
-
-    from django.contrib.auth.decorators import login_required
-
-    def my_view(request):
-        # ...
-    my_view = login_required(my_view)
-
-Here's an equivalent example, using the more compact decorator syntax
-introduced in Python 2.4::
-
-    from django.contrib.auth.decorators import login_required
-
-    @login_required
-    def my_view(request):
-        # ...
-
-In the Django development version, ``login_required`` also takes an optional
-``redirect_field_name`` parameter. Example::
-
-    from django.contrib.auth.decorators import login_required
-
-    def my_view(request):
-        # ...
-    my_view = login_required(redirect_field_name='redirect_to')(my_view)
-
-Again, an equivalent example of the more compact decorator syntax introduced in Python 2.4::
-
-    from django.contrib.auth.decorators import login_required
-
-    @login_required(redirect_field_name='redirect_to')
-    def my_view(request):
-        # ...
-
-``login_required`` does the following:
-
-    * If the user isn't logged in, redirect to ``settings.LOGIN_URL``
-      (``/accounts/login/`` by default), passing the current absolute URL
-      in the query string as ``next`` or the value of ``redirect_field_name``.
-      For example:
-      ``/accounts/login/?next=/polls/3/``.
-    * If the user is logged in, execute the view normally. The view code is
-      free to assume the user is logged in.
-
-Note that you'll need to map the appropriate Django view to ``settings.LOGIN_URL``.
-For example, using the defaults, add the following line to your URLconf::
-
-    (r'^accounts/login/$', 'django.contrib.auth.views.login'),
-
-Here's what ``django.contrib.auth.views.login`` does:
-
-    * If called via ``GET``, it displays a login form that POSTs to the same
-      URL. More on this in a bit.
-
-    * If called via ``POST``, it tries to log the user in. If login is
-      successful, the view redirects to the URL specified in ``next``. If
-      ``next`` isn't provided, it redirects to ``settings.LOGIN_REDIRECT_URL``
-      (which defaults to ``/accounts/profile/``). If login isn't successful,
-      it redisplays the login form.
-
-It's your responsibility to provide the login form in a template called
-``registration/login.html`` by default. This template gets passed three
-template context variables:
-
-    * ``form``: A ``Form`` object representing the login form. See the
-      `forms documentation`_ for more on ``FormWrapper`` objects.
-    * ``next``: The URL to redirect to after successful login. This may contain
-      a query string, too.
-    * ``site_name``: The name of the current ``Site``, according to the
-      ``SITE_ID`` setting. If you're using the Django development version and
-      you don't have the site framework installed, this will be set to the
-      value of ``request.META['SERVER_NAME']``. For more on sites, see the
-      `site framework docs`_.
-
-If you'd prefer not to call the template ``registration/login.html``, you can
-pass the ``template_name`` parameter via the extra arguments to the view in
-your URLconf. For example, this URLconf line would use ``myapp/login.html``
-instead::
-
-    (r'^accounts/login/$', 'django.contrib.auth.views.login', {'template_name': 'myapp/login.html'}),
-
-Here's a sample ``registration/login.html`` template you can use as a starting
-point. It assumes you have a ``base.html`` template that defines a ``content``
-block::
-
-    {% extends "base.html" %}
-
-    {% block content %}
-
-    {% if form.errors %}
-    <p>Your username and password didn't match. Please try again.</p>
-    {% endif %}
-
-    <form method="post" action=".">
-    <table>
-    <tr><td>{{ form.username.label_tag }}</td><td>{{ form.username }}</td></tr>
-    <tr><td>{{ form.password.label_tag }}</td><td>{{ form.password }}</td></tr>
-    </table>
-
-    <input type="submit" value="login" />
-    <input type="hidden" name="next" value="{{ next }}" />
-    </form>
-
-    {% endblock %}
-
-.. _forms documentation: ../forms/
-.. _site framework docs: ../sites/
-
-Other built-in views
---------------------
-
-In addition to the ``login`` view, the authentication system includes a
-few other useful built-in views:
-
-``django.contrib.auth.views.logout``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-**Description:**
-
-Logs a user out.
-
-**Optional arguments:**
-
-    * ``template_name``: The full name of a template to display after
-      logging the user out. This will default to
-      ``registration/logged_out.html`` if no argument is supplied.
-
-**Template context:**
-
-    * ``title``: The string "Logged out", localized.
-
-``django.contrib.auth.views.logout_then_login``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-**Description:**
-
-Logs a user out, then redirects to the login page.
-
-**Optional arguments:**
-
-    * ``login_url``: The URL of the login page to redirect to. This
-      will default to ``settings.LOGIN_URL`` if not supplied.
-
-``django.contrib.auth.views.password_change``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-**Description:**
-
-Allows a user to change their password.
-
-**Optional arguments:**
-
-    * ``template_name``: The full name of a template to use for
-      displaying the password change form. This will default to
-      ``registration/password_change_form.html`` if not supplied.
-
-**Template context:**
-
-    * ``form``: The password change form.
-
-``django.contrib.auth.views.password_change_done``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-**Description:**
-
-The page shown after a user has changed their password.
-
-**Optional arguments:**
-
-    * ``template_name``: The full name of a template to use. This will
-      default to ``registration/password_change_done.html`` if not
-      supplied.
-
-``django.contrib.auth.views.password_reset``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-**Description:**
-
-Allows a user to reset their password, and sends them the new password
-in an e-mail.
-
-**Optional arguments:**
-
-    * ``template_name``: The full name of a template to use for
-      displaying the password reset form. This will default to
-      ``registration/password_reset_form.html`` if not supplied.
-
-    * ``email_template_name``: The full name of a template to use for
-      generating the e-mail with the new password. This will default to
-      ``registration/password_reset_email.html`` if not supplied.
-
-**Template context:**
-
-    * ``form``: The form for resetting the user's password.
-
-``django.contrib.auth.views.password_reset_done``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-**Description:**
-
-The page shown after a user has reset their password.
-
-**Optional arguments:**
-
-    * ``template_name``: The full name of a template to use. This will
-      default to ``registration/password_reset_done.html`` if not
-      supplied.
-
-``django.contrib.auth.views.redirect_to_login``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-**Description:**
-
-Redirects to the login page, and then back to another URL after a
-successful login.
-
-**Required arguments:**
-
-    * ``next``: The URL to redirect to after a successful login.
-
-**Optional arguments:**
-
-    * ``login_url``: The URL of the login page to redirect to. This
-      will default to ``settings.LOGIN_URL`` if not supplied.
-
-Built-in forms
---------------
-
-**New in Django development version.**
-
-If you don't want to use the built-in views, but want the convenience
-of not having to write forms for this functionality, the authentication
-system provides several built-in forms:
-
-    * ``django.contrib.auth.forms.AdminPasswordChangeForm``: A form used in
-      the admin interface to change a user's password.
-
-    * ``django.contrib.auth.forms.AuthenticationForm``: A form for logging a
-      user in.
-
-    * ``django.contrib.auth.forms.PasswordChangeForm``: A form for allowing a
-      user to change their password.
-
-    * ``django.contrib.auth.forms.PasswordResetForm``: A form for resetting a
-      user's password and e-mailing the new password to them.
-
-    * ``django.contrib.auth.forms.UserCreationForm``: A form for creating a
-      new user.
-
-Limiting access to logged-in users that pass a test
----------------------------------------------------
-
-To limit access based on certain permissions or some other test, you'd do
-essentially the same thing as described in the previous section.
-
-The simple way is to run your test on ``request.user`` in the view directly.
-For example, this view checks to make sure the user is logged in and has the
-permission ``polls.can_vote``::
-
-    def my_view(request):
-        if not (request.user.is_authenticated() and request.user.has_perm('polls.can_vote')):
-            return HttpResponse("You can't vote in this poll.")
-        # ...
-
-As a shortcut, you can use the convenient ``user_passes_test`` decorator::
-
-    from django.contrib.auth.decorators import user_passes_test
-
-    def my_view(request):
-        # ...
-    my_view = user_passes_test(lambda u: u.has_perm('polls.can_vote'))(my_view)
-
-We're using this particular test as a relatively simple example. However, if
-you just want to test whether a permission is available to a user, you can use
-the ``permission_required()`` decorator, described later in this document.
-
-Here's the same thing, using Python 2.4's decorator syntax::
-
-    from django.contrib.auth.decorators import user_passes_test
-
-    @user_passes_test(lambda u: u.has_perm('polls.can_vote'))
-    def my_view(request):
-        # ...
-
-``user_passes_test`` takes a required argument: a callable that takes a
-``User`` object and returns ``True`` if the user is allowed to view the page.
-Note that ``user_passes_test`` does not automatically check that the ``User``
-is not anonymous.
-
-``user_passes_test()`` takes an optional ``login_url`` argument, which lets you
-specify the URL for your login page (``settings.LOGIN_URL`` by default).
-
-Example in Python 2.3 syntax::
-
-    from django.contrib.auth.decorators import user_passes_test
-
-    def my_view(request):
-        # ...
-    my_view = user_passes_test(lambda u: u.has_perm('polls.can_vote'), login_url='/login/')(my_view)
-
-Example in Python 2.4 syntax::
-
-    from django.contrib.auth.decorators import user_passes_test
-
-    @user_passes_test(lambda u: u.has_perm('polls.can_vote'), login_url='/login/')
-    def my_view(request):
-        # ...
-
-The permission_required decorator
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-It's a relatively common task to check whether a user has a particular
-permission. For that reason, Django provides a shortcut for that case: the
-``permission_required()`` decorator. Using this decorator, the earlier example
-can be written as::
-
-    from django.contrib.auth.decorators import permission_required
-
-    def my_view(request):
-        # ...
-    my_view = permission_required('polls.can_vote')(my_view)
-
-Note that ``permission_required()`` also takes an optional ``login_url``
-parameter. Example::
-
-    from django.contrib.auth.decorators import permission_required
-
-    def my_view(request):
-        # ...
-    my_view = permission_required('polls.can_vote', login_url='/loginpage/')(my_view)
-
-As in the ``login_required`` decorator, ``login_url`` defaults to
-``settings.LOGIN_URL``.
-
-Limiting access to generic views
---------------------------------
-
-To limit access to a `generic view`_, write a thin wrapper around the view,
-and point your URLconf to your wrapper instead of the generic view itself.
-For example::
-
-    from django.views.generic.date_based import object_detail
-
-    @login_required
-    def limited_object_detail(*args, **kwargs):
-        return object_detail(*args, **kwargs)
-
-.. _generic view: ../generic_views/
-
-Permissions
-===========
-
-Django comes with a simple permissions system. It provides a way to assign
-permissions to specific users and groups of users.
-
-It's used by the Django admin site, but you're welcome to use it in your own
-code.
-
-The Django admin site uses permissions as follows:
-
-    * Access to view the "add" form and add an object is limited to users with
-      the "add" permission for that type of object.
-    * Access to view the change list, view the "change" form and change an
-      object is limited to users with the "change" permission for that type of
-      object.
-    * Access to delete an object is limited to users with the "delete"
-      permission for that type of object.
-
-Permissions are set globally per type of object, not per specific object
-instance. For example, it's possible to say "Mary may change news stories," but
-it's not currently possible to say "Mary may change news stories, but only the
-ones she created herself" or "Mary may only change news stories that have a
-certain status, publication date or ID." The latter functionality is something
-Django developers are currently discussing.
-
-Default permissions
--------------------
-
-When ``django.contrib.auth`` is listed in your ``INSTALLED_APPS``
-setting, it will ensure that three default permissions -- add, change
-and delete -- are created for each Django model defined in one of your
-installed applications.
-
-These permissions will be created when you run ``manage.py syncdb``;
-the first time you run ``syncdb`` after adding ``django.contrib.auth``
-to ``INSTALLED_APPS``, the default permissions will be created for all
-previously-installed models, as well as for any new models being
-installed at that time. Afterward, it will create default permissions
-for new models each time you run ``manage.py syncdb``.
-
-Custom permissions
-------------------
-
-To create custom permissions for a given model object, use the ``permissions``
-`model Meta attribute`_.
-
-This example model creates three custom permissions::
-
-    class USCitizen(models.Model):
-        # ...
-        class Meta:
-            permissions = (
-                ("can_drive", "Can drive"),
-                ("can_vote", "Can vote in elections"),
-                ("can_drink", "Can drink alcohol"),
-            )
-
-The only thing this does is create those extra permissions when you run
-``syncdb``.
-
-.. _model Meta attribute: ../model-api/#meta-options
-
-API reference
--------------
-
-Just like users, permissions are implemented in a Django model that lives in
-`django/contrib/auth/models.py`_.
-
-.. _django/contrib/auth/models.py: http://code.djangoproject.com/browser/django/trunk/django/contrib/auth/models.py
-
-Fields
-~~~~~~
-
-``Permission`` objects have the following fields:
-
-    * ``name`` -- Required. 50 characters or fewer. Example: ``'Can vote'``.
-    * ``content_type`` -- Required. A reference to the ``django_content_type``
-      database table, which contains a record for each installed Django model.
-    * ``codename`` -- Required. 100 characters or fewer. Example: ``'can_vote'``.
-
-Methods
-~~~~~~~
-
-``Permission`` objects have the standard data-access methods like any other
-`Django model`_.
-
-Authentication data in templates
-================================
-
-The currently logged-in user and his/her permissions are made available in the
-`template context`_ when you use ``RequestContext``.
-
-.. admonition:: Technicality
-
-   Technically, these variables are only made available in the template context
-   if you use ``RequestContext`` *and* your ``TEMPLATE_CONTEXT_PROCESSORS``
-   setting contains ``"django.core.context_processors.auth"``, which is default.
-   For more, see the `RequestContext docs`_.
-
-   .. _RequestContext docs: ../templates_python/#subclassing-context-requestcontext
-
-Users
------
-
-The currently logged-in user, either a ``User`` instance or an``AnonymousUser``
-instance, is stored in the template variable ``{{ user }}``::
-
-    {% if user.is_authenticated %}
-        <p>Welcome, {{ user.username }}. Thanks for logging in.</p>
-    {% else %}
-        <p>Welcome, new user. Please log in.</p>
-    {% endif %}
-
-Permissions
------------
-
-The currently logged-in user's permissions are stored in the template variable
-``{{ perms }}``. This is an instance of ``django.core.context_processors.PermWrapper``,
-which is a template-friendly proxy of permissions.
-
-In the ``{{ perms }}`` object, single-attribute lookup is a proxy to
-``User.has_module_perms``. This example would display ``True`` if the logged-in
-user had any permissions in the ``foo`` app::
-
-    {{ perms.foo }}
-
-Two-level-attribute lookup is a proxy to ``User.has_perm``. This example would
-display ``True`` if the logged-in user had the permission ``foo.can_vote``::
-
-    {{ perms.foo.can_vote }}
-
-Thus, you can check permissions in template ``{% if %}`` statements::
-
-    {% if perms.foo %}
-        <p>You have permission to do something in the foo app.</p>
-        {% if perms.foo.can_vote %}
-            <p>You can vote!</p>
-        {% endif %}
-        {% if perms.foo.can_drive %}
-            <p>You can drive!</p>
-        {% endif %}
-    {% else %}
-        <p>You don't have permission to do anything in the foo app.</p>
-    {% endif %}
-
-.. _template context: ../templates_python/
-
-Groups
-======
-
-Groups are a generic way of categorizing users so you can apply permissions, or
-some other label, to those users. A user can belong to any number of groups.
-
-A user in a group automatically has the permissions granted to that group. For
-example, if the group ``Site editors`` has the permission
-``can_edit_home_page``, any user in that group will have that permission.
-
-Beyond permissions, groups are a convenient way to categorize users to give
-them some label, or extended functionality. For example, you could create a
-group ``'Special users'``, and you could write code that could, say, give them
-access to a members-only portion of your site, or send them members-only e-mail
-messages.
-
-Messages
-========
-
-The message system is a lightweight way to queue messages for given users.
-
-A message is associated with a ``User``. There's no concept of expiration or
-timestamps.
-
-Messages are used by the Django admin after successful actions. For example,
-``"The poll Foo was created successfully."`` is a message.
-
-The API is simple:
-
-    * To create a new message, use
-      ``user_obj.message_set.create(message='message_text')``.
-    * To retrieve/delete messages, use ``user_obj.get_and_delete_messages()``,
-      which returns a list of ``Message`` objects in the user's queue (if any)
-      and deletes the messages from the queue.
-
-In this example view, the system saves a message for the user after creating
-a playlist::
-
-    def create_playlist(request, songs):
-        # Create the playlist with the given songs.
-        # ...
-        request.user.message_set.create(message="Your playlist was added successfully.")
-        return render_to_response("playlists/create.html",
-            context_instance=RequestContext(request))
-
-When you use ``RequestContext``, the currently logged-in user and his/her
-messages are made available in the `template context`_ as the template variable
-``{{ messages }}``. Here's an example of template code that displays messages::
-
-    {% if messages %}
-    <ul>
-        {% for message in messages %}
-        <li>{{ message }}</li>
-        {% endfor %}
-    </ul>
-    {% endif %}
-
-Note that ``RequestContext`` calls ``get_and_delete_messages`` behind the
-scenes, so any messages will be deleted even if you don't display them.
-
-Finally, note that this messages framework only works with users in the user
-database. To send messages to anonymous users, use the `session framework`_.
-
-.. _session framework: ../sessions/
-
-Other authentication sources
-============================
-
-The authentication that comes with Django is good enough for most common cases,
-but you may have the need to hook into another authentication source -- that
-is, another source of usernames and passwords or authentication methods.
-
-For example, your company may already have an LDAP setup that stores a username
-and password for every employee. It'd be a hassle for both the network
-administrator and the users themselves if users had separate accounts in LDAP
-and the Django-based applications.
-
-So, to handle situations like this, the Django authentication system lets you
-plug in another authentication sources. You can override Django's default
-database-based scheme, or you can use the default system in tandem with other
-systems.
-
-Specifying authentication backends
-----------------------------------
-
-Behind the scenes, Django maintains a list of "authentication backends" that it
-checks for authentication. When somebody calls
-``django.contrib.auth.authenticate()`` -- as described in "How to log a user in"
-above -- Django tries authenticating across all of its authentication backends.
-If the first authentication method fails, Django tries the second one, and so
-on, until all backends have been attempted.
-
-The list of authentication backends to use is specified in the
-``AUTHENTICATION_BACKENDS`` setting. This should be a tuple of Python path
-names that point to Python classes that know how to authenticate. These classes
-can be anywhere on your Python path.
-
-By default, ``AUTHENTICATION_BACKENDS`` is set to::
-
-    ('django.contrib.auth.backends.ModelBackend',)
-
-That's the basic authentication scheme that checks the Django users database.
-
-The order of ``AUTHENTICATION_BACKENDS`` matters, so if the same username and
-password is valid in multiple backends, Django will stop processing at the
-first positive match.
-
-Writing an authentication backend
----------------------------------
-
-An authentication backend is a class that implements two methods:
-``get_user(user_id)`` and ``authenticate(**credentials)``.
-
-The ``get_user`` method takes a ``user_id`` -- which could be a username,
-database ID or whatever -- and returns a ``User`` object.
-
-The  ``authenticate`` method takes credentials as keyword arguments. Most of
-the time, it'll just look like this::
-
-    class MyBackend:
-        def authenticate(self, username=None, password=None):
-            # Check the username/password and return a User.
-
-But it could also authenticate a token, like so::
-
-    class MyBackend:
-        def authenticate(self, token=None):
-            # Check the token and return a User.
-
-Either way, ``authenticate`` should check the credentials it gets, and it
-should return a ``User`` object that matches those credentials, if the
-credentials are valid. If they're not valid, it should return ``None``.
-
-The Django admin system is tightly coupled to the Django ``User`` object
-described at the beginning of this document. For now, the best way to deal with
-this is to create a Django ``User`` object for each user that exists for your
-backend (e.g., in your LDAP directory, your external SQL database, etc.) You
-can either write a script to do this in advance, or your ``authenticate``
-method can do it the first time a user logs in.
-
-Here's an example backend that authenticates against a username and password
-variable defined in your ``settings.py`` file and creates a Django ``User``
-object the first time a user authenticates::
-
-    from django.conf import settings
-    from django.contrib.auth.models import User, check_password
-
-    class SettingsBackend:
-        """
-        Authenticate against the settings ADMIN_LOGIN and ADMIN_PASSWORD.
-
-        Use the login name, and a hash of the password. For example:
-
-        ADMIN_LOGIN = 'admin'
-        ADMIN_PASSWORD = 'sha1$4e987$afbcf42e21bd417fb71db8c66b321e9fc33051de'
-        """
-        def authenticate(self, username=None, password=None):
-            login_valid = (settings.ADMIN_LOGIN == username)
-            pwd_valid = check_password(password, settings.ADMIN_PASSWORD)
-            if login_valid and pwd_valid:
-                try:
-                    user = User.objects.get(username=username)
-                except User.DoesNotExist:
-                    # Create a new user. Note that we can set password
-                    # to anything, because it won't be checked; the password
-                    # from settings.py will.
-                    user = User(username=username, password='get from settings.py')
-                    user.is_staff = True
-                    user.is_superuser = True
-                    user.save()
-                return user
-            return None
-
-        def get_user(self, user_id):
-            try:
-                return User.objects.get(pk=user_id)
-            except User.DoesNotExist:
-                return None
-
-Handling authorization in custom backends
------------------------------------------
-
-Custom auth backends can provide their own permissions.
-
-The user model will delegate permission lookup functions
-(``get_group_permissions()``, ``get_all_permissions()``, ``has_perm()``, and
-``has_module_perms()``) to any authentication backend that implements these
-functions.
-
-The permissions given to the user will be the superset of all permissions
-returned by all backends. That is, Django grants a permission to a user that any
-one backend grants.
-
-The simple backend above could implement permissions for the magic admin fairly
-simply::
-
-    class SettingsBackend:
-
-        # ...
-
-        def has_perm(self, user_obj, perm):
-            if user_obj.username == settings.ADMIN_LOGIN:
-                return True
-            else:
-                return False
-
-This gives full permissions to the user granted access in the above example. Notice
-that the backend auth functions all take the user object as an argument, and
-they also accept the same arguments given to the associated ``User`` functions.
-
-A full authorization implementation can be found in
-``django/contrib/auth/backends.py`` _, which is the default backend and queries
-the ``auth_permission`` table most of the time.
-
-.. _django/contrib/auth/backends.py: http://code.djangoproject.com/browser/django/trunk/django/contrib/auth/backends.py

+ 22 - 9
docs/conf.py

@@ -12,35 +12,36 @@
 # serve to show the default value.
 
 import sys
+import os
 
 # If your extensions are in another directory, add it here.
-#sys.path.append('some/directory')
+sys.path.append(os.path.join(os.path.dirname(__file__), "_ext"))
 
 # General configuration
 # ---------------------
 
 # Add any Sphinx extension module names here, as strings. They can be extensions
 # coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
-#extensions = []
+extensions = ["djangodocs"]
 
 # Add any paths that contain templates here, relative to this directory.
-templates_path = []
+templates_path = ["_templates"]
 
 # The suffix of source filenames.
 source_suffix = '.txt'
 
 # The master toctree document.
-master_doc = 'index'
+master_doc = 'contents'
 
 # General substitutions.
 project = 'Django'
-copyright = '2008, Django Software Foundation'
+copyright = 'Django Software Foundation and contributors'
 
 # The default replacements for |version| and |release|, also used in various
 # other places throughout the built documents.
 #
 # The short X.Y version.
-version = 'SVN'
+version = '1.0'
 # The full version, including alpha/beta/rc tags.
 release = version
 
@@ -65,7 +66,7 @@ add_module_names = False
 show_authors = False
 
 # The name of the Pygments (syntax highlighting) style to use.
-pygments_style = 'sphinx'
+pygments_style = 'trac'
 
 
 # Options for HTML output
@@ -79,7 +80,7 @@ html_style = 'default.css'
 # Add any paths that contain custom static files (such as style sheets) here,
 # relative to this directory. They are copied after the builtin static files,
 # so a file named "default.css" will overwrite the builtin "default.css".
-html_static_path = []
+html_static_path = ["_static"]
 
 # If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
 # using the given strftime format.
@@ -89,6 +90,9 @@ html_last_updated_fmt = '%b %d, %Y'
 # typographically correct entities.
 html_use_smartypants = True
 
+# HTML translator class for the builder
+html_translator_class = "djangodocs.DjangoHTMLTranslator"
+
 # Content template for the index page.
 #html_index = ''
 
@@ -97,7 +101,7 @@ html_use_smartypants = True
 
 # Additional templates that should be rendered to pages, maps page names to
 # template names.
-#html_additional_pages = {}
+html_additional_pages = {}
 
 # If false, no module index is generated.
 #html_use_modindex = True
@@ -121,6 +125,9 @@ htmlhelp_basename = 'Djangodoc'
 # Grouping the document tree into LaTeX files. List of tuples
 # (source start file, target name, title, author, document class [howto/manual]).
 #latex_documents = []
+latex_documents = [
+  ('index', 'django.tex', 'Django Documentation', 'Django Software Foundation', 'manual'),
+]
 
 # Additional stuff for the LaTeX preamble.
 #latex_preamble = ''
@@ -130,3 +137,9 @@ htmlhelp_basename = 'Djangodoc'
 
 # If false, no module index is generated.
 #latex_use_modindex = True
+
+# For "manual" documents, if this is true, then toplevel headings are parts,
+# not chapters.
+# If this isn't set to True, the LaTex writer can only handle six levels of headers.
+latex_use_parts = True
+

+ 36 - 0
docs/contents.txt

@@ -0,0 +1,36 @@
+.. _contents:
+
+=============================
+Django documentation contents
+=============================
+
+.. toctree::
+   :maxdepth: 2
+   
+   intro/index
+   topics/index
+   howto/index
+   faq/index
+   ref/index
+   misc/index
+   glossary
+   releases/index
+   internals/index
+
+Indices, glossary and tables
+============================
+
+* :ref:`genindex`
+* :ref:`modindex`
+* :ref:`glossary`
+
+Deprecated/obsolete documentation
+=================================
+
+The following documentation covers features that have been deprecated or that
+have been replaced in newer versions of Django.
+
+.. toctree::
+   :maxdepth: 2
+   
+   obsolete/index

+ 0 - 297
docs/contenttypes.txt

@@ -1,297 +0,0 @@
-==========================
-The contenttypes framework
-==========================
-
-Django includes a "contenttypes" application that can track all of
-the models installed in your Django-powered project, providing a
-high-level, generic interface for working with your models.
-
-Overview
-========
-
-At the heart of the contenttypes application is the ``ContentType``
-model, which lives at
-``django.contrib.contenttypes.models.ContentType``. Instances of
-``ContentType`` represent and store information about the models
-installed in your project, and new instances of ``ContentType`` are
-automatically created whenever new models are installed.
-
-Instances of ``ContentType`` have methods for returning the model
-classes they represent and for querying objects from those models.
-``ContentType`` also has a `custom manager`_ that adds methods for
-working with ``ContentType`` and for obtaining instances of
-``ContentType`` for a particular model.
-
-Relations between your models and ``ContentType`` can also be used to
-enable "generic" relationships between an instance of one of your
-models and instances of any model you have installed.
-
-.. _custom manager: ../model-api/#custom-managers
-
-Installing the contenttypes framework
-=====================================
-
-The contenttypes framework is included in the default
-``INSTALLED_APPS`` list created by ``django-admin.py startproject``,
-but if you've removed it or if you manually set up your
-``INSTALLED_APPS`` list, you can enable it by adding
-``'django.contrib.contenttypes'`` to your ``INSTALLED_APPS`` setting.
-
-It's generally a good idea to have the contenttypes framework
-installed; several of Django's other bundled applications require it:
-
-    * The admin application uses it to log the history of each object
-      added or changed through the admin interface.
-
-    * Django's `authentication framework`_ uses it to tie user permissions
-      to specific models.
-
-    * Django's comments system (``django.contrib.comments``) uses it to
-      "attach" comments to any installed model.
-
-.. _authentication framework: ../authentication/
-
-The ``ContentType`` model
-=========================
-
-Each instance of ``ContentType`` has three fields which, taken
-together, uniquely describe an installed model:
-
-    ``app_label``
-        The name of the application the model is part of. This is taken from
-        the ``app_label`` attribute of the model, and includes only the *last*
-        part of the application's Python import path;
-        "django.contrib.contenttypes", for example, becomes an ``app_label``
-        of "contenttypes".
-
-    ``model``
-        The name of the model class.
-
-    ``name``
-        The human-readable name of the model. This is taken from
-        `the verbose_name attribute`_ of the model.
-
-Let's look at an example to see how this works. If you already have
-the contenttypes application installed, and then add `the sites application`_
-to your ``INSTALLED_APPS`` setting and run ``manage.py syncdb`` to install it,
-the model ``django.contrib.sites.models.Site`` will be installed into your
-database. Along with it a new instance of ``ContentType`` will be created with
-the following values:
-
-    * ``app_label`` will be set to ``'sites'`` (the last part of the Python
-      path "django.contrib.sites").
-
-    * ``model`` will be set to ``'site'``.
-
-    * ``name`` will be set to ``'site'``.
-
-.. _the verbose_name attribute: ../model-api/#verbose_name
-.. _the sites application: ../sites/
-
-Methods on ``ContentType`` instances
-====================================
-
-Each ``ContentType`` instance has methods that allow you to get from a
-``ContentType`` instance to the model it represents, or to retrieve objects
-from that model:
-
-    ``get_object_for_this_type(**kwargs)``
-        Takes a set of valid `lookup arguments`_ for the model the
-        ``ContentType`` represents, and does `a get() lookup`_ on that
-        model, returning the corresponding object.
-
-    ``model_class()``
-        Returns the model class represented by this ``ContentType``
-        instance.
-
-For example, we could look up the ``ContentType`` for the ``User`` model::
-
-    >>> from django.contrib.contenttypes.models import ContentType
-    >>> user_type = ContentType.objects.get(app_label="auth", model="user")
-    >>> user_type
-    <ContentType: user>
-
-And then use it to query for a particular ``User``, or to get access
-to the ``User`` model class::
-
-    >>> user_type.model_class()
-    <class 'django.contrib.auth.models.User'>
-    >>> user_type.get_object_for_this_type(username='Guido')
-    <User: Guido>
-
-Together, ``get_object_for_this_type`` and ``model_class`` enable two
-extremely important use cases:
-
-    1. Using these methods, you can write high-level generic code that
-       performs queries on any installed model -- instead of importing and
-       using a single specific model class, you can pass an ``app_label``
-       and ``model`` into a ``ContentType`` lookup at runtime, and then
-       work with the model class or retrieve objects from it.
-
-    2. You can relate another model to ``ContentType`` as a way of tying
-       instances of it to particular model classes, and use these methods
-       to get access to those model classes.
-
-Several of Django's bundled applications make use of the latter
-technique. For example, `the permissions system`_ in Django's
-authentication framework uses a ``Permission`` model with a foreign
-key to ``ContentType``; this lets ``Permission`` represent concepts
-like "can add blog entry" or "can delete news story".
-
-.. _lookup arguments: ../db-api/#field-lookups
-.. _a get() lookup: ../db-api/#get-kwargs
-.. _the permissions system: ../authentication/#permissions
-
-The ``ContentTypeManager``
---------------------------
-
-``ContentType`` also has a custom manager, ``ContentTypeManager``,
-which adds the following methods:
-
-    ``clear_cache()``
-        Clears an internal cache used by ``ContentType`` to keep track of which
-        models for which it has created ``ContentType`` instances. You probably
-        won't ever need to call this method yourself; Django will call it
-        automatically when it's needed.
-
-    ``get_for_model(model)``
-        Takes either a model class or an instance of a model, and returns the
-        ``ContentType`` instance representing that model.
-
-The ``get_for_model`` method is especially useful when you know you
-need to work with a ``ContentType`` but don't want to go to the
-trouble of obtaining the model's metadata to perform a manual lookup::
-
-    >>> from django.contrib.auth.models import User
-    >>> user_type = ContentType.objects.get_for_model(User)
-    >>> user_type
-    <ContentType: user>
-
-Generic relations
-=================
-
-Adding a foreign key from one of your own models to ``ContentType``
-allows your model to effectively tie itself to another model class, as
-in the example of the ``Permission`` model above. But it's possible to
-go one step further and use ``ContentType`` to enable truly generic
-(sometimes called "polymorphic") relationships between models.
-
-A simple example is a tagging system, which might look like this::
-
-    from django.db import models
-    from django.contrib.contenttypes.models import ContentType
-    from django.contrib.contenttypes import generic
-
-    class TaggedItem(models.Model):
-        tag = models.SlugField()
-        content_type = models.ForeignKey(ContentType)
-        object_id = models.PositiveIntegerField()
-        content_object = generic.GenericForeignKey('content_type', 'object_id')
-
-        def __unicode__(self):
-            return self.tag
-
-A normal ``ForeignKey`` can only "point to" one other model, which
-means that if the ``TaggedItem`` model used a ``ForeignKey`` it would have to
-choose one and only one model to store tags for. The contenttypes
-application provides a special field type --
-``django.contrib.contenttypes.generic.GenericForeignKey`` -- which
-works around this and allows the relationship to be with any
-model. There are three parts to setting up a ``GenericForeignKey``:
-
-    1. Give your model a ``ForeignKey`` to ``ContentType``.
-
-    2. Give your model a field that can store a primary-key value from the
-       models you'll be relating to. (For most models, this means an
-       ``IntegerField`` or ``PositiveIntegerField``.)
-
-       This field must be of the same type as the primary key of the models
-       that will be involved in the generic relation. For example, if you use
-       ``IntegerField``, you won't be able to form a generic relation with a
-       model that uses a ``CharField`` as a primary key.
-
-    3. Give your model a ``GenericForeignKey``, and pass it the names of
-       the two fields described above. If these fields are named
-       "content_type" and "object_id", you can omit this -- those are the
-       default field names ``GenericForeignKey`` will look for.
-
-This will enable an API similar to the one used for a normal ``ForeignKey``;
-each ``TaggedItem`` will have a ``content_object`` field that returns the
-object it's related to, and you can also assign to that field or use it when
-creating a ``TaggedItem``::
-
-    >>> from django.contrib.auth.models import User
-    >>> guido = User.objects.get(username='Guido')
-    >>> t = TaggedItem(content_object=guido, tag='bdfl')
-    >>> t.save()
-    >>> t.content_object
-    <User: Guido>
-
-Due to the way ``GenericForeignKey`` is implemeneted, you cannot use such
-fields directly with filters (``filter()`` and ``exclude()``, for example) via
-the database API. They aren't normal field objects. These examples will *not*
-work::
-
-	# This will fail
-	>>> TaggedItem.objects.filter(content_object=guido)
-	# This will also fail
-	>>> TaggedItem.objects.get(content_object=guido)
-
-Reverse generic relations
--------------------------
-
-If you know which models you'll be using most often, you can also add
-a "reverse" generic relationship to enable an additional API. For example::
-
-    class Bookmark(models.Model):
-        url = models.URLField()
-        tags = generic.GenericRelation(TaggedItem)
-
-``Bookmark`` instances will each have a ``tags`` attribute, which can
-be used to retrieve their associated ``TaggedItems``::
-
-    >>> b = Bookmark(url='http://www.djangoproject.com/')
-    >>> b.save()
-    >>> t1 = TaggedItem(content_object=b, tag='django')
-    >>> t1.save()
-    >>> t2 = TaggedItem(content_object=b, tag='python')
-    >>> t2.save()
-    >>> b.tags.all()
-    [<TaggedItem: django>, <TaggedItem: python>]
-
-If you don't add the reverse relationship, you can do the lookup manually::
-
-    >>> b = Bookmark.objects.get(url='http://www.djangoproject.com/)
-    >>> bookmark_type = ContentType.objects.get_for_model(b)
-    >>> TaggedItem.objects.filter(content_type__pk=bookmark_type.id,
-    ...                           object_id=b.id)
-    [<TaggedItem: django>, <TaggedItem: python>]
-
-Note that if you delete an object that has a ``GenericRelation``, any objects
-which have a ``GenericForeignKey`` pointing at it will be deleted as well. In
-the example above, this means that if a ``Bookmark`` object were deleted, any
-``TaggedItem`` objects pointing at it would be deleted at the same time.
-
-Generic relations in forms and admin
-------------------------------------
-
-``django.contrib.contenttypes.generic`` provides both a ``GenericInlineFormSet``
-and ``GenericInlineModelAdmin``. This enables the use of generic relations in
-forms and the admin. See the `model formset`_ and `admin`_ documentation for
-more information.
-
-``GenericInlineModelAdmin`` options
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The ``GenericInlineModelAdmin`` class inherits all properties from an
-``InlineModelAdmin`` class. However, it adds a couple of its own for working
-with the generic relation:
-
-    * ``ct_field`` - The name of the ``ContentType`` foreign key field on the
-      model. Defaults to ``content_type``.
-    
-    * ``ct_fk_field`` - The name of the integer field that represents the ID
-      of the related object. Defaults to ``object_id``.
-
-.. _model formset: ../modelforms/
-.. _admin: ../admin/

+ 0 - 2421
docs/db-api.txt

@@ -1,2421 +0,0 @@
-======================
-Database API reference
-======================
-
-Once you've created your `data models`_, Django automatically gives you a
-database-abstraction API that lets you create, retrieve, update and delete
-objects. This document explains that API.
-
-.. _`data models`: ../model-api/
-
-Throughout this reference, we'll refer to the following models, which comprise
-a weblog application::
-
-    class Blog(models.Model):
-        name = models.CharField(max_length=100)
-        tagline = models.TextField()
-
-        def __unicode__(self):
-            return self.name
-
-    class Author(models.Model):
-        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(max_length=255)
-        body_text = models.TextField()
-        pub_date = models.DateTimeField()
-        authors = models.ManyToManyField(Author)
-
-        def __unicode__(self):
-            return self.headline
-
-Creating objects
-================
-
-To represent database-table data in Python objects, Django uses an intuitive
-system: A model class represents a database table, and an instance of that
-class represents a particular record in the database table.
-
-To create an object, instantiate it using keyword arguments to the model class,
-then call ``save()`` to save it to the database.
-
-You import the model class from wherever it lives on the Python path, as you
-may expect. (We point this out here because previous Django versions required
-funky model importing.)
-
-Assuming models live in a file ``mysite/blog/models.py``, here's an example::
-
-    from mysite.blog.models import Blog
-    b = Blog(name='Beatles Blog', tagline='All the latest Beatles news.')
-    b.save()
-
-This performs an ``INSERT`` SQL statement behind the scenes. Django doesn't hit
-the database until you explicitly call ``save()``.
-
-The ``save()`` method has no return value.
-
-To create an object and save it all in one step see the `create`__ method.
-
-__ `create(**kwargs)`_
-
-Auto-incrementing primary keys
-------------------------------
-
-If a model has an ``AutoField`` -- an auto-incrementing primary key -- then
-that auto-incremented value will be calculated and saved as an attribute on
-your object the first time you call ``save()``.
-
-Example::
-
-    b2 = Blog(name='Cheddar Talk', tagline='Thoughts on cheese.')
-    b2.id     # Returns None, because b doesn't have an ID yet.
-    b2.save()
-    b2.id     # Returns the ID of your new object.
-
-There's no way to tell what the value of an ID will be before you call
-``save()``, because that value is calculated by your database, not by Django.
-
-(For convenience, each model has an ``AutoField`` named ``id`` by default
-unless you explicitly specify ``primary_key=True`` on a field. See the
-`AutoField documentation`_.)
-
-.. _AutoField documentation: ../model-api/#autofield
-
-Explicitly specifying auto-primary-key values
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-If a model has an ``AutoField`` but you want to define a new object's ID
-explicitly when saving, just define it explicitly before saving, rather than
-relying on the auto-assignment of the ID.
-
-Example::
-
-    b3 = Blog(id=3, name='Cheddar Talk', tagline='Thoughts on cheese.')
-    b3.id     # Returns 3.
-    b3.save()
-    b3.id     # Returns 3.
-
-If you assign auto-primary-key values manually, make sure not to use an
-already-existing primary-key value! If you create a new object with an explicit
-primary-key value that already exists in the database, Django will assume
-you're changing the existing record rather than creating a new one.
-
-Given the above ``'Cheddar Talk'`` blog example, this example would override
-the previous record in the database::
-
-    b4 = Blog(id=3, name='Not Cheddar', tagline='Anything but cheese.')
-    b4.save()  # Overrides the previous blog with ID=3!
-
-See `How Django knows to UPDATE vs. INSERT`_, below, for the reason this
-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.)
-
-Saving changes to objects
-=========================
-
-To save changes to an object that's already in the database, use ``save()``.
-
-Given a ``Blog`` instance ``b5`` that has already been saved to the database,
-this example changes its name and updates its record in the database::
-
-    b5.name = 'New name'
-    b5.save()
-
-This performs an ``UPDATE`` SQL statement behind the scenes. Django doesn't hit
-the database until you explicitly call ``save()``.
-
-The ``save()`` method has no return value.
-
-Saving ForeignKey and ManyToManyField fields
---------------------------------------------
-
-Updating ``ForeignKey`` fields works exactly the same way as saving a normal
-field; simply assign an object of the right type to the field in question::
-
-    cheese_blog = Blog.objects.get(name="Cheddar Talk")
-    entry.blog = cheese_blog
-    entry.save()
-
-Updating a ``ManyToManyField`` works a little differently; use the ``add()``
-method on the field to add a record to the relation::
-
-    joe = Author.objects.create(name="Joe")
-    entry.authors.add(joe)
-
-Django will complain if you try to assign or add an object of the wrong type.
-
-How Django knows to UPDATE vs. INSERT
--------------------------------------
-
-You may have noticed Django database objects use the same ``save()`` method
-for creating and changing objects. Django abstracts the need to use ``INSERT``
-or ``UPDATE`` SQL statements. Specifically, when you call ``save()``, Django
-follows this algorithm:
-
-    * If the object's primary key attribute is set to a value that evaluates to
-      ``True`` (i.e., a value other than ``None`` or the empty string), Django
-      executes a ``SELECT`` query to determine whether a record with the given
-      primary key already exists.
-    * If the record with the given primary key does already exist, Django
-      executes an ``UPDATE`` query.
-    * If the object's primary key attribute is *not* set, or if it's set but a
-      record doesn't exist, Django executes an ``INSERT``.
-
-The one gotcha here is that you should be careful not to specify a primary-key
-value explicitly when saving new objects, if you cannot guarantee the
-primary-key value is unused. For more on this nuance, see `Explicitly
-specifying auto-primary-key values`_ above and `Forcing an INSERT or UPDATE`_
-below.
-
-Forcing an INSERT or UPDATE
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-**New in Django development version**
-
-In some rare circumstances, it's necesary to be able to force the ``save()``
-method to perform an SQL ``INSERT`` and not fall back to doing an ``UPDATE``.
-Or vice-versa: update, if possible, but not insert a new row. In these cases
-you can pass the ``force_insert=True`` or ``force_update=True`` parameters to
-the ``save()`` method. Passing both parameters is an error, since you cannot
-both insert *and* update at the same time.
-
-It should be very rare that you'll need to use these parameters. Django will
-almost always do the right thing and trying to override that will lead to
-errors that are difficult to track down. This feature is for advanced use
-only.
-
-Retrieving objects
-==================
-
-To retrieve objects from your database, you construct a ``QuerySet`` via a
-``Manager`` on your model class.
-
-A ``QuerySet`` represents a collection of objects from your database. It can
-have zero, one or many *filters* -- criteria that narrow down the collection
-based on given parameters. In SQL terms, a ``QuerySet`` equates to a ``SELECT``
-statement, and a filter is a limiting clause such as ``WHERE`` or ``LIMIT``.
-
-You get a ``QuerySet`` by using your model's ``Manager``. Each model has at
-least one ``Manager``, and it's called ``objects`` by default. Access it
-directly via the model class, like so::
-
-    Blog.objects  # <django.db.models.manager.Manager object at ...>
-    b = Blog(name='Foo', tagline='Bar')
-    b.objects     # AttributeError: "Manager isn't accessible via Blog instances."
-
-(``Managers`` are accessible only via model classes, rather than from model
-instances, to enforce a separation between "table-level" operations and
-"record-level" operations.)
-
-The ``Manager`` is the main source of ``QuerySets`` for a model. It acts as a
-"root" ``QuerySet`` that describes all objects in the model's database table.
-For example, ``Blog.objects`` is the initial ``QuerySet`` that contains all
-``Blog`` objects in the database.
-
-Retrieving all objects
-----------------------
-
-The simplest way to retrieve objects from a table is to get all of them.
-To do this, use the ``all()`` method on a ``Manager``.
-
-Example::
-
-    all_entries = Entry.objects.all()
-
-The ``all()`` method returns a ``QuerySet`` of all the objects in the database.
-
-(If ``Entry.objects`` is a ``QuerySet``, why can't we just do ``Entry.objects``?
-That's because ``Entry.objects``, the root ``QuerySet``, is a special case
-that cannot be evaluated. The ``all()`` method returns a ``QuerySet`` that
-*can* be evaluated.)
-
-Filtering objects
------------------
-
-The root ``QuerySet`` provided by the ``Manager`` describes all objects in the
-database table. Usually, though, you'll need to select only a subset of the
-complete set of objects.
-
-To create such a subset, you refine the initial ``QuerySet``, adding filter
-conditions. The two most common ways to refine a ``QuerySet`` are:
-
-``filter(**kwargs)``
-    Returns a new ``QuerySet`` containing objects that match the given lookup
-    parameters.
-
-``exclude(**kwargs)``
-    Returns a new ``QuerySet`` containing objects that do *not* match the given
-    lookup parameters.
-
-The lookup parameters (``**kwargs`` in the above function definitions) should
-be in the format described in `Field lookups`_ below.
-
-For example, to get a ``QuerySet`` of blog entries from the year 2006, use
-``filter()`` like so::
-
-    Entry.objects.filter(pub_date__year=2006)
-
-(Note we don't have to add an ``all()`` -- ``Entry.objects.all().filter(...)``.
-That would still work, but you only need ``all()`` when you want all objects
-from the root ``QuerySet``.)
-
-Chaining filters
-~~~~~~~~~~~~~~~~
-
-The result of refining a ``QuerySet`` is itself a ``QuerySet``, so it's
-possible to chain refinements together. For example::
-
-    Entry.objects.filter(
-        headline__startswith='What').exclude(
-            pub_date__gte=datetime.now()).filter(
-                pub_date__gte=datetime(2005, 1, 1))
-
-...takes the initial ``QuerySet`` of all entries in the database, adds a
-filter, then an exclusion, then another filter. The final result is a
-``QuerySet`` containing all entries with a headline that starts with "What",
-that were published between January 1, 2005, and the current day.
-
-Filtered QuerySets are unique
------------------------------
-
-Each time you refine a ``QuerySet``, you get a brand-new ``QuerySet`` that is
-in no way bound to the previous ``QuerySet``. Each refinement creates a
-separate and distinct ``QuerySet`` that can be stored, used and reused.
-
-Example::
-
-    q1 = Entry.objects.filter(headline__startswith="What")
-    q2 = q1.exclude(pub_date__gte=datetime.now())
-    q3 = q1.filter(pub_date__gte=datetime.now())
-
-These three ``QuerySets`` are separate. The first is a base ``QuerySet``
-containing all entries that contain a headline starting with "What". The second
-is a subset of the first, with an additional criteria that excludes records
-whose ``pub_date`` is greater than now. The third is a subset of the first,
-with an additional criteria that selects only the records whose ``pub_date`` is
-greater than now. The initial ``QuerySet`` (``q1``) is unaffected by the
-refinement process.
-
-QuerySets are lazy
-------------------
-
-``QuerySets`` are lazy -- the act of creating a ``QuerySet`` doesn't involve
-any database activity. You can stack filters together all day long, and Django
-won't actually run the query until the ``QuerySet`` is *evaluated*.
-
-When QuerySets are evaluated
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-You can evaluate a ``QuerySet`` in the following ways:
-
-    * **Iteration.** A ``QuerySet`` is iterable, and it executes its database
-      query the first time you iterate over it. For example, this will print
-      the headline of all entries in the database::
-
-          for e in Entry.objects.all():
-              print e.headline
-
-    * **Slicing.** As explained in `Limiting QuerySets`_ below, a ``QuerySet``
-      can be sliced, using Python's array-slicing syntax. Usually slicing a
-      ``QuerySet`` returns another (unevaluated )``QuerySet``, but Django will
-      execute the database query if you use the "step" parameter of slice
-      syntax.
-
-    * **repr().** A ``QuerySet`` is evaluated when you call ``repr()`` on it.
-      This is for convenience in the Python interactive interpreter, so you can
-      immediately see your results when using the API interactively.
-
-    * **len().** A ``QuerySet`` is evaluated when you call ``len()`` on it.
-      This, as you might expect, returns the length of the result list.
-
-      Note: *Don't* use ``len()`` on ``QuerySet``\s if all you want to do is
-      determine the number of records in the set. It's much more efficient to
-      handle a count at the database level, using SQL's ``SELECT COUNT(*)``,
-      and Django provides a ``count()`` method for precisely this reason. See
-      ``count()`` below.
-
-    * **list().** Force evaluation of a ``QuerySet`` by calling ``list()`` on
-      it. For example::
-
-          entry_list = list(Entry.objects.all())
-
-      Be warned, though, that this could have a large memory overhead, because
-      Django will load each element of the list into memory. In contrast,
-      iterating over a ``QuerySet`` will take advantage of your database to
-      load data and instantiate objects only as you need them.
-
-
-Pickling QuerySets
-~~~~~~~~~~~~~~~~~~
-
-If you pickle_ a ``QuerySet``, this will also force all the results to be
-loaded into memory prior to pickling. This is because pickling is usually used
-as a precursor to caching and when the cached ``QuerySet`` is reloaded, you want
-the results to already be present. This means that when you unpickle a
-``QuerySet``, it contains the results at the moment it was pickled, rather
-than the results that are currently in the database.
-
-If you only want to pickle the necessary information to recreate the
-``Queryset`` from the database at a later time, pickle the ``query`` attribute
-of the ``QuerySet``. You can then recreate the original ``QuerySet`` (without
-any results loaded) using some code like this::
-
-    >>> import pickle
-    >>> query = pickle.loads(s)     # Assuming 's' is the pickled string.
-    >>> qs = MyModel.objects.all()
-    >>> qs.query = query            # Restore the original 'query'.
-
-.. _pickle: http://docs.python.org/lib/module-pickle.html
-
-Limiting QuerySets
-------------------
-
-Use Python's array-slicing syntax to limit your ``QuerySet`` to a certain
-number of results. This is the equivalent of SQL's ``LIMIT`` and ``OFFSET``
-clauses.
-
-For example, this returns the first 5 objects (``LIMIT 5``)::
-
-    Entry.objects.all()[:5]
-
-This returns the sixth through tenth objects (``OFFSET 5 LIMIT 5``)::
-
-    Entry.objects.all()[5:10]
-
-You can also slice from the item ''N'' to the end of the queryset. For
-example, to return everything from the sixth item onwards::
-
-    Entry.objects.all()[5:]
-
-How this last example is implemented in SQL varies depending upon the database
-used, but it is supported in all cases.
-
-Generally, slicing a ``QuerySet`` returns a new ``QuerySet`` -- it doesn't
-evaluate the query. An exception is if you use the "step" parameter of Python
-slice syntax. For example, this would actually execute the query in order to
-return a list of every *second* object of the first 10::
-
-    Entry.objects.all()[:10:2]
-
-To retrieve a *single* object rather than a list
-(e.g. ``SELECT foo FROM bar LIMIT 1``), use a simple index instead of a
-slice. For example, this returns the first ``Entry`` in the database, after
-ordering entries alphabetically by headline::
-
-    Entry.objects.order_by('headline')[0]
-
-This is roughly equivalent to::
-
-    Entry.objects.order_by('headline')[0:1].get()
-
-Note, however, that the first of these will raise ``IndexError`` while the
-second will raise ``DoesNotExist`` if no objects match the given criteria.
-
-Combining QuerySets
--------------------
-
-If you have two ``QuerySet`` instances that act on the same model, you can
-combine them using ``&`` and ``|`` to get the items that are in both result
-sets or in either results set, respectively. For example::
-
-    Entry.objects.filter(pubdate__gte=date1) & \
-            Entry.objects.filter(headline__startswith="What")
-
-will combine the two queries into a single SQL query. Of course, in this case
-you could have achieved the same result using multiple filters on the same
-``QuerySet``, but sometimes the ability to combine individual ``QuerySet``
-instance is useful.
-
-Be careful, if you are using ``extra()`` to add custom handling to your
-``QuerySet`` however. All the ``extra()`` components are merged and the result
-may or may not make sense. If you are using custom SQL fragments in your
-``extra()`` calls, Django will not inspect these fragments to see if they need
-to be rewritten because of changes in the merged query. So test the effects
-carefully. Also realize that if you are combining two ``QuerySets`` with
-``|``, you cannot use ``extra(select=...)`` or ``extra(where=...)`` on *both*
-``QuerySets``. You can only use those calls on one or the other (Django will
-raise a ``ValueError`` if you try to use this incorrectly).
-
-QuerySet methods that return new QuerySets
-------------------------------------------
-
-Django provides a range of ``QuerySet`` refinement methods that modify either
-the types of results returned by the ``QuerySet`` or the way its SQL query is
-executed.
-
-``filter(**kwargs)``
-~~~~~~~~~~~~~~~~~~~~
-
-Returns a new ``QuerySet`` containing objects that match the given lookup
-parameters.
-
-The lookup parameters (``**kwargs``) should be in the format described in
-`Field lookups`_ below. Multiple parameters are joined via ``AND`` in the
-underlying SQL statement.
-
-``exclude(**kwargs)``
-~~~~~~~~~~~~~~~~~~~~~
-
-Returns a new ``QuerySet`` containing objects that do *not* match the given
-lookup parameters.
-
-The lookup parameters (``**kwargs``) should be in the format described in
-`Field lookups`_ below. Multiple parameters are joined via ``AND`` in the
-underlying SQL statement, and the whole thing is enclosed in a ``NOT()``.
-
-This example excludes all entries whose ``pub_date`` is later than 2005-1-3
-AND whose ``headline`` is "Hello"::
-
-    Entry.objects.exclude(pub_date__gt=datetime.date(2005, 1, 3), headline='Hello')
-
-In SQL terms, that evaluates to::
-
-    SELECT ...
-    WHERE NOT (pub_date > '2005-1-3' AND headline = 'Hello')
-
-This example excludes all entries whose ``pub_date`` is later than 2005-1-3
-OR whose headline is "Hello"::
-
-    Entry.objects.exclude(pub_date__gt=datetime.date(2005, 1, 3)).exclude(headline='Hello')
-
-In SQL terms, that evaluates to::
-
-    SELECT ...
-    WHERE NOT pub_date > '2005-1-3'
-    AND NOT headline = 'Hello'
-
-Note the second example is more restrictive.
-
-``order_by(*fields)``
-~~~~~~~~~~~~~~~~~~~~~
-
-By default, results returned by a ``QuerySet`` are ordered by the ordering
-tuple given by the ``ordering`` option in the model's ``Meta``. You can
-override this on a per-``QuerySet`` basis by using the ``order_by`` method.
-
-Example::
-
-    Entry.objects.filter(pub_date__year=2005).order_by('-pub_date', 'headline')
-
-The result above will be ordered by ``pub_date`` descending, then by
-``headline`` ascending. The negative sign in front of ``"-pub_date"`` indicates
-*descending* order. Ascending order is implied. To order randomly, use ``"?"``,
-like so::
-
-    Entry.objects.order_by('?')
-
-Note: ``order_by('?')`` queries may be expensive and slow, depending on the
-database backend you're using.
-
-To order by a field in a different model, use the same syntax as when you are
-querying across model relations. That is, the name of the field, followed by a
-double underscore (``__``), followed by the name of the field in the new model,
-and so on for as many models as you want to join. For example::
-
-    Entry.objects.order_by('blog__name', 'headline')
-
-If you try to order by a field that is a relation to another model, Django will
-use the default ordering on the related model (or order by the related model's
-primary key if there is no ``Meta.ordering`` specified. For example::
-
-    Entry.objects.order_by('blog')
-
-...is identical to::
-
-    Entry.objects.order_by('blog__id')
-
-...since the ``Blog`` model has no default ordering specified.
-
-Be cautious when ordering by fields in related models if you are also using
-``distinct()``. See the note in the `distinct()`_ section for an explanation
-of how related model ordering can change the expected results.
-
-It is permissible to specify a multi-valued field to order the results by (for
-example, a ``ManyToMany`` field). Normally this won't be a sensible thing to
-do and it's really an advanced usage feature. However, if you know that your
-queryset's filtering or available data implies that there will only be one
-ordering piece of data for each of the main items you are selecting, the
-ordering may well be exactly what you want to do. Use ordering on multi-valued
-fields with care and make sure the results are what you expect.
-
-**New in Django development version:** If you don't want any ordering to be
-applied to a query, not even the default ordering, call ``order_by()`` with no
-parameters.
-
-**New in Django development version:** The syntax for ordering across related
-models has changed. See the `Django 0.96 documentation`_ for the old behavior.
-
-.. _Django 0.96 documentation: http://www.djangoproject.com/documentation/0.96/model-api/#floatfield
-
-There's no way to specify whether ordering should be case sensitive. With
-respect to case-sensitivity, Django will order results however your database
-backend normally orders them.
-
-``reverse()``
-~~~~~~~~~~~~~
-
-**New in Django development version**
-
-Use the ``reverse()`` method to reverse the order in which a queryset's
-elements are returned. Calling ``reverse()`` a second time restores the
-ordering back to the normal direction.
-
-To retrieve the ''last'' five items in a queryset, you could do this::
-
-    my_queryset.reverse()[:5]
-
-Note that this is not quite the same as slicing from the end of a sequence in
-Python. The above example will return the last item first, then the
-penultimate item and so on. If we had a Python sequence and looked at
-``seq[:-5]``, we would see the fifth-last item first. Django doesn't support
-that mode of access (slicing from the end), because it's not possible to do it
-efficiently in SQL.
-
-Also, note that ``reverse()`` should generally only be called on a
-``QuerySet`` which has a defined ordering (e.g., when querying against
-a model which defines a default ordering, or when using
-``order_by()``). If no such ordering is defined for a given
-``QuerySet``, calling ``reverse()`` on it has no real effect (the
-ordering was undefined prior to calling ``reverse()``, and will remain
-undefined afterward).
-
-
-``distinct()``
-~~~~~~~~~~~~~~
-
-Returns a new ``QuerySet`` that uses ``SELECT DISTINCT`` in its SQL query. This
-eliminates duplicate rows from the query results.
-
-By default, a ``QuerySet`` will not eliminate duplicate rows. In practice, this
-is rarely a problem, because simple queries such as ``Blog.objects.all()``
-don't introduce the possibility of duplicate result rows. However, if your
-query spans multiple tables, it's possible to get duplicate results when a
-``QuerySet`` is evaluated. That's when you'd use ``distinct()``.
-
-.. note::
-    Any fields used in an ``order_by()`` call are included in the SQL
-    ``SELECT`` columns. This can sometimes lead to unexpected results when
-    used in conjunction with ``distinct()``. If you order by fields from a
-    related model, those fields will be added to the selected columns and they
-    may make otherwise duplicate rows appear to be distinct. Since the extra
-    columns don't appear in the returned results (they are only there to
-    support ordering), it sometimes looks like non-distinct results are being
-    returned.
-
-    Similarly, if you use a ``values()`` query to restrict the columns
-    selected, the columns used in any ``order_by()`` (or default model
-    ordering) will still be involved and may affect uniqueness of the results.
-
-    The moral here is that if you are using ``distinct()`` be careful about
-    ordering by related models. Similarly, when using ``distinct()`` and
-    ``values()`` together, be careful when ordering by fields not in the
-    ``values()`` call.
-
-``values(*fields)``
-~~~~~~~~~~~~~~~~~~~
-
-Returns a ``ValuesQuerySet`` -- a ``QuerySet`` that evaluates to a list of
-dictionaries instead of model-instance objects.
-
-Each of those dictionaries represents an object, with the keys corresponding to
-the attribute names of model objects.
-
-This example compares the dictionaries of ``values()`` with the normal model
-objects::
-
-    # This list contains a Blog object.
-    >>> Blog.objects.filter(name__startswith='Beatles')
-    [Beatles Blog]
-
-    # This list contains a dictionary.
-    >>> Blog.objects.filter(name__startswith='Beatles').values()
-    [{'id': 1, 'name': 'Beatles Blog', 'tagline': 'All the latest Beatles news.'}]
-
-``values()`` takes optional positional arguments, ``*fields``, which specify
-field names to which the ``SELECT`` should be limited. If you specify the
-fields, each dictionary will contain only the field keys/values for the fields
-you specify. If you don't specify the fields, each dictionary will contain a
-key and value for every field in the database table.
-
-Example::
-
-    >>> Blog.objects.values()
-    [{'id': 1, 'name': 'Beatles Blog', 'tagline': 'All the latest Beatles news.'}],
-    >>> Blog.objects.values('id', 'name')
-    [{'id': 1, 'name': 'Beatles Blog'}]
-
-You can also retrieve values from across ``ForeignKey`` relations by using
-double underscores to separate the field names, just as when calling the
-``filter()`` command. For example::
-
-    >>> Entry.objects.values('blog__name').distinct()
-    [{'name': 'Beatles Blog'}]
-
-A couple of subtleties that are worth mentioning:
-
-    * The ``values()`` method does not return anything for ``ManyToManyField``
-      attributes and will raise an error if you try to pass in this type of
-      field to it.
-    * If you have a field called ``foo`` that is a ``ForeignKey``, the default
-      ``values()`` call will return a dictionary key called ``foo_id``, since
-      this is the name of the hidden model attribute that stores the actual
-      value (the ``foo`` attribute refers to the related model). When you are
-      calling ``values()`` and passing in field names, you can pass in either
-      ``foo`` or ``foo_id`` and you will get back the same thing (the
-      dictionary key will match the field name you passed in).
-
-      For example::
-
-        >>> Entry.objects.values()
-        [{'blog_id: 1, 'headline': u'First Entry', ...}, ...]
-
-        >>> Entry.objects.values('blog')
-        [{'blog': 1}, ...]
-
-        >>> Entry.objects.values('blog_id')
-        [{'blog_id': 1}, ...]
-    * When using ``values()`` together with ``distinct()``, be aware that
-      ordering can affect the results. See the note in the `distinct()`_
-      section, above, for details.
-
-**New in Django development version:** Previously, it was not possible to pass
-``blog_id`` to ``values()`` in the above example, only ``blog``.
-
-A ``ValuesQuerySet`` is useful when you know you're only going to need values
-from a small number of the available fields and you won't need the
-functionality of a model instance object. It's more efficient to select only
-the fields you need to use.
-
-Finally, note a ``ValuesQuerySet`` is a subclass of ``QuerySet``, so it has all
-methods of ``QuerySet``. You can call ``filter()`` on it, or ``order_by()``, or
-whatever. Yes, that means these two calls are identical::
-
-    Blog.objects.values().order_by('id')
-    Blog.objects.order_by('id').values()
-
-The people who made Django prefer to put all the SQL-affecting methods first,
-followed (optionally) by any output-affecting methods (such as ``values()``),
-but it doesn't really matter. This is your chance to really flaunt your
-individualism.
-
-``values_list(*fields)``
-~~~~~~~~~~~~~~~~~~~~~~~~
-
-**New in Django development version**
-
-This is similar to ``values()`` except that instead of returning a list of
-dictionaries, it returns a list of tuples. Each tuple contains the value from
-the respective field passed into the ``values_list()`` call -- so the first
-item is the first field, etc. For example::
-
-    >>> Entry.objects.values_list('id', 'headline')
-    [(1, u'First entry'), ...]
-
-If you only pass in a single field, you can also pass in the ``flat``
-parameter. If ``True``, this will mean the returned results are single values,
-rather than one-tuples. An example should make the difference clearer::
-
-    >>> Entry.objects.values_list('id').order_by('id')
-    [(1,), (2,), (3,), ...]
-
-    >>> Entry.objects.values_list('id', flat=True).order_by('id')
-    [1, 2, 3, ...]
-
-It is an error to pass in ``flat`` when there is more than one field.
-
-If you don't pass any values to ``values_list()``, it will return all the
-fields in the model, in the order they were declared.
-
-``dates(field, kind, order='ASC')``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Returns a ``DateQuerySet`` -- a ``QuerySet`` that evaluates to a list of
-``datetime.datetime`` objects representing all available dates of a particular
-kind within the contents of the ``QuerySet``.
-
-``field`` should be the name of a ``DateField`` or ``DateTimeField`` of your
-model.
-
-``kind`` should be either ``"year"``, ``"month"`` or ``"day"``. Each
-``datetime.datetime`` object in the result list is "truncated" to the given
-``type``.
-
-    * ``"year"`` returns a list of all distinct year values for the field.
-    * ``"month"`` returns a list of all distinct year/month values for the field.
-    * ``"day"`` returns a list of all distinct year/month/day values for the field.
-
-``order``, which defaults to ``'ASC'``, should be either ``'ASC'`` or
-``'DESC'``. This specifies how to order the results.
-
-Examples::
-
-    >>> Entry.objects.dates('pub_date', 'year')
-    [datetime.datetime(2005, 1, 1)]
-    >>> Entry.objects.dates('pub_date', 'month')
-    [datetime.datetime(2005, 2, 1), datetime.datetime(2005, 3, 1)]
-    >>> Entry.objects.dates('pub_date', 'day')
-    [datetime.datetime(2005, 2, 20), datetime.datetime(2005, 3, 20)]
-    >>> Entry.objects.dates('pub_date', 'day', order='DESC')
-    [datetime.datetime(2005, 3, 20), datetime.datetime(2005, 2, 20)]
-    >>> Entry.objects.filter(headline__contains='Lennon').dates('pub_date', 'day')
-    [datetime.datetime(2005, 3, 20)]
-
-``none()``
-~~~~~~~~~~
-
-**New in Django development version**
-
-Returns an ``EmptyQuerySet`` -- a ``QuerySet`` that always evaluates to
-an empty list. This can be used in cases where you know that you should
-return an empty result set and your caller is expecting a ``QuerySet``
-object (instead of returning an empty list, for example.)
-
-Examples::
-
-    >>> Entry.objects.none()
-    []
-
-``all()``
-~~~~~~~~~~
-
-**New in Django development version**
-
-Returns a ''copy'' of the current ``QuerySet`` (or ``QuerySet`` subclass you
-pass in). This can be useful in some situations where you might want to pass
-in either a model manager or a ``QuerySet`` and do further filtering on the
-result. You can safely call ``all()`` on either object and then you'll
-definitely have a ``QuerySet`` to work with.
-
-``select_related()``
-~~~~~~~~~~~~~~~~~~~~
-
-Returns a ``QuerySet`` that will automatically "follow" foreign-key
-relationships, selecting that additional related-object data when it executes
-its query. This is a performance booster which results in (sometimes much)
-larger queries but means later use of foreign-key relationships won't require
-database queries.
-
-The following examples illustrate the difference between plain lookups and
-``select_related()`` lookups. Here's standard lookup::
-
-    # Hits the database.
-    e = Entry.objects.get(id=5)
-
-    # Hits the database again to get the related Blog object.
-    b = e.blog
-
-And here's ``select_related`` lookup::
-
-    # Hits the database.
-    e = Entry.objects.select_related().get(id=5)
-
-    # Doesn't hit the database, because e.blog has been prepopulated
-    # in the previous query.
-    b = e.blog
-
-``select_related()`` follows foreign keys as far as possible. If you have the
-following models::
-
-    class City(models.Model):
-        # ...
-
-    class Person(models.Model):
-        # ...
-        hometown = models.ForeignKey(City)
-
-    class Book(models.Model):
-        # ...
-        author = models.ForeignKey(Person)
-
-...then a call to ``Book.objects.select_related().get(id=4)`` will cache the
-related ``Person`` *and* the related ``City``::
-
-    b = Book.objects.select_related().get(id=4)
-    p = b.author         # Doesn't hit the database.
-    c = p.hometown       # Doesn't hit the database.
-
-    b = Book.objects.get(id=4) # No select_related() in this example.
-    p = b.author         # Hits the database.
-    c = p.hometown       # Hits the database.
-
-Note that, by default, ``select_related()`` does not follow foreign keys that
-have ``null=True``.
-
-Usually, using ``select_related()`` can vastly improve performance because your
-app can avoid many database calls. However, in situations with deeply nested
-sets of relationships ``select_related()`` can sometimes end up following "too
-many" relations, and can generate queries so large that they end up being slow.
-
-In these situations, you can use the ``depth`` argument to ``select_related()``
-to control how many "levels" of relations ``select_related()`` will actually
-follow::
-
-    b = Book.objects.select_related(depth=1).get(id=4)
-    p = b.author         # Doesn't hit the database.
-    c = p.hometown       # Requires a database call.
-
-The ``depth`` argument is new in the Django development version.
-
-**New in Django development version:** Sometimes you only need to access
-specific models that are related to your root model, not all of the related
-models. In these cases, you can pass the related field names to
-``select_related()`` and it will only follow those relations. You can even do
-this for models that are more than one relation away by separating the field
-names with double underscores, just as for filters. For example, if we have
-this model::
-
-    class Room(models.Model):
-        # ...
-        building = models.ForeignKey(...)
-
-    class Group(models.Model):
-        # ...
-        teacher = models.ForeignKey(...)
-        room = models.ForeignKey(Room)
-        subject = models.ForeignKey(...)
-
-...and we only needed to work with the ``room`` and ``subject`` attributes, we
-could write this::
-
-    g = Group.objects.select_related('room', 'subject')
-
-This is also valid::
-
-    g = Group.objects.select_related('room__building', 'subject')
-
-...and would also pull in the ``building`` relation.
-
-You can only refer to ``ForeignKey`` relations in the list of fields passed to
-``select_related``. You *can* refer to foreign keys that have ``null=True``
-(unlike the default ``select_related()`` call). It's an error to use both a
-list of fields and the ``depth`` parameter in the same ``select_related()``
-call, since they are conflicting options.
-
-``extra(select=None, where=None, params=None, tables=None, order_by=None, select_params=None)``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Sometimes, the Django query syntax by itself can't easily express a complex
-``WHERE`` clause. For these edge cases, Django provides the ``extra()``
-``QuerySet`` modifier -- a hook for injecting specific clauses into the SQL
-generated by a ``QuerySet``.
-
-By definition, these extra lookups may not be portable to different database
-engines (because you're explicitly writing SQL code) and violate the DRY
-principle, so you should avoid them if possible.
-
-Specify one or more of ``params``, ``select``, ``where`` or ``tables``. None
-of the arguments is required, but you should use at least one of them.
-
-``select``
-    The ``select`` argument lets you put extra fields in the ``SELECT`` clause.
-    It should be a dictionary mapping attribute names to SQL clauses to use to
-    calculate that attribute.
-
-    Example::
-
-        Entry.objects.extra(select={'is_recent': "pub_date > '2006-01-01'"})
-
-    As a result, each ``Entry`` object will have an extra attribute,
-    ``is_recent``, a boolean representing whether the entry's ``pub_date`` is
-    greater than Jan. 1, 2006.
-
-    Django inserts the given SQL snippet directly into the ``SELECT``
-    statement, so the resulting SQL of the above example would be::
-
-        SELECT blog_entry.*, (pub_date > '2006-01-01')
-        FROM blog_entry;
-
-
-    The next example is more advanced; it does a subquery to give each
-    resulting ``Blog`` object an ``entry_count`` attribute, an integer count
-    of associated ``Entry`` objects::
-
-        Blog.objects.extra(
-            select={
-                'entry_count': 'SELECT COUNT(*) FROM blog_entry WHERE blog_entry.blog_id = blog_blog.id'
-            },
-        )
-
-    (In this particular case, we're exploiting the fact that the query will
-    already contain the ``blog_blog`` table in its ``FROM`` clause.)
-
-    The resulting SQL of the above example would be::
-
-        SELECT blog_blog.*, (SELECT COUNT(*) FROM blog_entry WHERE blog_entry.blog_id = blog_blog.id)
-        FROM blog_blog;
-
-    Note that the parenthesis required by most database engines around
-    subqueries are not required in Django's ``select`` clauses. Also note that
-    some database backends, such as some MySQL versions, don't support
-    subqueries.
-
-    **New in Django development version**
-    In some rare cases, you might wish to pass parameters to the SQL fragments
-    in ``extra(select=...)```. For this purpose, use the ``select_params``
-    parameter. Since ``select_params`` is a sequence and the ``select``
-    attribute is a dictionary, some care is required so that the parameters
-    are matched up correctly with the extra select pieces.  In this situation,
-    you should use a ``django.utils.datastructures.SortedDict`` for the
-    ``select`` value, not just a normal Python dictionary.
-
-    This will work, for example::
-
-        Blog.objects.extra(
-            select=SortedDict([('a', '%s'), ('b', '%s')]),
-            select_params=('one', 'two'))
-
-    The only thing to be careful about when using select parameters in
-    ``extra()`` is to avoid using the substring ``"%%s"`` (that's *two*
-    percent characters before the ``s``) in the select strings. Django's
-    tracking of parameters looks for ``%s`` and an escaped ``%`` character
-    like this isn't detected. That will lead to incorrect results.
-
-``where`` / ``tables``
-    You can define explicit SQL ``WHERE`` clauses -- perhaps to perform
-    non-explicit joins -- by using ``where``. You can manually add tables to
-    the SQL ``FROM`` clause by using ``tables``.
-
-    ``where`` and ``tables`` both take a list of strings. All ``where``
-    parameters are "AND"ed to any other search criteria.
-
-    Example::
-
-        Entry.objects.extra(where=['id IN (3, 4, 5, 20)'])
-
-    ...translates (roughly) into the following SQL::
-
-        SELECT * FROM blog_entry WHERE id IN (3, 4, 5, 20);
-
-    Be careful when using the ``tables`` parameter if you're specifying
-    tables that are already used in the query. When you add extra tables
-    via the ``tables`` parameter, Django assumes you want that table included
-    an extra time, if it is already included. That creates a problem,
-    since the table name will then be given an alias. If a table appears
-    multiple times in an SQL statement, the second and subsequent occurrences
-    must use aliases so the database can tell them apart. If you're
-    referring to the extra table you added in the extra ``where`` parameter
-    this is going to cause errors.
-
-    Normally you'll only be adding extra tables that don't already appear in
-    the query. However, if the case outlined above does occur, there are a few
-    solutions. First, see if you can get by without including the extra table
-    and use the one already in the query. If that isn't possible, put your
-    ``extra()`` call at the front of the queryset construction so that your
-    table is the first use of that table. Finally, if all else fails, look at
-    the query produced and rewrite your ``where`` addition to use the alias
-    given to your extra table. The alias will be the same each time you
-    construct the queryset in the same way, so you can rely upon the alias
-    name to not change.
-
-``order_by``
-    If you need to order the resulting queryset using some of the new fields
-    or tables you have included via ``extra()`` use the ``order_by`` parameter
-    to ``extra()`` and pass in a sequence of strings. These strings should
-    either be model fields (as in the normal ``order_by()`` method on
-    querysets), of the form ``table_name.column_name`` or an alias for a column
-    that you specified in the ``select`` parameter to ``extra()``.
-
-    For example::
-
-        q = Entry.objects.extra(select={'is_recent': "pub_date > '2006-01-01'"})
-        q = q.extra(order_by = ['-is_recent'])
-
-    This would sort all the items for which ``is_recent`` is true to the front
-    of the result set (``True`` sorts before ``False`` in a descending
-    ordering).
-
-    This shows, by the way, that you can make multiple calls to
-    ``extra()`` and it will behave as you expect (adding new constraints each
-    time).
-
-``params``
-    The ``where`` parameter described above may use standard Python database
-    string placeholders -- ``'%s'`` to indicate parameters the database engine
-    should automatically quote. The ``params`` argument is a list of any extra
-    parameters to be substituted.
-
-    Example::
-
-        Entry.objects.extra(where=['headline=%s'], params=['Lennon'])
-
-    Always use ``params`` instead of embedding values directly into ``where``
-    because ``params`` will ensure values are quoted correctly according to
-    your particular backend. (For example, quotes will be escaped correctly.)
-
-    Bad::
-
-        Entry.objects.extra(where=["headline='Lennon'"])
-
-    Good::
-
-        Entry.objects.extra(where=['headline=%s'], params=['Lennon'])
-
-**New in Django development version** The ``select_params`` argument to
-``extra()`` is new. Previously, you could attempt to pass parameters for
-``select`` in the ``params`` argument, but it worked very unreliably.
-
-QuerySet methods that do not return QuerySets
----------------------------------------------
-
-The following ``QuerySet`` methods evaluate the ``QuerySet`` and return
-something *other than* a ``QuerySet``.
-
-These methods do not use a cache (see `Caching and QuerySets`_ below). Rather,
-they query the database each time they're called.
-
-``get(**kwargs)``
-~~~~~~~~~~~~~~~~~
-
-Returns the object matching the given lookup parameters, which should be in
-the format described in `Field lookups`_.
-
-``get()`` raises ``MultipleObjectsReturned`` if more than one object was found.
-The ``MultipleObjectsReturned`` exception is an attribute of the model class.
-For example, the following will raise ``MultipleObjectsReturned`` if there
-are more than one authors with the name of 'John'::
-
-	Author.objects.get(name='John') # raises Author.MultipleObjectsReturned
-
-``get()`` raises a ``DoesNotExist`` exception if an object wasn't found for the
-given parameters. The ``DoesNotExist`` exception is an attribute of the model
-class. Example::
-
-    Entry.objects.get(id='foo') # raises Entry.DoesNotExist
-
-The ``DoesNotExist`` exception inherits from
-``django.core.exceptions.ObjectDoesNotExist``, so you can target multiple
-``DoesNotExist`` exceptions. Example::
-
-    from django.core.exceptions import ObjectDoesNotExist
-    try:
-        e = Entry.objects.get(id=3)
-        b = Blog.objects.get(id=1)
-    except ObjectDoesNotExist:
-        print "Either the entry or blog doesn't exist."
-
-``create(**kwargs)``
-~~~~~~~~~~~~~~~~~~~~
-
-A convenience method for creating an object and saving it all in one step.  Thus::
-
-    p = Person.objects.create(first_name="Bruce", last_name="Springsteen")
-
-and::
-
-    p = Person(first_name="Bruce", last_name="Springsteen")
-    p.save()
-
-are equivalent.
-
-``get_or_create(**kwargs)``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-A convenience method for looking up an object with the given kwargs, creating
-one if necessary.
-
-Returns a tuple of ``(object, created)``, where ``object`` is the retrieved or
-created object and ``created`` is a boolean specifying whether a new object was
-created.
-
-This is meant as a shortcut to boilerplatish code and is mostly useful for
-data-import scripts. For example::
-
-    try:
-        obj = Person.objects.get(first_name='John', last_name='Lennon')
-    except Person.DoesNotExist:
-        obj = Person(first_name='John', last_name='Lennon', birthday=date(1940, 10, 9))
-        obj.save()
-
-This pattern gets quite unwieldy as the number of fields in a model goes up.
-The above example can be rewritten using ``get_or_create()`` like so::
-
-    obj, created = Person.objects.get_or_create(first_name='John', last_name='Lennon',
-                      defaults={'birthday': date(1940, 10, 9)})
-
-Any keyword arguments passed to ``get_or_create()`` -- *except* an optional one
-called ``defaults`` -- will be used in a ``get()`` call. If an object is found,
-``get_or_create()`` returns a tuple of that object and ``False``. If an object
-is *not* found, ``get_or_create()`` will instantiate and save a new object,
-returning a tuple of the new object and ``True``. The new object will be
-created according to this algorithm::
-
-    defaults = kwargs.pop('defaults', {})
-    params = dict([(k, v) for k, v in kwargs.items() if '__' not in k])
-    params.update(defaults)
-    obj = self.model(**params)
-    obj.save()
-
-In English, that means start with any non-``'defaults'`` keyword argument that
-doesn't contain a double underscore (which would indicate a non-exact lookup).
-Then add the contents of ``defaults``, overriding any keys if necessary, and
-use the result as the keyword arguments to the model class.
-
-If you have a field named ``defaults`` and want to use it as an exact lookup in
-``get_or_create()``, just use ``'defaults__exact'``, like so::
-
-    Foo.objects.get_or_create(defaults__exact='bar', defaults={'defaults': 'baz'})
-
-Finally, a word on using ``get_or_create()`` in Django views. As mentioned
-earlier, ``get_or_create()`` is mostly useful in scripts that need to parse
-data and create new records if existing ones aren't available. But if you need
-to use ``get_or_create()`` in a view, please make sure to use it only in
-``POST`` requests unless you have a good reason not to. ``GET`` requests
-shouldn't have any effect on data; use ``POST`` whenever a request to a page
-has a side effect on your data. For more, see `Safe methods`_ in the HTTP spec.
-
-.. _Safe methods: http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.1.1
-
-``count()``
-~~~~~~~~~~~
-
-Returns an integer representing the number of objects in the database matching
-the ``QuerySet``. ``count()`` never raises exceptions.
-
-Example::
-
-    # Returns the total number of entries in the database.
-    Entry.objects.count()
-
-    # Returns the number of entries whose headline contains 'Lennon'
-    Entry.objects.filter(headline__contains='Lennon').count()
-
-``count()`` performs a ``SELECT COUNT(*)`` behind the scenes, so you should
-always use ``count()`` rather than loading all of the record into Python
-objects and calling ``len()`` on the result.
-
-Depending on which database you're using (e.g. PostgreSQL vs. MySQL),
-``count()`` may return a long integer instead of a normal Python integer. This
-is an underlying implementation quirk that shouldn't pose any real-world
-problems.
-
-``in_bulk(id_list)``
-~~~~~~~~~~~~~~~~~~~~
-
-Takes a list of primary-key values and returns a dictionary mapping each
-primary-key value to an instance of the object with the given ID.
-
-Example::
-
-    >>> Blog.objects.in_bulk([1])
-    {1: Beatles Blog}
-    >>> Blog.objects.in_bulk([1, 2])
-    {1: Beatles Blog, 2: Cheddar Talk}
-    >>> Blog.objects.in_bulk([])
-    {}
-
-If you pass ``in_bulk()`` an empty list, you'll get an empty dictionary.
-
-``iterator()``
-~~~~~~~~~~~~~~
-
-Evaluates the ``QuerySet`` (by performing the query) and returns an
-`iterator`_ over the results. A ``QuerySet`` typically reads all of
-its results and instantiates all of the corresponding objects the
-first time you access it; ``iterator()`` will instead read results and
-instantiate objects in discrete chunks, yielding them one at a
-time. For a ``QuerySet`` which returns a large number of objects, this
-often results in better performance and a significant reduction in
-memory use.
-
-Note that using ``iterator()`` on a ``QuerySet`` which has already
-been evaluated will force it to evaluate again, repeating the query.
-
-.. _iterator: http://www.python.org/dev/peps/pep-0234/
-
-``latest(field_name=None)``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Returns the latest object in the table, by date, using the ``field_name``
-provided as the date field.
-
-This example returns the latest ``Entry`` in the table, according to the
-``pub_date`` field::
-
-    Entry.objects.latest('pub_date')
-
-If your model's ``Meta`` specifies ``get_latest_by``, you can leave off the
-``field_name`` argument to ``latest()``. Django will use the field specified in
-``get_latest_by`` by default.
-
-Like ``get()``, ``latest()`` raises ``DoesNotExist`` if an object doesn't
-exist with the given parameters.
-
-Note ``latest()`` exists purely for convenience and readability.
-
-Field lookups
--------------
-
-Field lookups are how you specify the meat of an SQL ``WHERE`` clause. They're
-specified as keyword arguments to the ``QuerySet`` methods ``filter()``,
-``exclude()`` and ``get()``.
-
-Basic lookups keyword arguments take the form ``field__lookuptype=value``.
-(That's a double-underscore). For example::
-
-    Entry.objects.filter(pub_date__lte='2006-01-01')
-
-translates (roughly) into the following SQL::
-
-    SELECT * FROM blog_entry WHERE pub_date <= '2006-01-01';
-
-.. admonition:: How this is possible
-
-   Python has the ability to define functions that accept arbitrary name-value
-   arguments whose names and values are evaluated at runtime. For more
-   information, see `Keyword Arguments`_ in the official Python tutorial.
-
-   .. _`Keyword Arguments`: http://docs.python.org/tut/node6.html#SECTION006720000000000000000
-
-If you pass an invalid keyword argument, a lookup function will raise
-``TypeError``.
-
-The database API supports the following lookup types:
-
-exact
-~~~~~
-
-Exact match. If the value provided for comparison is ``None``, it will
-be interpreted as an SQL ``NULL`` (See isnull_ for more details).
-
-Examples::
-
-    Entry.objects.get(id__exact=14)
-    Entry.objects.get(id__exact=None)
-
-SQL equivalents::
-
-    SELECT ... WHERE id = 14;
-    SELECT ... WHERE id IS NULL;
-
-**New in Django development version:** The semantics of ``id__exact=None`` have
-changed in the development version. Previously, it was (intentionally)
-converted to ``WHERE id = NULL`` at the SQL level, which would never match
-anything. It has now been changed to behave the same as ``id__isnull=True``.
-
-.. admonition:: MySQL comparisons
-
-    In MySQL, whether or not ``exact`` comparisons are case-sensitive depends
-    upon the collation setting of the table involved. The default is usually
-    ``latin1_swedish_ci`` or ``utf8_swedish_ci``, which results in
-    case-insensitive comparisons. Change the collation to
-    ``latin1_swedish_cs`` or ``utf8_bin`` for case sensitive comparisons.
-
-    For more details, refer to the MySQL manual section about `character sets
-    and collations`_.
-
-.. _character sets and collations: http://dev.mysql.com/doc/refman/5.0/en/charset.html
-
-iexact
-~~~~~~
-
-Case-insensitive exact match.
-
-Example::
-
-    Blog.objects.get(name__iexact='beatles blog')
-
-SQL equivalent::
-
-    SELECT ... WHERE name ILIKE 'beatles blog';
-
-Note this will match ``'Beatles Blog'``, ``'beatles blog'``,
-``'BeAtLes BLoG'``, etc.
-
-contains
-~~~~~~~~
-
-Case-sensitive containment test.
-
-Example::
-
-    Entry.objects.get(headline__contains='Lennon')
-
-SQL equivalent::
-
-    SELECT ... WHERE headline LIKE '%Lennon%';
-
-Note this will match the headline ``'Today Lennon honored'`` but not
-``'today lennon honored'``.
-
-SQLite doesn't support case-sensitive ``LIKE`` statements; ``contains`` acts
-like ``icontains`` for SQLite.
-
-icontains
-~~~~~~~~~
-
-Case-insensitive containment test.
-
-Example::
-
-    Entry.objects.get(headline__icontains='Lennon')
-
-SQL equivalent::
-
-    SELECT ... WHERE headline ILIKE '%Lennon%';
-
-gt
-~~
-
-Greater than.
-
-Example::
-
-    Entry.objects.filter(id__gt=4)
-
-SQL equivalent::
-
-    SELECT ... WHERE id > 4;
-
-gte
-~~~
-
-Greater than or equal to.
-
-lt
-~~
-
-Less than.
-
-lte
-~~~
-
-Less than or equal to.
-
-in
-~~
-
-In a given list.
-
-Example::
-
-    Entry.objects.filter(id__in=[1, 3, 4])
-
-SQL equivalent::
-
-    SELECT ... WHERE id IN (1, 3, 4);
-
-You can also use a queryset to dynamically evaluate the list of values
-instead of providing a list of literal values. The queryset must be
-reduced to a list of individual values using the ``values()`` method,
-and then converted into a query using the ``query`` attribute::
-
-    Entry.objects.filter(blog__in=Blog.objects.filter(name__contains='Cheddar').values('pk').query)
-
-This queryset will be evaluated as subselect statement::
-
-    SELECT ... WHERE blog.id IN (SELECT id FROM ... WHERE NAME LIKE '%Cheddar%')
-
-startswith
-~~~~~~~~~~
-
-Case-sensitive starts-with.
-
-Example::
-
-    Entry.objects.filter(headline__startswith='Will')
-
-SQL equivalent::
-
-    SELECT ... WHERE headline LIKE 'Will%';
-
-SQLite doesn't support case-sensitive ``LIKE`` statements; ``startswith`` acts
-like ``istartswith`` for SQLite.
-
-istartswith
-~~~~~~~~~~~
-
-Case-insensitive starts-with.
-
-Example::
-
-    Entry.objects.filter(headline__istartswith='will')
-
-SQL equivalent::
-
-    SELECT ... WHERE headline ILIKE 'Will%';
-
-endswith
-~~~~~~~~
-
-Case-sensitive ends-with.
-
-Example::
-
-    Entry.objects.filter(headline__endswith='cats')
-
-SQL equivalent::
-
-    SELECT ... WHERE headline LIKE '%cats';
-
-SQLite doesn't support case-sensitive ``LIKE`` statements; ``endswith`` acts
-like ``iendswith`` for SQLite.
-
-iendswith
-~~~~~~~~~
-
-Case-insensitive ends-with.
-
-Example::
-
-    Entry.objects.filter(headline__iendswith='will')
-
-SQL equivalent::
-
-    SELECT ... WHERE headline ILIKE '%will'
-
-range
-~~~~~
-
-Range test (inclusive).
-
-Example::
-
-    start_date = datetime.date(2005, 1, 1)
-    end_date = datetime.date(2005, 3, 31)
-    Entry.objects.filter(pub_date__range=(start_date, end_date))
-
-SQL equivalent::
-
-    SELECT ... WHERE pub_date BETWEEN '2005-01-01' and '2005-03-31';
-
-You can use ``range`` anywhere you can use ``BETWEEN`` in SQL -- for dates,
-numbers and even characters.
-
-year
-~~~~
-
-For date/datetime fields, exact year match. Takes a four-digit year.
-
-Example::
-
-    Entry.objects.filter(pub_date__year=2005)
-
-SQL equivalent::
-
-    SELECT ... WHERE EXTRACT('year' FROM pub_date) = '2005';
-
-(The exact SQL syntax varies for each database engine.)
-
-month
-~~~~~
-
-For date/datetime fields, exact month match. Takes an integer 1 (January)
-through 12 (December).
-
-Example::
-
-    Entry.objects.filter(pub_date__month=12)
-
-SQL equivalent::
-
-    SELECT ... WHERE EXTRACT('month' FROM pub_date) = '12';
-
-(The exact SQL syntax varies for each database engine.)
-
-day
-~~~
-
-For date/datetime fields, exact day match.
-
-Example::
-
-    Entry.objects.filter(pub_date__day=3)
-
-SQL equivalent::
-
-    SELECT ... WHERE EXTRACT('day' FROM pub_date) = '3';
-
-(The exact SQL syntax varies for each database engine.)
-
-Note this will match any record with a pub_date on the third day of the month,
-such as January 3, July 3, etc.
-
-isnull
-~~~~~~
-
-Takes either ``True`` or ``False``, which correspond to SQL queries of
-``IS NULL`` and ``IS NOT NULL``, respectively.
-
-Example::
-
-    Entry.objects.filter(pub_date__isnull=True)
-
-SQL equivalent::
-
-    SELECT ... WHERE pub_date IS NULL;
-
-search
-~~~~~~
-
-A boolean full-text search, taking advantage of full-text indexing. This is
-like ``contains`` but is significantly faster due to full-text indexing.
-
-Note this is only available in MySQL and requires direct manipulation of the
-database to add the full-text index.
-
-regex
-~~~~~
-
-**New in Django development version**
-
-Case-sensitive regular expression match.
-
-The regular expression syntax is that of the database backend in use. In the
-case of SQLite, which doesn't natively support regular-expression lookups, the
-syntax is that of Python's ``re`` module.
-
-Example::
-
-    Entry.objects.get(title__regex=r'^(An?|The) +')
-
-SQL equivalents::
-
-    SELECT ... WHERE title REGEXP BINARY '^(An?|The) +'; -- MySQL
-
-    SELECT ... WHERE REGEXP_LIKE(title, '^(an?|the) +', 'c'); -- Oracle
-
-    SELECT ... WHERE title ~ '^(An?|The) +'; -- PostgreSQL
-
-    SELECT ... WHERE title REGEXP '^(An?|The) +'; -- SQLite
-
-Using raw strings (e.g., ``r'foo'`` instead of ``'foo'``) for passing in the
-regular expression syntax is recommended.
-
-iregex
-~~~~~~
-
-**New in Django development version**
-
-Case-insensitive regular expression match.
-
-Example::
-
-    Entry.objects.get(title__iregex=r'^(an?|the) +')
-
-SQL equivalents::
-
-    SELECT ... WHERE title REGEXP '^(an?|the) +'; -- MySQL
-
-    SELECT ... WHERE REGEXP_LIKE(title, '^(an?|the) +', 'i'); -- Oracle
-
-    SELECT ... WHERE title ~* '^(an?|the) +'; -- PostgreSQL
-
-    SELECT ... WHERE title REGEXP '(?i)^(an?|the) +'; -- SQLite
-
-Default lookups are exact
--------------------------
-
-If you don't provide a lookup type -- that is, if your keyword argument doesn't
-contain a double underscore -- the lookup type is assumed to be ``exact``.
-
-For example, the following two statements are equivalent::
-
-    Blog.objects.get(id__exact=14) # Explicit form
-    Blog.objects.get(id=14) # __exact is implied
-
-This is for convenience, because ``exact`` lookups are the common case.
-
-The pk lookup shortcut
-----------------------
-
-For convenience, Django provides a ``pk`` lookup type, which stands for
-"primary_key".
-
-In the example ``Blog`` model, the primary key is the ``id`` field, so these
-three statements are equivalent::
-
-    Blog.objects.get(id__exact=14) # Explicit form
-    Blog.objects.get(id=14) # __exact is implied
-    Blog.objects.get(pk=14) # pk implies id__exact
-
-The use of ``pk`` isn't limited to ``__exact`` queries -- any query term
-can be combined with ``pk`` to perform a query on the primary key of a model::
-
-    # Get blogs entries  with id 1, 4 and 7
-    Blog.objects.filter(pk__in=[1,4,7])
-    # Get all blog entries with id > 14
-    Blog.objects.filter(pk__gt=14)
-
-``pk`` lookups also work across joins. For example, these three statements are
-equivalent::
-
-    Entry.objects.filter(blog__id__exact=3) # Explicit form
-    Entry.objects.filter(blog__id=3) # __exact is implied
-    Entry.objects.filter(blog__pk=3) # __pk implies __id__exact
-
-.. note::
-    Because of this shortcut, you cannot have a field called ``pk`` that is not
-    the primary key of the model. It will always be replaced by the name of the
-    model's primary key in queries.
-
-Lookups that span relationships
--------------------------------
-
-Django offers a powerful and intuitive way to "follow" relationships in
-lookups, taking care of the SQL ``JOIN``\s for you automatically, behind the
-scenes. To span a relationship, just use the field name of related fields
-across models, separated by double underscores, until you get to the field you
-want.
-
-This example retrieves all ``Entry`` objects with a ``Blog`` whose ``name``
-is ``'Beatles Blog'``::
-
-    Entry.objects.filter(blog__name__exact='Beatles Blog')
-
-This spanning can be as deep as you'd like.
-
-It works backwards, too. To refer to a "reverse" relationship, just use the
-lowercase name of the model.
-
-This example retrieves all ``Blog`` objects which have at least one ``Entry``
-whose ``headline`` contains ``'Lennon'``::
-
-    Blog.objects.filter(entry__headline__contains='Lennon')
-
-If you are filtering across multiple relationships and one of the intermediate
-models doesn't have a value that meets the filter condition, Django will treat
-it as if there is an empty (all values are ``NULL``), but valid, object there.
-All this means is that no error will be raised. For example, in this filter::
-
-    Blog.objects.filter(entry__author__name='Lennon')
-
-(if there was a related ``Author`` model), if there was no ``author``
-associated with an entry, it would be treated as if there was also no ``name``
-attached, rather than raising an error because of the missing ``author``.
-Usually this is exactly what you want to have happen. The only case where it
-might be confusing is if you are using ``isnull``. Thus::
-
-    Blog.objects.filter(entry__author__name__isnull=True)
-
-will return ``Blog`` objects that have an empty ``name`` on the ``author`` and
-also those which have an empty ``author`` on the ``entry``. If you don't want
-those latter objects, you could write::
-
-    Blog.objetcs.filter(entry__author__isnull=False,
-            entry__author__name__isnull=True)
-
-Spanning multi-valued relationships
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-**New in Django development version**
-
-When you are filtering an object based on a ``ManyToManyField`` or a reverse
-``ForeignKeyField``, there are two different sorts of filter you may be
-interested in. Consider the ``Blog``/``Entry`` relationship (``Blog`` to
-``Entry`` is a one-to-many relation). We might be interested in finding blogs
-that have an entry which has both *"Lennon"* in the headline and was published
-in 2008. Or we might want to find blogs that have an entry with *"Lennon"* in
-the headline as well as an entry that was published in 2008. Since there are
-multiple entries associated with a single ``Blog``, both of these queries are
-possible and make sense in some situations.
-
-The same type of situation arises with a ``ManyToManyField``. For example, if
-an ``Entry`` has a ``ManyToManyField`` called ``tags``, we might want to find
-entries linked to tags called *"music"* and *"bands"* or we might want an
-entry that contains a tag with a name of *"music"* and a status of *"public"*.
-
-To handle both of these situations, Django has a consistent way of processing
-``filter()`` and ``exclude()`` calls. Everything inside a single ``filter()``
-call is applied simultaneously to filter out items matching all those
-requirements. Successive ``filter()`` calls further restrict the set of
-objects, but for multi-valued relations, they apply to any object linked to
-the primary model, not necessarily those objects that were selected by an
-earlier ``filter()`` call.
-
-That may sound a bit confusing, so hopefully an example will clarify. To
-select all blogs that contains entries with *"Lennon"* in the headline and
-were published in 2008, we would write::
-
-    Blog.objects.filter(entry__headline__contains='Lennon',
-            entry__pub_date__year=2008)
-
-To select all blogs that contain an entry with *"Lennon"* in the headline
-**as well as** an entry that was published in 2008, we would write::
-
-    Blog.objects.filter(entry__headline__contains='Lennon').filter(
-            entry__pub_date__year=2008)
-
-In this second example, the first filter restricted the queryset to all those
-blogs linked to that particular type of entry. The second filter restricted
-the set of blogs *further* to those that are also linked to the second type of
-entry. The entries select by the second filter may or may not be the same as
-the entries in the first filter. We are filtering the ``Blog`` items with each
-filter statement, not the ``Entry`` items.
-
-All of this behavior also applies to ``exclude()``: all the conditions in a
-single ``exclude()`` statement apply to a single instance (if those conditions
-are talking about the same multi-valued relation). Conditions in subsequent
-``filter()`` or ``exclude()`` calls that refer to the same relation may end up
-filtering on different linked objects.
-
-Escaping percent signs and underscores in LIKE statements
----------------------------------------------------------
-
-The field lookups that equate to ``LIKE`` SQL statements (``iexact``,
-``contains``, ``icontains``, ``startswith``, ``istartswith``, ``endswith``
-and ``iendswith``) will automatically escape the two special characters used in
-``LIKE`` statements -- the percent sign and the underscore. (In a ``LIKE``
-statement, the percent sign signifies a multiple-character wildcard and the
-underscore signifies a single-character wildcard.)
-
-This means things should work intuitively, so the abstraction doesn't leak.
-For example, to retrieve all the entries that contain a percent sign, just use
-the percent sign as any other character::
-
-    Entry.objects.filter(headline__contains='%')
-
-Django takes care of the quoting for you; the resulting SQL will look something
-like this::
-
-    SELECT ... WHERE headline LIKE '%\%%';
-
-Same goes for underscores. Both percentage signs and underscores are handled
-for you transparently.
-
-Caching and QuerySets
----------------------
-
-Each ``QuerySet`` contains a cache, to minimize database access. It's important
-to understand how it works, in order to write the most efficient code.
-
-In a newly created ``QuerySet``, the cache is empty. The first time a
-``QuerySet`` is evaluated -- and, hence, a database query happens -- Django
-saves the query results in the ``QuerySet``'s cache and returns the results
-that have been explicitly requested (e.g., the next element, if the
-``QuerySet`` is being iterated over). Subsequent evaluations of the
-``QuerySet`` reuse the cached results.
-
-Keep this caching behavior in mind, because it may bite you if you don't use
-your ``QuerySet``\s correctly. For example, the following will create two
-``QuerySet``\s, evaluate them, and throw them away::
-
-    print [e.headline for e in Entry.objects.all()]
-    print [e.pub_date for e in Entry.objects.all()]
-
-That means the same database query will be executed twice, effectively doubling
-your database load. Also, there's a possibility the two lists may not include
-the same database records, because an ``Entry`` may have been added or deleted
-in the split second between the two requests.
-
-To avoid this problem, simply save the ``QuerySet`` and reuse it::
-
-    queryset = Poll.objects.all()
-    print [p.headline for p in queryset] # Evaluate the query set.
-    print [p.pub_date for p in queryset] # Re-use the cache from the evaluation.
-
-Comparing objects
-=================
-
-To compare two model instances, just use the standard Python comparison operator,
-the double equals sign: ``==``. Behind the scenes, that compares the primary
-key values of two models.
-
-Using the ``Entry`` example above, the following two statements are equivalent::
-
-    some_entry == other_entry
-    some_entry.id == other_entry.id
-
-If a model's primary key isn't called ``id``, no problem. Comparisons will
-always use the primary key, whatever it's called. For example, if a model's
-primary key field is called ``name``, these two statements are equivalent::
-
-    some_obj == other_obj
-    some_obj.name == other_obj.name
-
-Complex lookups with Q objects
-==============================
-
-Keyword argument queries -- in ``filter()``, etc. -- are "AND"ed together. If
-you need to execute more complex queries (for example, queries with ``OR``
-statements), you can use ``Q`` objects.
-
-A ``Q`` object (``django.db.models.Q``) is an object used to encapsulate a
-collection of keyword arguments. These keyword arguments are specified as in
-"Field lookups" above.
-
-For example, this ``Q`` object encapsulates a single ``LIKE`` query::
-
-    Q(question__startswith='What')
-
-``Q`` objects can be combined using the ``&`` and ``|`` operators. When an
-operator is used on two ``Q`` objects, it yields a new ``Q`` object.
-
-For example, this statement yields a single ``Q`` object that represents the
-"OR" of two ``"question__startswith"`` queries::
-
-    Q(question__startswith='Who') | Q(question__startswith='What')
-
-This is equivalent to the following SQL ``WHERE`` clause::
-
-    WHERE question LIKE 'Who%' OR question LIKE 'What%'
-
-You can compose statements of arbitrary complexity by combining ``Q`` objects
-with the ``&`` and ``|`` operators. You can also use parenthetical grouping.
-
-**New in Django development version:** ``Q`` objects can also be negated using
-the ``~`` operator, allowing for combined lookups that combine both a normal
-query and a negated (``NOT``) query::
-
-    Q(question__startswith='Who') | ~Q(pub_date__year=2005)
-
-Each lookup function that takes keyword-arguments (e.g. ``filter()``,
-``exclude()``, ``get()``) can also be passed one or more ``Q`` objects as
-positional (not-named) arguments. If you provide multiple ``Q`` object
-arguments to a lookup function, the arguments will be "AND"ed together. For
-example::
-
-    Poll.objects.get(
-        Q(question__startswith='Who'),
-        Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6))
-    )
-
-... roughly translates into the SQL::
-
-    SELECT * from polls WHERE question LIKE 'Who%'
-        AND (pub_date = '2005-05-02' OR pub_date = '2005-05-06')
-
-Lookup functions can mix the use of ``Q`` objects and keyword arguments. All
-arguments provided to a lookup function (be they keyword arguments or ``Q``
-objects) are "AND"ed together. However, if a ``Q`` object is provided, it must
-precede the definition of any keyword arguments. For example::
-
-    Poll.objects.get(
-        Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)),
-        question__startswith='Who')
-
-... would be a valid query, equivalent to the previous example; but::
-
-    # INVALID QUERY
-    Poll.objects.get(
-        question__startswith='Who',
-        Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)))
-
-... would not be valid.
-
-See the `OR lookups examples page`_ for more examples.
-
-.. _OR lookups examples page: ../models/or_lookups/
-
-Related objects
-===============
-
-When you define a relationship in a model (i.e., a ``ForeignKey``,
-``OneToOneField``, or ``ManyToManyField``), instances of that model will have
-a convenient API to access the related object(s).
-
-Using the models at the top of this page, for example, an ``Entry`` object ``e``
-can get its associated ``Blog`` object by accessing the ``blog`` attribute:
-``e.blog``.
-
-(Behind the scenes, this functionality is implemented by Python descriptors_.
-This shouldn't really matter to you, but we point it out here for the curious.)
-
-Django also creates API accessors for the "other" side of the relationship --
-the link from the related model to the model that defines the relationship.
-For example, a ``Blog`` object ``b`` has access to a list of all related
-``Entry`` objects via the ``entry_set`` attribute: ``b.entry_set.all()``.
-
-All examples in this section use the sample ``Blog``, ``Author`` and ``Entry``
-models defined at the top of this page.
-
-.. _descriptors: http://users.rcn.com/python/download/Descriptor.htm
-
-One-to-many relationships
--------------------------
-
-Forward
-~~~~~~~
-
-If a model has a ``ForeignKey``, instances of that model will have access to
-the related (foreign) object via a simple attribute of the model.
-
-Example::
-
-    e = Entry.objects.get(id=2)
-    e.blog # Returns the related Blog object.
-
-You can get and set via a foreign-key attribute. As you may expect, changes to
-the foreign key aren't saved to the database until you call ``save()``.
-Example::
-
-    e = Entry.objects.get(id=2)
-    e.blog = some_blog
-    e.save()
-
-If a ``ForeignKey`` field has ``null=True`` set (i.e., it allows ``NULL``
-values), you can assign ``None`` to it. Example::
-
-    e = Entry.objects.get(id=2)
-    e.blog = None
-    e.save() # "UPDATE blog_entry SET blog_id = NULL ...;"
-
-Forward access to one-to-many relationships is cached the first time the
-related object is accessed. Subsequent accesses to the foreign key on the same
-object instance are cached. Example::
-
-    e = Entry.objects.get(id=2)
-    print e.blog  # Hits the database to retrieve the associated Blog.
-    print e.blog  # Doesn't hit the database; uses cached version.
-
-Note that the ``select_related()`` ``QuerySet`` method recursively prepopulates
-the cache of all one-to-many relationships ahead of time. Example::
-
-    e = Entry.objects.select_related().get(id=2)
-    print e.blog  # Doesn't hit the database; uses cached version.
-    print e.blog  # Doesn't hit the database; uses cached version.
-
-``select_related()`` is documented in the `QuerySet methods that return new QuerySets`_ section above.
-
-Backward
-~~~~~~~~
-
-If a model has a ``ForeignKey``, instances of the foreign-key model will have
-access to a ``Manager`` that returns all instances of the first model. By
-default, this ``Manager`` is named ``FOO_set``, where ``FOO`` is the source
-model name, lowercased. This ``Manager`` returns ``QuerySets``, which can be
-filtered and manipulated as described in the "Retrieving objects" section
-above.
-
-Example::
-
-    b = Blog.objects.get(id=1)
-    b.entry_set.all() # Returns all Entry objects related to Blog.
-
-    # b.entry_set is a Manager that returns QuerySets.
-    b.entry_set.filter(headline__contains='Lennon')
-    b.entry_set.count()
-
-You can override the ``FOO_set`` name by setting the ``related_name``
-parameter in the ``ForeignKey()`` definition. For example, if the ``Entry``
-model was altered to ``blog = ForeignKey(Blog, related_name='entries')``, the
-above example code would look like this::
-
-    b = Blog.objects.get(id=1)
-    b.entries.all() # Returns all Entry objects related to Blog.
-
-    # b.entries is a Manager that returns QuerySets.
-    b.entries.filter(headline__contains='Lennon')
-    b.entries.count()
-
-You cannot access a reverse ``ForeignKey`` ``Manager`` from the class; it must
-be accessed from an instance. Example::
-
-    Blog.entry_set # Raises AttributeError: "Manager must be accessed via instance".
-
-In addition to the ``QuerySet`` methods defined in "Retrieving objects" above,
-the ``ForeignKey`` ``Manager`` has these additional methods:
-
-    * ``add(obj1, obj2, ...)``: Adds the specified model objects to the related
-      object set.
-
-      Example::
-
-          b = Blog.objects.get(id=1)
-          e = Entry.objects.get(id=234)
-          b.entry_set.add(e) # Associates Entry e with Blog b.
-
-    * ``create(**kwargs)``: Creates a new object, saves it and puts it in the
-      related object set. Returns the newly created object.
-
-      Example::
-
-          b = Blog.objects.get(id=1)
-          e = b.entry_set.create(headline='Hello', body_text='Hi', pub_date=datetime.date(2005, 1, 1))
-          # No need to call e.save() at this point -- it's already been saved.
-
-      This is equivalent to (but much simpler than)::
-
-          b = Blog.objects.get(id=1)
-          e = Entry(blog=b, headline='Hello', body_text='Hi', pub_date=datetime.date(2005, 1, 1))
-          e.save()
-
-      Note that there's no need to specify the keyword argument of the model
-      that defines the relationship. In the above example, we don't pass the
-      parameter ``blog`` to ``create()``. Django figures out that the new
-      ``Entry`` object's ``blog`` field should be set to ``b``.
-
-    * ``remove(obj1, obj2, ...)``: Removes the specified model objects from the
-      related object set.
-
-      Example::
-
-          b = Blog.objects.get(id=1)
-          e = Entry.objects.get(id=234)
-          b.entry_set.remove(e) # Disassociates Entry e from Blog b.
-
-      In order to prevent database inconsistency, this method only exists on
-      ``ForeignKey`` objects where ``null=True``. If the related field can't be
-      set to ``None`` (``NULL``), then an object can't be removed from a
-      relation without being added to another. In the above example, removing
-      ``e`` from ``b.entry_set()`` is equivalent to doing ``e.blog = None``,
-      and because the ``blog`` ``ForeignKey`` doesn't have ``null=True``, this
-      is invalid.
-
-    * ``clear()``: Removes all objects from the related object set.
-
-      Example::
-
-          b = Blog.objects.get(id=1)
-          b.entry_set.clear()
-
-      Note this doesn't delete the related objects -- it just disassociates
-      them.
-
-      Just like ``remove()``, ``clear()`` is only available on ``ForeignKey``s
-      where ``null=True``.
-
-To assign the members of a related set in one fell swoop, just assign to it
-from any iterable object. Example::
-
-    b = Blog.objects.get(id=1)
-    b.entry_set = [e1, e2]
-
-If the ``clear()`` method is available, any pre-existing objects will be
-removed from the ``entry_set`` before all objects in the iterable (in this
-case, a list) are added to the set. If the ``clear()`` method is *not*
-available, all objects in the iterable will be added without removing any
-existing elements.
-
-Each "reverse" operation described in this section has an immediate effect on
-the database. Every addition, creation and deletion is immediately and
-automatically saved to the database.
-
-One-to-one relationships
-------------------------
-
-One-to-one relationships are very similar to many-to-one relationships.
-If you define a OneToOneField on your model, instances of that model will have
-access to the related object via a simple attribute of the model.
-
-For example::
-
-    class EntryDetail(models.Model):
-        entry = models.OneToOneField(Entry)
-        details = models.TextField()
-
-    ed = EntryDetail.objects.get(id=2)
-    ed.entry # Returns the related Entry object.
-
-The difference comes in "reverse" queries. The related model in a one-to-one
-relationship also has access to a ``Manager`` object, but that ``Manager``
-represents a single object, rather than a collection of objects::
-
-    e = Entry.objects.get(id=2)
-    e.entrydetail # returns the related EntryDetail object
-
-If no object has been assigned to this relationship, Django will raise
-a ``DoesNotExist`` exception.
-
-Instances can be assigned to the reverse relationship in the same way as
-you would assign the forward relationship::
-
-    e.entrydetail = ed
-
-Many-to-many relationships
---------------------------
-
-Both ends of a many-to-many relationship get automatic API access to the other
-end. The API works just as a "backward" one-to-many relationship. See Backward_
-above.
-
-The only difference is in the attribute naming: The model that defines the
-``ManyToManyField`` uses the attribute name of that field itself, whereas the
-"reverse" model uses the lowercased model name of the original model, plus
-``'_set'`` (just like reverse one-to-many relationships).
-
-An example makes this easier to understand::
-
-    e = Entry.objects.get(id=3)
-    e.authors.all() # Returns all Author objects for this Entry.
-    e.authors.count()
-    e.authors.filter(name__contains='John')
-
-    a = Author.objects.get(id=5)
-    a.entry_set.all() # Returns all Entry objects for this Author.
-
-Like ``ForeignKey``, ``ManyToManyField`` can specify ``related_name``. In the
-above example, if the ``ManyToManyField`` in ``Entry`` had specified
-``related_name='entries'``, then each ``Author`` instance would have an
-``entries`` attribute instead of ``entry_set``.
-
-How are the backward relationships possible?
---------------------------------------------
-
-Other object-relational mappers require you to define relationships on both
-sides. The Django developers believe this is a violation of the DRY (Don't
-Repeat Yourself) principle, so Django only requires you to define the
-relationship on one end.
-
-But how is this possible, given that a model class doesn't know which other
-model classes are related to it until those other model classes are loaded?
-
-The answer lies in the ``INSTALLED_APPS`` setting. The first time any model is
-loaded, Django iterates over every model in ``INSTALLED_APPS`` and creates the
-backward relationships in memory as needed. Essentially, one of the functions
-of ``INSTALLED_APPS`` is to tell Django the entire model domain.
-
-Queries over related objects
-----------------------------
-
-Queries involving related objects follow the same rules as queries involving
-normal value fields. When specifying the the value for a query to match, you
-may use either an object instance itself, or the primary key value for the
-object.
-
-For example, if you have a Blog object ``b`` with ``id=5``, the following
-three queries would be identical::
-
-    Entry.objects.filter(blog=b) # Query using object instance
-    Entry.objects.filter(blog=b.id) # Query using id from instance
-    Entry.objects.filter(blog=5) # Query using id directly
-
-Deleting objects
-================
-
-The delete method, conveniently, is named ``delete()``. This method immediately
-deletes the object and has no return value. Example::
-
-    e.delete()
-
-You can also delete objects in bulk. Every ``QuerySet`` has a ``delete()``
-method, which deletes all members of that ``QuerySet``.
-
-For example, this deletes all ``Entry`` objects with a ``pub_date`` year of
-2005::
-
-    Entry.objects.filter(pub_date__year=2005).delete()
-
-Keep in mind that this will, whenever possible, be executed purely in
-SQL, and so the ``delete()`` methods of individual object instances
-will not necessarily be called during the process. If you've provided
-a custom ``delete()`` method on a model class and want to ensure that
-it is called, you will need to "manually" delete instances of that
-model (e.g., by iterating over a ``QuerySet`` and calling ``delete()``
-on each object individually) rather than using the bulk ``delete()``
-method of a ``QuerySet``.
-
-When Django deletes an object, it emulates the behavior of the SQL
-constraint ``ON DELETE CASCADE`` -- in other words, any objects which
-had foreign keys pointing at the object to be deleted will be deleted
-along with it. For example::
-
-    b = Blog.objects.get(pk=1)
-    # This will delete the Blog and all of its Entry objects.
-    b.delete()
-
-Note that ``delete()`` is the only ``QuerySet`` method that is not exposed on a
-``Manager`` itself. This is a safety mechanism to prevent you from accidentally
-requesting ``Entry.objects.delete()``, and deleting *all* the entries. If you
-*do* want to delete all the objects, then you have to explicitly request a
-complete query set::
-
-    Entry.objects.all().delete()
-
-Updating multiple objects at once
-=================================
-
-**New in Django development version**
-
-Sometimes you want to set a field to a particular value for all the objects in
-a ``QuerySet``. You can do this with the ``update()`` method. For example::
-
-    # Update all the headlines with pub_date in 2007.
-    Entry.objects.filter(pub_date__year=2007).update(headline='Everything is the same')
-
-You can only set non-relation fields and ``ForeignKey`` fields using this
-method, and the value you set the field to must be a hard-coded Python value
-(i.e., you can't set a field to be equal to some other field at the moment).
-
-To update ``ForeignKey`` fields, set the new value to be the new model
-instance you want to point to. Example::
-
-    b = Blog.objects.get(pk=1)
-    # Change every Entry so that it belongs to this Blog.
-    Entry.objects.all().update(blog=b)
-
-The ``update()`` method is applied instantly and doesn't return anything
-(similar to ``delete()``). The only restriction on the ``QuerySet`` that is
-updated is that it can only access one database table, the model's main
-table. So don't try to filter based on related fields or anything like that;
-it won't work.
-
-Be aware that the ``update()`` method is converted directly to an SQL
-statement. It is a bulk operation for direct updates. It doesn't run any
-``save()`` methods on your models, or emit the ``pre_save`` or ``post_save``
-signals (which are a consequence of calling ``save()``). If you want to save
-every item in a ``QuerySet`` and make sure that the ``save()`` method is
-called on each instance, you don't need any special function to handle that.
-Just loop over them and call ``save()``::
-
-    for item in my_queryset:
-        item.save()
-
-
-Extra instance methods
-======================
-
-In addition to ``save()``, ``delete()``, a model object might get any or all
-of the following methods:
-
-get_FOO_display()
------------------
-
-For every field that has ``choices`` set, the object will have a
-``get_FOO_display()`` method, where ``FOO`` is the name of the field. This
-method returns the "human-readable" value of the field. For example, in the
-following model::
-
-    GENDER_CHOICES = (
-        ('M', 'Male'),
-        ('F', 'Female'),
-    )
-    class Person(models.Model):
-        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::
-
-    >>> p = Person(name='John', gender='M')
-    >>> p.save()
-    >>> p.gender
-    'M'
-    >>> p.get_gender_display()
-    'Male'
-
-get_next_by_FOO(\**kwargs) and get_previous_by_FOO(\**kwargs)
--------------------------------------------------------------
-
-For every ``DateField`` and ``DateTimeField`` that does not have ``null=True``,
-the object will have ``get_next_by_FOO()`` and ``get_previous_by_FOO()``
-methods, where ``FOO`` is the name of the field. This returns the next and
-previous object with respect to the date field, raising the appropriate
-``DoesNotExist`` exception when appropriate.
-
-Both methods accept optional keyword arguments, which should be in the format
-described in `Field lookups`_ above.
-
-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: ../models/lookup/
-
-
-Shortcuts
-=========
-
-As you develop views, you will discover a number of common idioms in the
-way you use the database API. Django encodes some of these idioms as
-shortcuts that can be used to simplify the process of writing views. These
-functions are in the ``django.shortcuts`` module.
-
-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 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
-    e = get_object_or_404(Entry, pk=3)
-
-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.
-For example::
-
-    # Get the author of blog instance e with a name of 'Fred'
-    a = get_object_or_404(e.authors, name='Fred')
-
-    # Use a custom manager 'recent_entries' in the search for an
-    # 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()
------------------
-
-``get_list_or_404`` behaves the same way as ``get_object_or_404()``
--- except that it uses ``filter()`` instead of ``get()``. It raises
-``Http404`` if the list is empty.
-
-Falling back to raw SQL
-=======================
-
-If you find yourself needing to write an SQL query that is too complex for
-Django's database-mapper to handle, you can fall back into raw-SQL statement
-mode.
-
-The preferred way to do this is by giving your model custom methods or custom
-manager methods that execute queries. Although there's nothing in Django that
-*requires* database queries to live in the model layer, this approach keeps all
-your data-access logic in one place, which is smart from an code-organization
-standpoint. For instructions, see `Executing custom SQL`_.
-
-Finally, it's important to note that the Django database layer is merely an
-interface to your database. You can access your database via other tools,
-programming languages or database frameworks; there's nothing Django-specific
-about your database.
-
-.. _Executing custom SQL: ../model-api/#executing-custom-sql

+ 0 - 138
docs/documentation.txt

@@ -1,138 +0,0 @@
-====================================
-How to read the Django documentation
-====================================
-
-We've put a lot of effort into making Django's documentation useful, easy to
-read and as complete as possible. Here are a few tips on how to make the best
-of it, along with some style guidelines.
-
-(Yes, this is documentation about documentation. Rest assured we have no plans
-to write a document about how to read the document about documentation.)
-
-How documentation is updated
-============================
-
-Just as the Django code base is developed and improved on a daily basis, our
-documentation is consistently improving. We improve documentation for several
-reasons:
-
-    * To make content fixes, such as grammar/typo corrections.
-    * To add information and/or examples to existing sections that need to be
-      expanded.
-    * To document Django features that aren't yet documented. (The list of
-      such features is shrinking but exists nonetheless.)
-    * To add documentation for new features as new features get added, or as
-      Django APIs or behaviors change.
-
-Django's documentation is kept in the same source control system as its code.
-It lives in the `django/trunk/docs`_ directory of our Subversion repository.
-Each document is a separate text file that covers a narrowly focused topic,
-such as the "generic views" framework or how to construct a database model.
-
-.. _django/trunk/docs: http://code.djangoproject.com/browser/django/trunk/docs
-
-Where to get it
-===============
-
-You can read Django documentation in several ways. They are, in order of
-preference:
-
-On the Web
-----------
-
-The most recent version of the Django documentation lives at
-http://www.djangoproject.com/documentation/ . These HTML pages are generated
-automatically from the text files in source control. That means they reflect
-the "latest and greatest" in Django -- they include the very latest
-corrections and additions, and they discuss the latest Django features,
-which may only be available to users of the Django development version. (See
-"Differences between versions" below.)
-
-We encourage you to help improve the docs by submitting changes, corrections
-and suggestions in the `ticket system`_. The Django developers actively monitor
-the ticket system and use your feedback to improve the documentation for
-everybody.
-
-Note, however, that tickets should explicitly relate to the documentation,
-rather than asking broad tech-support questions. If you need help with your
-particular Django setup, try the `django-users mailing list`_ or the
-`#django IRC channel`_ instead.
-
-.. _ticket system: http://code.djangoproject.com/simpleticket?component=Documentation
-.. _django-users mailing list: http://groups.google.com/group/django-users
-.. _#django IRC channel: irc://irc.freenode.net/django
-
-In plain text
--------------
-
-For offline reading, or just for convenience, you can read the Django
-documentation in plain text.
-
-If you're using an official release of Django, note that the zipped package
-(tarball) of the code includes a ``docs/`` directory, which contains all the
-documentation for that release.
-
-If you're using the development version of Django (aka the Subversion "trunk"),
-note that the ``docs/`` directory contains all of the documentation. You can
-``svn update`` it, just as you ``svn update`` the Python code, in order to get
-the latest changes.
-
-You can check out the latest Django documentation from Subversion using this
-shell command::
-
-    svn co http://code.djangoproject.com/svn/django/trunk/docs/ django_docs
-
-One low-tech way of taking advantage of the text documentation is by using the
-Unix ``grep`` utility to search for a phrase in all of the documentation. For
-example, this will show you each mention of the phrase "edit_inline" in any
-Django document::
-
-    grep edit_inline /path/to/django/docs/*.txt
-
-Formatting
-~~~~~~~~~~
-
-The text documentation is written in ReST (ReStructured Text) format. That
-means it's easy to read but is also formatted in a way that makes it easy to
-convert into other formats, such as HTML. If you have the `reStructuredText`_
-library installed, you can use ``rst2html`` to generate your own HTML files.
-
-.. _reStructuredText: http://docutils.sourceforge.net/rst.html
-
-Differences between versions
-============================
-
-As previously mentioned, the text documentation in our Subversion repository
-contains the "latest and greatest" changes and additions. These changes often
-include documentation of new features added in the Django development version
--- the Subversion ("trunk") version of Django. For that reason, it's worth
-pointing out our policy on keeping straight the documentation for various
-versions of the framework.
-
-We follow this policy:
-
-    * The primary documentation on djangoproject.com is an HTML version of the
-      latest docs in Subversion. These docs always correspond to the latest
-      official Django release, plus whatever features we've added/changed in
-      the framework *since* the latest release.
-
-    * As we add features to Django's development version, we try to update the
-      documentation in the same Subversion commit transaction.
-
-    * To distinguish feature changes/additions in the docs, we use the phrase
-      **New in Django development version**. In practice, this means that the
-      current documentation on djangoproject.com can be used by users of either
-      the latest release *or* the development version.
-
-    * Documentation for a particular Django release is frozen once the version
-      has been released officially. It remains a snapshot of the docs as of the
-      moment of the release. We will make exceptions to this rule in
-      the case of retroactive security updates or other such retroactive
-      changes. Once documentation is frozen, we add a note to the top of each
-      frozen document that says "These docs are frozen for Django version XXX"
-      and links to the current version of that document.
-
-    * The `main documentation Web page`_ includes links to documentation for
-      all previous versions.
-
-.. _main documentation Web page: http://www.djangoproject.com/documentation/

+ 0 - 744
docs/faq.txt

@@ -1,744 +0,0 @@
-==========
-Django FAQ
-==========
-
-General questions
-=================
-
-Why does this project exist?
-----------------------------
-
-Django grew from a very practical need: World Online, a newspaper Web
-operation, is responsible for building intensive Web applications on journalism
-deadlines. In the fast-paced newsroom, World Online often has only a matter of
-hours to take a complicated Web application from concept to public launch.
-
-At the same time, the World Online Web developers have consistently been
-perfectionists when it comes to following best practices of Web development.
-
-In fall 2003, the World Online developers (Adrian Holovaty and Simon Willison)
-ditched PHP and began using Python to develop its Web sites. As they built
-intensive, richly interactive sites such as Lawrence.com, they began to extract
-a generic Web development framework that let them build Web applications more
-and more quickly. They tweaked this framework constantly, adding improvements
-over two years.
-
-In summer 2005, World Online decided to open-source the resulting software,
-Django. Django would not be possible without a whole host of open-source
-projects -- `Apache`_, `Python`_, and `PostgreSQL`_ to name a few -- and we're
-thrilled to be able to give something back to the open-source community.
-
-.. _Apache: http://httpd.apache.org/
-.. _Python: http://www.python.org/
-.. _PostgreSQL: http://www.postgresql.org/
-
-What does "Django" mean, and how do you pronounce it?
------------------------------------------------------
-
-Django is named after `Django Reinhardt`_, a gypsy jazz guitarist from the 1930s
-to early 1950s. To this day, he's considered one of the best guitarists of all time.
-
-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?
------------------
-
-Yes. World Online has been using Django for more than three years. Sites built
-on Django have weathered traffic spikes of over one million hits an hour and a
-number of Slashdottings. Yes, it's quite stable.
-
-Does Django scale?
-------------------
-
-Yes. Compared to development time, hardware is cheap, and so Django is
-designed to take advantage of as much hardware as you can throw at it.
-
-Django uses a "shared-nothing" architecture, which means you can add hardware
-at any level -- database servers, caching servers or Web/application servers.
-
-The framework cleanly separates components such as its database layer and
-application layer. And it ships with a simple-yet-powerful `cache framework`_.
-
-.. _`cache framework`: ../cache/
-
-Who's behind this?
-------------------
-
-Django was developed at `World Online`_, the Web department of a newspaper in
-Lawrence, Kansas, USA.
-
-`Adrian Holovaty`_
-    Adrian is a Web developer with a background in journalism. He was lead
-    developer at World Online for 2.5 years, during which time Django was
-    developed and implemented on World Online's sites. Now he works for
-    washingtonpost.com building rich, database-backed information sites, and
-    continues to oversee Django development. He likes playing guitar (Django
-    Reinhardt style) and hacking on side projects such as `chicagocrime.org`_.
-    He lives in Chicago.
-
-    On IRC, Adrian goes by ``adrian_h``.
-
-`Jacob Kaplan-Moss`_
-    Jacob is a whipper-snapper from California who spends equal time coding and
-    cooking. He's lead developer at World Online and actively hacks on various
-    cool side projects. He's contributed to the Python-ObjC bindings and was
-    the first guy to figure out how to write Tivo apps in Python. Lately he's
-    been messing with Python on the PSP. He lives in Lawrence, Kansas.
-
-    On IRC, Jacob goes by ``jacobkm``.
-
-`Simon Willison`_
-    Simon is a well-respected Web developer from England. He had a one-year
-    internship at World Online, during which time he and Adrian developed
-    Django from scratch. The most enthusiastic Brit you'll ever meet, he's
-    passionate about best practices in Web development and has maintained a
-    well-read Web-development blog for years at http://simon.incutio.com.
-    He works for Yahoo UK, where he managed to score the title "Hacker Liason."
-    He lives in London.
-
-    On IRC, Simon goes by ``SimonW``.
-
-`Wilson Miner`_
-    Wilson's design-fu makes us all look like rock stars. By day, he's an
-    interactive designer for `Apple`_. Don't ask him what he's working on, or
-    he'll have to kill you. He lives in San Francisco.
-
-    On IRC, Wilson goes by ``wilsonian``.
-
-.. _`World Online`: http://code.djangoproject.com/wiki/WorldOnline
-.. _`Adrian Holovaty`: http://www.holovaty.com/
-.. _`washingtonpost.com`: http://www.washingtonpost.com/
-.. _`chicagocrime.org`: http://www.chicagocrime.org/
-.. _`Simon Willison`: http://simon.incutio.com/
-.. _`simon.incutio.com`: http://simon.incutio.com/
-.. _`Jacob Kaplan-Moss`: http://www.jacobian.org/
-.. _`Wilson Miner`: http://www.wilsonminer.com/
-.. _`Apple`: http://www.apple.com/
-
-Which sites use Django?
------------------------
-
-The Django wiki features a consistently growing `list of Django-powered sites`_.
-Feel free to add your Django-powered site to the list.
-
-.. _list of Django-powered sites: http://code.djangoproject.com/wiki/DjangoPoweredSites
-
-Django appears to be a MVC framework, but you call the Controller the "view", and the View the "template". How come you don't use the standard names?
------------------------------------------------------------------------------------------------------------------------------------------------------
-
-Well, the standard names are debatable.
-
-In our interpretation of MVC, the "view" describes the data that gets presented
-to the user. It's not necessarily *how* the data *looks*, but *which* data is
-presented. The view describes *which data you see*, not *how you see it.* It's
-a subtle distinction.
-
-So, in our case, a "view" is the Python callback function for a particular URL,
-because that callback function describes which data is presented.
-
-Furthermore, it's sensible to separate content from presentation -- which is
-where templates come in. In Django, a "view" describes which data is presented,
-but a view normally delegates to a template, which describes *how* the data is
-presented.
-
-Where does the "controller" fit in, then? In Django's case, it's probably the
-framework itself: the machinery that sends a request to the appropriate view,
-according to the Django URL configuration.
-
-If you're hungry for acronyms, you might say that Django is a "MTV" framework
--- that is, "model", "template", and "view." That breakdown makes much more
-sense.
-
-At the end of the day, of course, it comes down to getting stuff done. And,
-regardless of how things are named, Django gets stuff done in a way that's most
-logical to us.
-
-<Framework X> does <feature Y> -- why doesn't Django?
------------------------------------------------------
-
-We're well aware that there are other awesome Web frameworks out there, and
-we're not averse to borrowing ideas where appropriate. However, Django was
-developed precisely because we were unhappy with the status quo, so please be
-aware that "because <Framework X> does it" is not going to be sufficient reason
-to add a given feature to Django.
-
-Why did you write all of Django from scratch, instead of using other Python libraries?
---------------------------------------------------------------------------------------
-
-When Django was originally written a couple of years ago, Adrian and Simon
-spent quite a bit of time exploring the various Python Web frameworks
-available.
-
-In our opinion, none of them were completely up to snuff.
-
-We're picky. You might even call us perfectionists. (With deadlines.)
-
-Over time, we stumbled across open-source libraries that did things we'd
-already implemented. It was reassuring to see other people solving similar
-problems in similar ways, but it was too late to integrate outside code: We'd
-already written, tested and implemented our own framework bits in several
-production settings -- and our own code met our needs delightfully.
-
-In most cases, however, we found that existing frameworks/tools inevitably had
-some sort of fundamental, fatal flaw that made us squeamish. No tool fit our
-philosophies 100%.
-
-Like we said: We're picky.
-
-We've documented our philosophies on the `design philosophies page`_.
-
-.. _design philosophies page: ../design_philosophies/
-
-Do you have any of those nifty "screencast" things?
----------------------------------------------------
-
-You can bet your bottom they're on the way. But, since we're still hammering
-out a few points, we want to make sure they reflect the final state of things
-at Django 1.0, not some intermediary step. In other words, we don't want to
-spend a lot of energy creating screencasts yet, because Django APIs will shift.
-
-Is Django a content-management-system (CMS)?
---------------------------------------------
-
-No, Django is not a CMS, or any sort of "turnkey product" in and of itself.
-It's a Web framework; it's a programming tool that lets you build Web sites.
-
-For example, it doesn't make much sense to compare Django to something like
-Drupal_, because Django is something you use to *create* things like Drupal.
-
-Of course, Django's automatic admin site is fantastic and timesaving -- but
-the admin site is one module of Django the framework. Furthermore, although
-Django has special conveniences for building "CMS-y" apps, that doesn't mean
-it's not just as appropriate for building "non-CMS-y" apps (whatever that
-means!).
-
-.. _Drupal: http://drupal.org/
-
-When will you release Django 1.0?
----------------------------------
-
-See our `version one roadmap`_ for the detailed timeline. We're aiming for
-September 2, 2008.
-
-.. _version one roadmap: http://code.djangoproject.com/wiki/VersionOneRoadmap
-
-How can I download the Django documentation to read it offline?
----------------------------------------------------------------
-
-The Django docs are available in the ``docs`` directory of each Django tarball
-release. These docs are in ReST (ReStructured Text) format, and each text file
-corresponds to a Web page on the official Django site.
-
-Because the documentation is `stored in revision control`_, you can browse
-documentation changes just like you can browse code changes.
-
-Technically, the docs on Django's site are generated from the latest development
-versions of those ReST documents, so the docs on the Django site may offer more
-information than the docs that come with the latest Django release.
-
-.. _stored in revision control: http://code.djangoproject.com/browser/django/trunk/docs
-
-Where can I find Django developers for hire?
---------------------------------------------
-
-Consult our `developers for hire page`_ for a list of Django developers who
-would be happy to help you.
-
-You might also be interested in posting a job to http://djangogigs.com/ .
-If you want to find Django-capable people in your local area, try
-http://djangopeople.net/ .
-
-.. _developers for hire page: http://code.djangoproject.com/wiki/DevelopersForHire
-
-Installation questions
-======================
-
-How do I get started?
----------------------
-
-    #. `Download the code`_.
-    #. Install Django (read the `installation guide`_).
-    #. Walk through the tutorial_.
-    #. Check out the rest of the documentation_, and `ask questions`_ if you
-       run into trouble.
-
-.. _`Download the code`: http://www.djangoproject.com/download/
-.. _`installation guide`: ../install/
-.. _tutorial:  ../tutorial01/
-.. _documentation: ../
-.. _ask questions: http://www.djangoproject.com/community/
-
-How do I fix the "install a later version of setuptools" error?
----------------------------------------------------------------
-
-Just run the ``ez_setup.py`` script in the Django distribution.
-
-What are Django's prerequisites?
---------------------------------
-
-Django requires Python_ 2.3 or later. No other Python libraries are required
-for basic Django usage.
-
-For a development environment -- if you just want to experiment with Django --
-you don't need to have a separate Web server installed; Django comes with its
-own lightweight development server. For a production environment, we recommend
-`Apache 2`_ and mod_python_, although Django follows the WSGI_ spec, which
-means it can run on a variety of server platforms.
-
-If you want to use Django with a database, which is probably the case, you'll
-also need a database engine. PostgreSQL_ is recommended, because we're
-PostgreSQL fans, and MySQL_, `SQLite 3`_, and Oracle_ are also supported.
-
-.. _Python: http://www.python.org/
-.. _Apache 2: http://httpd.apache.org/
-.. _mod_python: http://www.modpython.org/
-.. _WSGI: http://www.python.org/peps/pep-0333.html
-.. _PostgreSQL: http://www.postgresql.org/
-.. _MySQL: http://www.mysql.com/
-.. _`SQLite 3`: http://www.sqlite.org/
-.. _Oracle: http://www.oracle.com/
-
-Do I lose anything by using Python 2.3 versus newer Python versions, such as Python 2.5?
-----------------------------------------------------------------------------------------
-
-No. Django itself is guaranteed to work with any version of Python from 2.3
-and higher.
-
-If you use a Python version newer than 2.3, you will, of course, be able to
-take advantage of newer Python features in your own code, along with the speed
-improvements and other optimizations that have been made to the Python language
-itself. But the Django framework itself should work equally well on 2.3 as it
-does on 2.4 or 2.5.
-
-Do I have to use mod_python?
-----------------------------
-
-Although we recommend mod_python for production use, you don't have to use it,
-thanks to the fact that Django uses an arrangement called WSGI_. Django can
-talk to any WSGI-enabled server. Other non-mod_python deployment setups are
-FastCGI, SCGI or AJP. See `How to use Django with FastCGI, SCGI or AJP`_ for
-full information.
-
-Also, see the `server arrangements wiki page`_ for other deployment strategies.
-
-If you just want to play around and develop things on your local computer, use
-the development Web server that comes with Django. Things should Just Work.
-
-.. _WSGI: http://www.python.org/peps/pep-0333.html
-.. _How to use Django with FastCGI, SCGI or AJP: ../fastcgi/
-.. _server arrangements wiki page: http://code.djangoproject.com/wiki/ServerArrangements
-
-How do I install mod_python on Windows?
----------------------------------------
-
-    * For Python 2.4, grab mod_python from `win32 build of mod_python for
-      Python 2.4`_.
-    * For Python 2.4, check out this `Django on Windows howto`_.
-    * For Python 2.3, grab mod_python from http://www.modpython.org/ and read
-      `Running mod_python on Apache on Windows2000`_.
-    * Also, try this (not Windows-specific) `guide to getting mod_python
-      working`_.
-
-.. _`win32 build of mod_python for Python 2.4`: http://www.lehuen.com/nicolas/index.php/2005/02/21/39-win32-build-of-mod_python-314-for-python-24
-.. _`Django on Windows howto`: http://thinkhole.org/wp/django-on-windows/
-.. _`Running mod_python on Apache on Windows2000`: http://groups-beta.google.com/group/comp.lang.python/msg/139af8c83a5a9d4f
-.. _`guide to getting mod_python working`: http://www.dscpl.com.au/articles/modpython-001.html
-
-Will Django run under shared hosting (like TextDrive or Dreamhost)?
--------------------------------------------------------------------
-
-See our `Django-friendly Web hosts`_ page.
-
-.. _`Django-friendly Web hosts`: http://code.djangoproject.com/wiki/DjangoFriendlyWebHosts
-
-Should I use the official version or development version?
----------------------------------------------------------
-
-The Django developers improve Django every day and are pretty good about not
-checking in broken code. We use the development code (from the Subversion
-repository) directly on our servers, so we consider it stable. With that in
-mind, we recommend that you use the latest development code, because it
-generally contains more features and fewer bugs than the "official" releases.
-
-Using Django
-============
-
-Why do I get an error about importing DJANGO_SETTINGS_MODULE?
--------------------------------------------------------------
-
-Make sure that:
-
-    * The environment variable DJANGO_SETTINGS_MODULE is set to a fully-qualified
-      Python module (i.e. "mysite.settings").
-
-    * Said module is on ``sys.path`` (``import mysite.settings`` should work).
-
-    * The module doesn't contain syntax errors (of course).
-
-    * If you're using mod_python but *not* using Django's request handler,
-      you'll need to work around a mod_python bug related to the use of
-      ``SetEnv``; before you import anything from Django you'll need to do
-      the following::
-
-            os.environ.update(req.subprocess_env)
-
-      (where ``req`` is the mod_python request object).
-
-I can't stand your template language. Do I have to use it?
-----------------------------------------------------------
-
-We happen to think our template engine is the best thing since chunky bacon,
-but we recognize that choosing a template language runs close to religion.
-There's nothing about Django that requires using the template language, so
-if you're attached to ZPT, Cheetah, or whatever, feel free to use those.
-
-Do I have to use your model/database layer?
--------------------------------------------
-
-Nope. Just like the template system, the model/database layer is decoupled from
-the rest of the framework.
-
-The one exception is: If you use a different database library, you won't get to
-use Django's automatically-generated admin site. That app is coupled to the
-Django database layer.
-
-How do I use image and file fields?
------------------------------------
-
-Using a ``FileField`` or an ``ImageField`` in a model takes a few steps:
-
-    #. In your settings file, define ``MEDIA_ROOT`` as the full path to
-       a directory where you'd like Django to store uploaded files. (For
-       performance, these files are not stored in the database.) Define
-       ``MEDIA_URL`` as the base public URL of that directory. Make sure that
-       this directory is writable by the Web server's user account.
-
-    #. Add the ``FileField`` or ``ImageField`` to your model, making sure
-       to define the ``upload_to`` option to tell Django to which subdirectory
-       of ``MEDIA_ROOT`` it should upload files.
-
-    #. All that will be stored in your database is a path to the file
-       (relative to ``MEDIA_ROOT``). You'll most likely want to use the
-       convenience ``get_<fieldname>_url`` function provided by Django. For
-       example, if your ``ImageField`` is called ``mug_shot``, you can get the
-       absolute URL to your image in a template with
-       ``{{ object.get_mug_shot_url }}``.
-
-Databases and models
-====================
-
-How can I see the raw SQL queries Django is running?
-----------------------------------------------------
-
-Make sure your Django ``DEBUG`` setting is set to ``True``. Then, just do
-this::
-
-    >>> from django.db import connection
-    >>> connection.queries
-    [{'sql': 'SELECT polls_polls.id,polls_polls.question,polls_polls.pub_date FROM polls_polls',
-    'time': '0.002'}]
-
-``connection.queries`` is only available if ``DEBUG`` is ``True``. It's a list
-of dictionaries in order of query execution. Each dictionary has the following::
-
-    ``sql`` -- The raw SQL statement
-    ``time`` -- How long the statement took to execute, in seconds.
-
-``connection.queries`` includes all SQL statements -- INSERTs, UPDATES,
-SELECTs, etc. Each time your app hits the database, the query will be recorded.
-
-Can I use Django with a pre-existing database?
-----------------------------------------------
-
-Yes. See `Integrating with a legacy database`_.
-
-.. _`Integrating with a legacy database`: ../legacy_databases/
-
-If I make changes to a model, how do I update the database?
------------------------------------------------------------
-
-If you don't mind clearing data, your project's ``manage.py`` utility has an
-option to reset the SQL for a particular application::
-
-    manage.py reset appname
-
-This drops any tables associated with ``appname`` and recreates them.
-
-If you do care about deleting data, you'll have to execute the ``ALTER TABLE``
-statements manually in your database. That's the way we've always done it,
-because dealing with data is a very sensitive operation that we've wanted to
-avoid automating. That said, there's some work being done to add partially
-automated database-upgrade functionality.
-
-Do Django models support multiple-column primary keys?
-------------------------------------------------------
-
-No. Only single-column primary keys are supported.
-
-But this isn't an issue in practice, because there's nothing stopping you from
-adding other constraints (using the ``unique_together`` model option or
-creating the constraint directly in your database), and enforcing the
-uniqueness at that level. Single-column primary keys are needed for things such
-as the admin interface to work; e.g., you need a simple way of being able to
-specify an object to edit or delete.
-
-How do I add database-specific options to my CREATE TABLE statements, such as specifying MyISAM as the table type?
-------------------------------------------------------------------------------------------------------------------
-
-We try to avoid adding special cases in the Django code to accommodate all the
-database-specific options such as table type, etc. If you'd like to use any of
-these options, create an `SQL initial data file`_ that contains ``ALTER TABLE``
-statements that do what you want to do. The initial data files are executed in
-your database after the ``CREATE TABLE`` statements.
-
-For example, if you're using MySQL and want your tables to use the MyISAM table
-type, create an initial data file and put something like this in it::
-
-    ALTER TABLE myapp_mytable ENGINE=MyISAM;
-
-As explained in the `SQL initial data file`_ documentation, this SQL file can
-contain arbitrary SQL, so you can make any sorts of changes you need to make.
-
-.. _SQL initial data file: ../model-api/#providing-initial-sql-data
-
-Why is Django leaking memory?
------------------------------
-
-Django isn't known to leak memory. If you find your Django processes are
-allocating more and more memory, with no sign of releasing it, check to make
-sure your ``DEBUG`` setting is set to ``True``. If ``DEBUG`` is ``True``, then
-Django saves a copy of every SQL statement it has executed.
-
-(The queries are saved in ``django.db.connection.queries``. See
-`How can I see the raw SQL queries Django is running?`_.)
-
-To fix the problem, set ``DEBUG`` to ``False``.
-
-If you need to clear the query list manually at any point in your functions,
-just call ``reset_queries()``, like this::
-
-    from django import db
-    db.reset_queries()
-
-The admin site
-==============
-
-I can't log in. When I enter a valid username and password, it just brings up the login page again, with no error messages.
----------------------------------------------------------------------------------------------------------------------------
-
-The login cookie isn't being set correctly, because the domain of the cookie
-sent out by Django doesn't match the domain in your browser. Try these two
-things:
-
-    * Set the ``SESSION_COOKIE_DOMAIN`` setting in your admin config file
-      to match your domain. For example, if you're going to
-      "http://www.mysite.com/admin/" in your browser, in
-      "myproject.settings" you should set ``SESSION_COOKIE_DOMAIN = 'www.mysite.com'``.
-
-    * Some browsers (Firefox?) don't like to accept cookies from domains that
-      don't have dots in them. If you're running the admin site on "localhost"
-      or another domain that doesn't have a dot in it, try going to
-      "localhost.localdomain" or "127.0.0.1". And set
-      ``SESSION_COOKIE_DOMAIN`` accordingly.
-
-I can't log in. When I enter a valid username and password, it brings up the login page again, with a "Please enter a correct username and password" error.
------------------------------------------------------------------------------------------------------------------------------------------------------------
-
-If you're sure your username and password are correct, make sure your user
-account has ``is_active`` and ``is_staff`` set to True. The admin site only
-allows access to users with those two fields both set to True.
-
-How can I prevent the cache middleware from caching the admin site?
--------------------------------------------------------------------
-
-Set the ``CACHE_MIDDLEWARE_ANONYMOUS_ONLY`` setting to ``True``. See the
-`cache documentation`_ for more information.
-
-.. _cache documentation: ../cache/#the-per-site-cache
-
-How do I automatically set a field's value to the user who last edited the object in the admin?
------------------------------------------------------------------------------------------------
-
-At this point, Django doesn't have an official way to do this. But it's an oft-requested
-feature, so we're discussing how it can be implemented. The problem is we don't want to couple
-the model layer with the admin layer with the request layer (to get the current user). It's a
-tricky problem.
-
-One person hacked up a `solution that doesn't require patching Django`_, but note that it's an
-unofficial solution, and there's no guarantee it won't break at some point.
-
-.. _solution that doesn't require patching Django: http://lukeplant.me.uk/blog.php?id=1107301634
-
-How do I limit admin access so that objects can only be edited by the users who created them?
----------------------------------------------------------------------------------------------
-
-See the answer to the previous question.
-
-My admin-site CSS and images showed up fine using the development server, but they're not displaying when using mod_python.
----------------------------------------------------------------------------------------------------------------------------
-
-See `serving the admin files`_ in the "How to use Django with mod_python"
-documentation.
-
-.. _serving the admin files: ../modpython/#serving-the-admin-files
-
-My "list_filter" contains a ManyToManyField, but the filter doesn't display.
-----------------------------------------------------------------------------
-
-Django won't bother displaying the filter for a ``ManyToManyField`` if there
-are fewer than two related objects.
-
-For example, if your ``list_filter`` includes ``sites``, and there's only one
-site in your database, it won't display a "Site" filter. In that case,
-filtering by site would be meaningless.
-
-How can I customize the functionality of the admin interface?
--------------------------------------------------------------
-
-You've got several options. If you want to piggyback on top of an add/change
-form that Django automatically generates, you can attach arbitrary JavaScript
-modules to the page via the model's ``class Admin`` ``js`` parameter. That
-parameter is a list of URLs, as strings, pointing to JavaScript modules that
-will be included within the admin form via a ``<script>`` tag.
-
-If you want more flexibility than simply tweaking the auto-generated forms,
-feel free to write custom views for the admin. The admin is powered by Django
-itself, and you can write custom views that hook into the authentication
-system, check permissions and do whatever else they need to do.
-
-If you want to customize the look-and-feel of the admin interface, read the
-next question.
-
-The dynamically-generated admin site is ugly! How can I change it?
-------------------------------------------------------------------
-
-We like it, but if you don't agree, you can modify the admin site's
-presentation by editing the CSS stylesheet and/or associated image files. The
-site is built using semantic HTML and plenty of CSS hooks, so any changes you'd
-like to make should be possible by editing the stylesheet. We've got a
-`guide to the CSS used in the admin`_ to get you started.
-
-.. _`guide to the CSS used in the admin`: ../admin_css/
-
-How do I create users without having to edit password hashes?
--------------------------------------------------------------
-
-If you'd like to use the admin site to create users, upgrade to the Django
-development version, where this problem was fixed on Aug. 4, 2006.
-
-You can also use the Python API. See `creating users`_ for full info.
-
-.. _creating users: ../authentication/#creating-users
-
-Getting help
-============
-
-How do I do X? Why doesn't Y work? Where can I go to get help?
---------------------------------------------------------------
-
-If this FAQ doesn't contain an answer to your question, you might want to
-try the `django-users mailing list`_. Feel free to ask any question related
-to installing, using, or debugging Django.
-
-If you prefer IRC, the `#django IRC channel`_ on the Freenode IRC network is an
-active community of helpful individuals who may be able to solve your problem.
-
-.. _`django-users mailing list`: http://groups.google.com/group/django-users
-.. _`#django IRC channel`: irc://irc.freenode.net/django
-
-Why hasn't my message appeared on django-users?
------------------------------------------------
-
-django-users_ has a lot of subscribers. This is good for the community, as
-it means many people are available to contribute answers to questions.
-Unfortunately, it also means that django-users_ is an attractive target for
-spammers.
-
-In order to combat the spam problem, when you join the django-users_ mailing
-list, we manually moderate the first message you send to the list. This means
-that spammers get caught, but it also means that your first question to the
-list might take a little longer to get answered. We apologize for any
-inconvenience that this policy may cause.
-
-.. _django-users: http://groups.google.com/group/django-users
-
-Nobody on django-users answered my question! What should I do?
---------------------------------------------------------------
-
-Try making your question more specific, or provide a better example of your
-problem.
-
-As with most open-source mailing lists, the folks on django-users_ are
-volunteers. If nobody has answered your question, it may be because nobody
-knows the answer, it may be because nobody can understand the question, or it
-may be that everybody that can help is busy. One thing you might try is to ask
-the question on IRC -- visit the `#django IRC channel`_ on the Freenode IRC
-network.
-
-You might notice we have a second mailing list, called django-developers_ --
-but please don't e-mail support questions to this mailing list. This list is
-for discussion of the development of Django itself. Asking a tech support
-question there is considered quite impolite.
-
-.. _django-developers: http://groups.google.com/group/django-developers
-
-I think I've found a bug! What should I do?
--------------------------------------------
-
-Detailed instructions on how to handle a potential bug can be found in our
-`Guide to contributing to Django`_.
-
-.. _`Guide to contributing to Django`: ../contributing/#reporting-bugs
-
-I think I've found a security problem! What should I do?
---------------------------------------------------------
-
-If you think you've found a security problem with Django, please send a message
-to security@djangoproject.com. This is a private list only open to long-time,
-highly trusted Django developers, and its archives are not publicly readable.
-
-Due to the sensitive nature of security issues, we ask that if you think you
-have found a security problem, *please* don't send a message to one of the
-public mailing lists. Django has a `policy for handling security issues`_;
-while a defect is outstanding, we would like to minimize any damage that
-could be inflicted through public knowledge of that defect.
-
-.. _`policy for handling security issues`: ../contributing/#reporting-security-issues
-
-Contributing code
-=================
-
-How can I get started contributing code to Django?
---------------------------------------------------
-
-Thanks for asking! We've written an entire document devoted to this question.
-It's titled `Contributing to Django`_.
-
-.. _`Contributing to Django`: ../contributing/
-
-I submitted a bug fix in the ticket system several weeks ago. Why are you ignoring my patch?
---------------------------------------------------------------------------------------------
-
-Don't worry: We're not ignoring you!
-
-It's important to understand there is a difference between "a ticket is being
-ignored" and "a ticket has not been attended to yet." Django's ticket system
-contains hundreds of open tickets, of various degrees of impact on end-user
-functionality, and Django's developers have to review and prioritize.
-
-On top of that: the people who work on Django are all volunteers. As a result,
-the amount of time that we have to work on the framework is limited and will
-vary from week to week depending on our spare time. If we're busy, we may not
-be able to spend as much time on Django as we might want.
-
-Besides, if your feature request stands no chance of inclusion in Django, we
-won't ignore it -- we'll just close the ticket. So if your ticket is still
-open, it doesn't mean we're ignoring you; it just means we haven't had time to
-look at it yet.

+ 103 - 0
docs/faq/admin.txt

@@ -0,0 +1,103 @@
+.. _faq-admin:
+
+FAQ: The admin
+==============
+
+I can't log in. When I enter a valid username and password, it just brings up the login page again, with no error messages.
+---------------------------------------------------------------------------------------------------------------------------
+
+The login cookie isn't being set correctly, because the domain of the cookie
+sent out by Django doesn't match the domain in your browser. Try these two
+things:
+
+    * Set the ``SESSION_COOKIE_DOMAIN`` setting in your admin config file
+      to match your domain. For example, if you're going to
+      "http://www.example.com/admin/" in your browser, in
+      "myproject.settings" you should set ``SESSION_COOKIE_DOMAIN = 'www.example.com'``.
+
+    * Some browsers (Firefox?) don't like to accept cookies from domains that
+      don't have dots in them. If you're running the admin site on "localhost"
+      or another domain that doesn't have a dot in it, try going to
+      "localhost.localdomain" or "127.0.0.1". And set
+      ``SESSION_COOKIE_DOMAIN`` accordingly.
+
+I can't log in. When I enter a valid username and password, it brings up the login page again, with a "Please enter a correct username and password" error.
+-----------------------------------------------------------------------------------------------------------------------------------------------------------
+
+If you're sure your username and password are correct, make sure your user
+account has ``is_active`` and ``is_staff`` set to True. The admin site only
+allows access to users with those two fields both set to True.
+
+How can I prevent the cache middleware from caching the admin site?
+-------------------------------------------------------------------
+
+Set the :setting:``CACHE_MIDDLEWARE_ANONYMOUS_ONLY`` setting to ``True``. See the
+:ref:`cache documentation <topics-cache>` for more information.
+
+How do I automatically set a field's value to the user who last edited the object in the admin?
+-----------------------------------------------------------------------------------------------
+
+At this point, Django doesn't have an official way to do this. But it's an oft-requested
+feature, so we're discussing how it can be implemented. The problem is we don't want to couple
+the model layer with the admin layer with the request layer (to get the current user). It's a
+tricky problem.
+
+One person hacked up a `solution that doesn't require patching Django`_, but note that it's an
+unofficial solution, and there's no guarantee it won't break at some point.
+
+.. _solution that doesn't require patching Django: http://lukeplant.me.uk/blog.php?id=1107301634
+
+How do I limit admin access so that objects can only be edited by the users who created them?
+---------------------------------------------------------------------------------------------
+
+See the answer to the previous question.
+
+My admin-site CSS and images showed up fine using the development server, but they're not displaying when using mod_python.
+---------------------------------------------------------------------------------------------------------------------------
+
+See :ref:`serving the admin files <howto-deployment-modpython-serving-the-admin-files`
+in the "How to use Django with mod_python" documentation.
+
+My "list_filter" contains a ManyToManyField, but the filter doesn't display.
+----------------------------------------------------------------------------
+
+Django won't bother displaying the filter for a ``ManyToManyField`` if there
+are fewer than two related objects.
+
+For example, if your ``list_filter`` includes ``sites``, and there's only one
+site in your database, it won't display a "Site" filter. In that case,
+filtering by site would be meaningless.
+
+How can I customize the functionality of the admin interface?
+-------------------------------------------------------------
+
+You've got several options. If you want to piggyback on top of an add/change
+form that Django automatically generates, you can attach arbitrary JavaScript
+modules to the page via the model's ``class Admin`` ``js`` parameter. That
+parameter is a list of URLs, as strings, pointing to JavaScript modules that
+will be included within the admin form via a ``<script>`` tag.
+
+If you want more flexibility than simply tweaking the auto-generated forms,
+feel free to write custom views for the admin. The admin is powered by Django
+itself, and you can write custom views that hook into the authentication
+system, check permissions and do whatever else they need to do.
+
+If you want to customize the look-and-feel of the admin interface, read the
+next question.
+
+The dynamically-generated admin site is ugly! How can I change it?
+------------------------------------------------------------------
+
+We like it, but if you don't agree, you can modify the admin site's
+presentation by editing the CSS stylesheet and/or associated image files. The
+site is built using semantic HTML and plenty of CSS hooks, so any changes you'd
+like to make should be possible by editing the stylesheet. We've got a
+:ref:`guide to the CSS used in the admin <obsolete-admin-css>` to get you started.
+
+How do I create users without having to edit password hashes?
+-------------------------------------------------------------
+
+If you'd like to use the admin site to create users, upgrade to the Django
+development version, where this problem was fixed on Aug. 4, 2006.
+
+You can also use the Python API. See :ref:`creating users <topics-auth-creating-users>` for full info.

+ 30 - 0
docs/faq/contributing.txt

@@ -0,0 +1,30 @@
+.. _faq-contributing:
+
+FAQ: Contributing code
+======================
+
+How can I get started contributing code to Django?
+--------------------------------------------------
+
+Thanks for asking! We've written an entire document devoted to this question.
+It's titled :ref:`Contributing to Django <internals-contributing>`.
+
+I submitted a bug fix in the ticket system several weeks ago. Why are you ignoring my patch?
+--------------------------------------------------------------------------------------------
+
+Don't worry: We're not ignoring you!
+
+It's important to understand there is a difference between "a ticket is being
+ignored" and "a ticket has not been attended to yet." Django's ticket system
+contains hundreds of open tickets, of various degrees of impact on end-user
+functionality, and Django's developers have to review and prioritize.
+
+On top of that: the people who work on Django are all volunteers. As a result,
+the amount of time that we have to work on the framework is limited and will
+vary from week to week depending on our spare time. If we're busy, we may not
+be able to spend as much time on Django as we might want.
+
+Besides, if your feature request stands no chance of inclusion in Django, we
+won't ignore it -- we'll just close the ticket. So if your ticket is still
+open, it doesn't mean we're ignoring you; it just means we haven't had time to
+look at it yet.

+ 256 - 0
docs/faq/general.txt

@@ -0,0 +1,256 @@
+.. _faq-general:
+
+FAQ: General
+============
+
+Why does this project exist?
+----------------------------
+
+Django grew from a very practical need: World Online, a newspaper Web
+operation, is responsible for building intensive Web applications on journalism
+deadlines. In the fast-paced newsroom, World Online often has only a matter of
+hours to take a complicated Web application from concept to public launch.
+
+At the same time, the World Online Web developers have consistently been
+perfectionists when it comes to following best practices of Web development.
+
+In fall 2003, the World Online developers (Adrian Holovaty and Simon Willison)
+ditched PHP and began using Python to develop its Web sites. As they built
+intensive, richly interactive sites such as Lawrence.com, they began to extract
+a generic Web development framework that let them build Web applications more
+and more quickly. They tweaked this framework constantly, adding improvements
+over two years.
+
+In summer 2005, World Online decided to open-source the resulting software,
+Django. Django would not be possible without a whole host of open-source
+projects -- `Apache`_, `Python`_, and `PostgreSQL`_ to name a few -- and we're
+thrilled to be able to give something back to the open-source community.
+
+.. _Apache: http://httpd.apache.org/
+.. _Python: http://www.python.org/
+.. _PostgreSQL: http://www.postgresql.org/
+
+What does "Django" mean, and how do you pronounce it?
+-----------------------------------------------------
+
+Django is named after `Django Reinhardt`_, a gypsy jazz guitarist from the 1930s
+to early 1950s. To this day, he's considered one of the best guitarists of all time.
+
+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?
+-----------------
+
+Yes. World Online has been using Django for more than three years. Sites built
+on Django have weathered traffic spikes of over one million hits an hour and a
+number of Slashdottings. Yes, it's quite stable.
+
+Does Django scale?
+------------------
+
+Yes. Compared to development time, hardware is cheap, and so Django is
+designed to take advantage of as much hardware as you can throw at it.
+
+Django uses a "shared-nothing" architecture, which means you can add hardware
+at any level -- database servers, caching servers or Web/application servers.
+
+The framework cleanly separates components such as its database layer and
+application layer. And it ships with a simple-yet-powerful
+:ref:`cache framework <topics-cache>`.
+
+Who's behind this?
+------------------
+
+Django was developed at `World Online`_, the Web department of a newspaper in
+Lawrence, Kansas, USA.
+
+`Adrian Holovaty`_
+    Adrian is a Web developer with a background in journalism. He was lead
+    developer at World Online for 2.5 years, during which time Django was
+    developed and implemented on World Online's sites. Now he works for
+    washingtonpost.com building rich, database-backed information sites, and
+    continues to oversee Django development. He likes playing guitar (Django
+    Reinhardt style) and hacking on side projects such as `chicagocrime.org`_.
+    He lives in Chicago.
+
+    On IRC, Adrian goes by ``adrian_h``.
+
+`Jacob Kaplan-Moss`_
+    Jacob is a whipper-snapper from California who spends equal time coding and
+    cooking. He's lead developer at World Online and actively hacks on various
+    cool side projects. He's contributed to the Python-ObjC bindings and was
+    the first guy to figure out how to write Tivo apps in Python. Lately he's
+    been messing with Python on the PSP. He lives in Lawrence, Kansas.
+
+    On IRC, Jacob goes by ``jacobkm``.
+
+`Simon Willison`_
+    Simon is a well-respected Web developer from England. He had a one-year
+    internship at World Online, during which time he and Adrian developed
+    Django from scratch. The most enthusiastic Brit you'll ever meet, he's
+    passionate about best practices in Web development and has maintained a
+    well-read Web-development blog for years at http://simon.incutio.com.
+    He works for Yahoo UK, where he managed to score the title "Hacker Liason."
+    He lives in London.
+
+    On IRC, Simon goes by ``SimonW``.
+
+`Wilson Miner`_
+    Wilson's design-fu makes us all look like rock stars. By day, he's an
+    interactive designer for `Apple`_. Don't ask him what he's working on, or
+    he'll have to kill you. He lives in San Francisco.
+
+    On IRC, Wilson goes by ``wilsonian``.
+
+.. _`World Online`: http://code.djangoproject.com/wiki/WorldOnline
+.. _`Adrian Holovaty`: http://www.holovaty.com/
+.. _`washingtonpost.com`: http://www.washingtonpost.com/
+.. _`chicagocrime.org`: http://www.chicagocrime.org/
+.. _`Simon Willison`: http://simon.incutio.com/
+.. _`simon.incutio.com`: http://simon.incutio.com/
+.. _`Jacob Kaplan-Moss`: http://www.jacobian.org/
+.. _`Wilson Miner`: http://www.wilsonminer.com/
+.. _`Apple`: http://www.apple.com/
+
+Which sites use Django?
+-----------------------
+
+The Django wiki features a consistently growing `list of Django-powered sites`_.
+Feel free to add your Django-powered site to the list.
+
+.. _list of Django-powered sites: http://code.djangoproject.com/wiki/DjangoPoweredSites
+
+.. _mtv:
+
+Django appears to be a MVC framework, but you call the Controller the "view", and the View the "template". How come you don't use the standard names?
+-----------------------------------------------------------------------------------------------------------------------------------------------------
+
+Well, the standard names are debatable.
+
+In our interpretation of MVC, the "view" describes the data that gets presented
+to the user. It's not necessarily *how* the data *looks*, but *which* data is
+presented. The view describes *which data you see*, not *how you see it.* It's
+a subtle distinction.
+
+So, in our case, a "view" is the Python callback function for a particular URL,
+because that callback function describes which data is presented.
+
+Furthermore, it's sensible to separate content from presentation -- which is
+where templates come in. In Django, a "view" describes which data is presented,
+but a view normally delegates to a template, which describes *how* the data is
+presented.
+
+Where does the "controller" fit in, then? In Django's case, it's probably the
+framework itself: the machinery that sends a request to the appropriate view,
+according to the Django URL configuration.
+
+If you're hungry for acronyms, you might say that Django is a "MTV" framework
+-- that is, "model", "template", and "view." That breakdown makes much more
+sense.
+
+At the end of the day, of course, it comes down to getting stuff done. And,
+regardless of how things are named, Django gets stuff done in a way that's most
+logical to us.
+
+<Framework X> does <feature Y> -- why doesn't Django?
+-----------------------------------------------------
+
+We're well aware that there are other awesome Web frameworks out there, and
+we're not averse to borrowing ideas where appropriate. However, Django was
+developed precisely because we were unhappy with the status quo, so please be
+aware that "because <Framework X> does it" is not going to be sufficient reason
+to add a given feature to Django.
+
+Why did you write all of Django from scratch, instead of using other Python libraries?
+--------------------------------------------------------------------------------------
+
+When Django was originally written a couple of years ago, Adrian and Simon
+spent quite a bit of time exploring the various Python Web frameworks
+available.
+
+In our opinion, none of them were completely up to snuff.
+
+We're picky. You might even call us perfectionists. (With deadlines.)
+
+Over time, we stumbled across open-source libraries that did things we'd
+already implemented. It was reassuring to see other people solving similar
+problems in similar ways, but it was too late to integrate outside code: We'd
+already written, tested and implemented our own framework bits in several
+production settings -- and our own code met our needs delightfully.
+
+In most cases, however, we found that existing frameworks/tools inevitably had
+some sort of fundamental, fatal flaw that made us squeamish. No tool fit our
+philosophies 100%.
+
+Like we said: We're picky.
+
+We've documented our philosophies on the
+:ref:`design philosophies page <misc-design-philosophies>`.
+
+Do you have any of those nifty "screencast" things?
+---------------------------------------------------
+
+You can bet your bottom they're on the way. But, since we're still hammering
+out a few points, we want to make sure they reflect the final state of things
+at Django 1.0, not some intermediary step. In other words, we don't want to
+spend a lot of energy creating screencasts yet, because Django APIs will shift.
+
+Is Django a content-management-system (CMS)?
+--------------------------------------------
+
+No, Django is not a CMS, or any sort of "turnkey product" in and of itself.
+It's a Web framework; it's a programming tool that lets you build Web sites.
+
+For example, it doesn't make much sense to compare Django to something like
+Drupal_, because Django is something you use to *create* things like Drupal.
+
+Of course, Django's automatic admin site is fantastic and timesaving -- but
+the admin site is one module of Django the framework. Furthermore, although
+Django has special conveniences for building "CMS-y" apps, that doesn't mean
+it's not just as appropriate for building "non-CMS-y" apps (whatever that
+means!).
+
+.. _Drupal: http://drupal.org/
+
+When will you release Django 1.0?
+---------------------------------
+
+See our `version one roadmap`_ for the detailed timeline. We're aiming for
+September 2, 2008.
+
+.. _version one roadmap: http://code.djangoproject.com/wiki/VersionOneRoadmap
+
+How can I download the Django documentation to read it offline?
+---------------------------------------------------------------
+
+The Django docs are available in the ``docs`` directory of each Django tarball
+release. These docs are in ReST (ReStructured Text) format, and each text file
+corresponds to a Web page on the official Django site.
+
+Because the documentation is `stored in revision control`_, you can browse
+documentation changes just like you can browse code changes.
+
+Technically, the docs on Django's site are generated from the latest development
+versions of those ReST documents, so the docs on the Django site may offer more
+information than the docs that come with the latest Django release.
+
+.. _stored in revision control: http://code.djangoproject.com/browser/django/trunk/docs
+
+Where can I find Django developers for hire?
+--------------------------------------------
+
+Consult our `developers for hire page`_ for a list of Django developers who
+would be happy to help you.
+
+You might also be interested in posting a job to http://djangogigs.com/ .
+If you want to find Django-capable people in your local area, try
+http://djangopeople.net/ .
+
+.. _developers for hire page: http://code.djangoproject.com/wiki/DevelopersForHire

+ 75 - 0
docs/faq/help.txt

@@ -0,0 +1,75 @@
+.. _faq-help:
+
+FAQ: Getting Help
+=================
+
+How do I do X? Why doesn't Y work? Where can I go to get help?
+--------------------------------------------------------------
+
+If this FAQ doesn't contain an answer to your question, you might want to
+try the `django-users mailing list`_. Feel free to ask any question related
+to installing, using, or debugging Django.
+
+If you prefer IRC, the `#django IRC channel`_ on the Freenode IRC network is an
+active community of helpful individuals who may be able to solve your problem.
+
+.. _`django-users mailing list`: http://groups.google.com/group/django-users
+.. _`#django IRC channel`: irc://irc.freenode.net/django
+
+Why hasn't my message appeared on django-users?
+-----------------------------------------------
+
+django-users_ has a lot of subscribers. This is good for the community, as
+it means many people are available to contribute answers to questions.
+Unfortunately, it also means that django-users_ is an attractive target for
+spammers.
+
+In order to combat the spam problem, when you join the django-users_ mailing
+list, we manually moderate the first message you send to the list. This means
+that spammers get caught, but it also means that your first question to the
+list might take a little longer to get answered. We apologize for any
+inconvenience that this policy may cause.
+
+.. _django-users: http://groups.google.com/group/django-users
+
+Nobody on django-users answered my question! What should I do?
+--------------------------------------------------------------
+
+Try making your question more specific, or provide a better example of your
+problem.
+
+As with most open-source mailing lists, the folks on django-users_ are
+volunteers. If nobody has answered your question, it may be because nobody
+knows the answer, it may be because nobody can understand the question, or it
+may be that everybody that can help is busy. One thing you might try is to ask
+the question on IRC -- visit the `#django IRC channel`_ on the Freenode IRC
+network.
+
+You might notice we have a second mailing list, called django-developers_ --
+but please don't e-mail support questions to this mailing list. This list is
+for discussion of the development of Django itself. Asking a tech support
+question there is considered quite impolite.
+
+.. _django-developers: http://groups.google.com/group/django-developers
+
+I think I've found a bug! What should I do?
+-------------------------------------------
+
+Detailed instructions on how to handle a potential bug can be found in our
+:ref:`Guide to contributing to Django <reporting-bugs>`.
+
+I think I've found a security problem! What should I do?
+--------------------------------------------------------
+
+If you think you've found a security problem with Django, please send a message
+to security@djangoproject.com. This is a private list only open to long-time,
+highly trusted Django developers, and its archives are not publicly readable.
+
+Due to the sensitive nature of security issues, we ask that if you think you
+have found a security problem, *please* don't send a message to one of the
+public mailing lists. Django has a
+:ref:`policy for handling security issues <reporting-security-issues>`;
+while a defect is outstanding, we would like to minimize any damage that
+could be inflicted through public knowledge of that defect.
+
+.. _`policy for handling security issues`: ../contributing/#reporting-security-issues

+ 16 - 0
docs/faq/index.txt

@@ -0,0 +1,16 @@
+.. _faq-index:
+
+==========
+Django FAQ
+==========
+
+.. toctree::
+   :maxdepth: 2
+   
+   general
+   install
+   usage
+   help
+   models
+   admin
+   contributing

+ 108 - 0
docs/faq/install.txt

@@ -0,0 +1,108 @@
+.. _faq-install:
+
+FAQ: Installation
+=================
+
+How do I get started?
+---------------------
+
+    #. `Download the code`_.
+    #. Install Django (read the :ref:`installation guide <intro-install>`).
+    #. Walk through the :ref:`tutorial <intro-tutorial01>`.
+    #. Check out the rest of the :ref:`documentation <index>`, and `ask questions`_ if you
+       run into trouble.
+
+.. _`Download the code`: http://www.djangoproject.com/download/
+.. _ask questions: http://www.djangoproject.com/community/
+
+How do I fix the "install a later version of setuptools" error?
+---------------------------------------------------------------
+
+Just run the ``ez_setup.py`` script in the Django distribution.
+
+What are Django's prerequisites?
+--------------------------------
+
+Django requires Python_ 2.3 or later. No other Python libraries are required
+for basic Django usage.
+
+For a development environment -- if you just want to experiment with Django --
+you don't need to have a separate Web server installed; Django comes with its
+own lightweight development server. For a production environment, we recommend
+`Apache 2`_ and mod_python_, although Django follows the WSGI_ spec, which
+means it can run on a variety of server platforms.
+
+If you want to use Django with a database, which is probably the case, you'll
+also need a database engine. PostgreSQL_ is recommended, because we're
+PostgreSQL fans, and MySQL_, `SQLite 3`_, and Oracle_ are also supported.
+
+.. _Python: http://www.python.org/
+.. _Apache 2: http://httpd.apache.org/
+.. _mod_python: http://www.modpython.org/
+.. _WSGI: http://www.python.org/peps/pep-0333.html
+.. _PostgreSQL: http://www.postgresql.org/
+.. _MySQL: http://www.mysql.com/
+.. _`SQLite 3`: http://www.sqlite.org/
+.. _Oracle: http://www.oracle.com/
+
+Do I lose anything by using Python 2.3 versus newer Python versions, such as Python 2.5?
+----------------------------------------------------------------------------------------
+
+No. Django itself is guaranteed to work with any version of Python from 2.3
+and higher.
+
+If you use a Python version newer than 2.3, you will, of course, be able to
+take advantage of newer Python features in your own code, along with the speed
+improvements and other optimizations that have been made to the Python language
+itself. But the Django framework itself should work equally well on 2.3 as it
+does on 2.4 or 2.5.
+
+Do I have to use mod_python?
+----------------------------
+
+Although we recommend mod_python for production use, you don't have to use it,
+thanks to the fact that Django uses an arrangement called WSGI_. Django can
+talk to any WSGI-enabled server. Other non-mod_python deployment setups are
+FastCGI, SCGI or AJP. See
+:ref:`How to use Django with FastCGI, SCGI or AJP <howto-deployment-fastcgi>`
+for full information.
+
+Also, see the `server arrangements wiki page`_ for other deployment strategies.
+
+If you just want to play around and develop things on your local computer, use
+the development Web server that comes with Django. Things should Just Work.
+
+.. _WSGI: http://www.python.org/peps/pep-0333.html
+.. _server arrangements wiki page: http://code.djangoproject.com/wiki/ServerArrangements
+
+How do I install mod_python on Windows?
+---------------------------------------
+
+    * For Python 2.4, grab mod_python from `win32 build of mod_python for
+      Python 2.4`_.
+    * For Python 2.4, check out this `Django on Windows howto`_.
+    * For Python 2.3, grab mod_python from http://www.modpython.org/ and read
+      `Running mod_python on Apache on Windows2000`_.
+    * Also, try this (not Windows-specific) `guide to getting mod_python
+      working`_.
+
+.. _`win32 build of mod_python for Python 2.4`: http://www.lehuen.com/nicolas/index.php/2005/02/21/39-win32-build-of-mod_python-314-for-python-24
+.. _`Django on Windows howto`: http://thinkhole.org/wp/django-on-windows/
+.. _`Running mod_python on Apache on Windows2000`: http://groups-beta.google.com/group/comp.lang.python/msg/139af8c83a5a9d4f
+.. _`guide to getting mod_python working`: http://www.dscpl.com.au/articles/modpython-001.html
+
+Will Django run under shared hosting (like TextDrive or Dreamhost)?
+-------------------------------------------------------------------
+
+See our `Django-friendly Web hosts`_ page.
+
+.. _`Django-friendly Web hosts`: http://code.djangoproject.com/wiki/DjangoFriendlyWebHosts
+
+Should I use the official version or development version?
+---------------------------------------------------------
+
+The Django developers improve Django every day and are pretty good about not
+checking in broken code. We use the development code (from the Subversion
+repository) directly on our servers, so we consider it stable. With that in
+mind, we recommend that you use the latest development code, because it
+generally contains more features and fewer bugs than the "official" releases.

+ 94 - 0
docs/faq/models.txt

@@ -0,0 +1,94 @@
+.. _faq-models:
+
+FAQ: Databases and models
+=========================
+
+How can I see the raw SQL queries Django is running?
+----------------------------------------------------
+
+Make sure your Django ``DEBUG`` setting is set to ``True``. Then, just do
+this::
+
+    >>> from django.db import connection
+    >>> connection.queries
+    [{'sql': 'SELECT polls_polls.id,polls_polls.question,polls_polls.pub_date FROM polls_polls',
+    'time': '0.002'}]
+
+``connection.queries`` is only available if ``DEBUG`` is ``True``. It's a list
+of dictionaries in order of query execution. Each dictionary has the following::
+
+    ``sql`` -- The raw SQL statement
+    ``time`` -- How long the statement took to execute, in seconds.
+
+``connection.queries`` includes all SQL statements -- INSERTs, UPDATES,
+SELECTs, etc. Each time your app hits the database, the query will be recorded.
+
+Can I use Django with a pre-existing database?
+----------------------------------------------
+
+Yes. See :ref:`Integrating with a legacy database <howto-legacy-databases>`.
+
+If I make changes to a model, how do I update the database?
+-----------------------------------------------------------
+
+If you don't mind clearing data, your project's ``manage.py`` utility has an
+option to reset the SQL for a particular application::
+
+    manage.py reset appname
+
+This drops any tables associated with ``appname`` and recreates them.
+
+If you do care about deleting data, you'll have to execute the ``ALTER TABLE``
+statements manually in your database. That's the way we've always done it,
+because dealing with data is a very sensitive operation that we've wanted to
+avoid automating. That said, there's some work being done to add partially
+automated database-upgrade functionality.
+
+Do Django models support multiple-column primary keys?
+------------------------------------------------------
+
+No. Only single-column primary keys are supported.
+
+But this isn't an issue in practice, because there's nothing stopping you from
+adding other constraints (using the ``unique_together`` model option or
+creating the constraint directly in your database), and enforcing the
+uniqueness at that level. Single-column primary keys are needed for things such
+as the admin interface to work; e.g., you need a simple way of being able to
+specify an object to edit or delete.
+
+How do I add database-specific options to my CREATE TABLE statements, such as specifying MyISAM as the table type?
+------------------------------------------------------------------------------------------------------------------
+
+We try to avoid adding special cases in the Django code to accommodate all the
+database-specific options such as table type, etc. If you'd like to use any of
+these options, create an :ref:`SQL initial data file <initial-sql>` that
+contains ``ALTER TABLE`` statements that do what you want to do. The initial
+data files are executed in your database after the ``CREATE TABLE`` statements.
+
+For example, if you're using MySQL and want your tables to use the MyISAM table
+type, create an initial data file and put something like this in it::
+
+    ALTER TABLE myapp_mytable ENGINE=MyISAM;
+
+As explained in the :ref:`SQL initial data file <initial-sql>` documentation,
+this SQL file can contain arbitrary SQL, so you can make any sorts of changes
+you need to make.
+
+Why is Django leaking memory?
+-----------------------------
+
+Django isn't known to leak memory. If you find your Django processes are
+allocating more and more memory, with no sign of releasing it, check to make
+sure your ``DEBUG`` setting is set to ``True``. If ``DEBUG`` is ``True``, then
+Django saves a copy of every SQL statement it has executed.
+
+(The queries are saved in ``django.db.connection.queries``. See
+`How can I see the raw SQL queries Django is running?`_.)
+
+To fix the problem, set ``DEBUG`` to ``False``.
+
+If you need to clear the query list manually at any point in your functions,
+just call ``reset_queries()``, like this::
+
+    from django import db
+    db.reset_queries()

+ 65 - 0
docs/faq/usage.txt

@@ -0,0 +1,65 @@
+.. _faq-usage:
+
+FAQ: Using Django
+=================
+
+Why do I get an error about importing DJANGO_SETTINGS_MODULE?
+-------------------------------------------------------------
+
+Make sure that:
+
+    * The environment variable DJANGO_SETTINGS_MODULE is set to a fully-qualified
+      Python module (i.e. "mysite.settings").
+
+    * Said module is on ``sys.path`` (``import mysite.settings`` should work).
+
+    * The module doesn't contain syntax errors (of course).
+
+    * If you're using mod_python but *not* using Django's request handler,
+      you'll need to work around a mod_python bug related to the use of
+      ``SetEnv``; before you import anything from Django you'll need to do
+      the following::
+
+            os.environ.update(req.subprocess_env)
+
+      (where ``req`` is the mod_python request object).
+
+I can't stand your template language. Do I have to use it?
+----------------------------------------------------------
+
+We happen to think our template engine is the best thing since chunky bacon,
+but we recognize that choosing a template language runs close to religion.
+There's nothing about Django that requires using the template language, so
+if you're attached to ZPT, Cheetah, or whatever, feel free to use those.
+
+Do I have to use your model/database layer?
+-------------------------------------------
+
+Nope. Just like the template system, the model/database layer is decoupled from
+the rest of the framework.
+
+The one exception is: If you use a different database library, you won't get to
+use Django's automatically-generated admin site. That app is coupled to the
+Django database layer.
+
+How do I use image and file fields?
+-----------------------------------
+
+Using a ``FileField`` or an ``ImageField`` in a model takes a few steps:
+
+    #. In your settings file, define ``MEDIA_ROOT`` as the full path to
+       a directory where you'd like Django to store uploaded files. (For
+       performance, these files are not stored in the database.) Define
+       ``MEDIA_URL`` as the base public URL of that directory. Make sure that
+       this directory is writable by the Web server's user account.
+
+    #. Add the ``FileField`` or ``ImageField`` to your model, making sure
+       to define the ``upload_to`` option to tell Django to which subdirectory
+       of ``MEDIA_ROOT`` it should upload files.
+
+    #. All that will be stored in your database is a path to the file
+       (relative to ``MEDIA_ROOT``). You'll most likely want to use the
+       convenience ``get_<fieldname>_url`` function provided by Django. For
+       example, if your ``ImageField`` is called ``mug_shot``, you can get the
+       absolute URL to your image in a template with
+       ``{{ object.get_mug_shot_url }}``.

+ 0 - 388
docs/files.txt

@@ -1,388 +0,0 @@
-==============
-Managing files
-==============
-
-**New in Django development version**
-
-This document describes Django's file access APIs.
-
-By default, Django stores files locally, using the ``MEDIA_ROOT`` and
-``MEDIA_URL`` settings_. The examples below assume that you're using
-these defaults.
-
-However, Django provides ways to write custom `file storage systems`_ that
-allow you to completely customize where and how Django stores files. The
-second half of this document describes how these storage systems work.
-
-.. _file storage systems: `File storage`_
-.. _settings: ../settings/
-
-Using files in models
-=====================
-
-When you use a `FileField`_ or `ImageField`_, Django provides a set of APIs you can use to deal with that file.
-
-.. _filefield: ../model-api/#filefield
-.. _imagefield: ../model-api/#imagefield
-
-Consider the following model, using a ``FileField`` to store a photo::
-
-    class Car(models.Model):
-        name = models.CharField(max_length=255)
-        price = models.DecimalField(max_digits=5, decimal_places=2)
-        photo = models.ImageField(upload_to='cars')
-
-Any ``Car`` instance will have a ``photo`` attribute that you can use to get at
-the details of the attached photo::
-
-    >>> car = Car.object.get(name="57 Chevy")
-    >>> car.photo
-    <ImageFieldFile: chevy.jpg>
-    >>> car.photo.name
-    u'chevy.jpg'
-    >>> car.photo.path
-    u'/media/cars/chevy.jpg'
-    >>> car.photo.url
-    u'http://media.example.com/cars/chevy.jpg'
-
-This object -- ``car.photo`` in the example -- is a ``File`` object, which means
-it has all the methods and attributes described below.
-
-The ``File`` object
-===================
-
-Internally, Django uses a ``django.core.files.File`` any time it needs to
-represent a file. This object is a thin wrapper around Python's `built-in file
-object`_ with some Django-specific additions.
-
-.. _built-in file object: http://docs.python.org/lib/bltin-file-objects.html
-
-Creating ``File`` instances
----------------------------
-
-Most of the time you'll simply use a ``File`` that Django's given you (i.e. a
-file attached to a model as above, or perhaps an `uploaded file`_).
-
-.. _uploaded file: ../upload_handling/
-
-If you need to construct a ``File`` yourself, the easiest way is to create one
-using a Python built-in ``file`` object::
-
-    >>> from django.core.files import File
-
-    # Create a Python file object using open()
-    >>> f = open('/tmp/hello.world', 'w')
-    >>> myfile = File(f)
-
-Now you can use any of the ``File`` attributes and methods defined below.
-
-``File`` attributes and methods
--------------------------------
-
-Django's ``File`` has the following attributes and methods:
-
-``File.path``
-~~~~~~~~~~~~~
-
-The absolute path to the file's location on a local filesystem.
-
-Custom `file storage systems`_ may not store files locally; files stored on
-these systems will have a ``path`` of ``None``.
-
-``File.url``
-~~~~~~~~~~~~
-
-The URL where the file can be retrieved. This is often useful in templates_; for
-example, a bit of a template for displaying a ``Car`` (see above) might look
-like::
-
-    <img src='{{ car.photo.url }}' alt='{{ car.name }}' />
-
-.. _templates: ../templates/
-
-``File.size``
-~~~~~~~~~~~~~
-
-The size of the file in bytes.
-
-``File.open(mode=None)``
-~~~~~~~~~~~~~~~~~~~~~~~~
-
-Open or reopen the file (which by definition also does ``File.seek(0)``). The
-``mode`` argument allows the same values as Python's standard ``open()``.
-
-When reopening a file, ``mode`` will override whatever mode the file was
-originally opened with; ``None`` means to reopen with the original mode.
-
-``File.read(num_bytes=None)``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Read content from the file. The optional ``size`` is the number of bytes to
-read; if not specified, the file will be read to the end.
-
-``File.__iter__()``
-~~~~~~~~~~~~~~~~~~~
-
-Iterate over the file yielding one line at a time.
-
-``File.chunks(chunk_size=None)``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Iterate over the file yielding "chunks" of a given size. ``chunk_size`` defaults
-to 64 KB.
-
-This is especially useful with very large files since it allows them to be
-streamed off disk and avoids storing the whole file in memory.
-
-``File.multiple_chunks(chunk_size=None)``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Returns ``True`` if the file is large enough to require multiple chunks to
-access all of its content give some ``chunk_size``.
-
-``File.write(content)``
-~~~~~~~~~~~~~~~~~~~~~~~
-
-Writes the specified content string to the file. Depending on the storage system
-behind the scenes, this content might not be fully committed until ``close()``
-is called on the file.
-
-``File.close()``
-~~~~~~~~~~~~~~~~
-
-Close the file.
-
-.. TODO: document the rest of the File methods.
-
-Additional ``ImageField`` attributes
-------------------------------------
-
-``File.width`` and ``File.height``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-These attributes provide the dimensions of the image.
-
-Additional methods on files attached to objects
------------------------------------------------
-
-Any ``File`` that's associated with an object (as with ``Car.photo``, above)
-will also have a couple of extra methods:
-
-``File.save(name, content, save=True)``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Saves a new file with the file name and contents provided. This will not replace
-the existing file, but will create a new file and update the object to point to
-it. If ``save`` is ``True``, the model's ``save()`` method will be called once
-the file is saved. That is, these two lines::
-
-    >>> car.photo.save('myphoto.jpg', contents, save=False)
-    >>> car.save()
-
-are the same as this one line::
-
-    >>> car.photo.save('myphoto.jpg', contents, save=True)
-
-``File.delete(save=True)``
-~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Remove the file from the model instance and delete the underlying file. The
-``save`` argument works as above.
-
-File storage
-============
-
-Behind the scenes, Django delegates decisions about how and where to store files
-to a file storage system. This is the object that actually understands things
-like file systems, opening and reading files, etc.
-
-Django's default file storage is given by the `DEFAULT_FILE_STORAGE setting`_;
-if you don't explicitly provide a storage system, this is the one that will be
-used.
-
-.. _default_file_storage setting: ../settings/#default-file-storage
-
-The built-in filesystem storage class
--------------------------------------
-
-Django ships with a built-in ``FileSystemStorage`` class (defined in
-``django.core.files.storage``) which implements basic local filesystem file
-storage. Its initializer takes two arguments:
-
-======================  ===================================================
-Argument                Description
-======================  ===================================================
-``location``            Optional. Absolute path to the directory that will
-                        hold the files. If omitted, it will be set to the
-                        value of your ``MEDIA_ROOT`` setting.
-``base_url``            Optional. URL that serves the files stored at this
-                        location. If omitted, it will default to the value
-                        of your ``MEDIA_URL`` setting.
-======================  ===================================================
-
-For example, the following code will store uploaded files under
-``/media/photos`` regardless of what your ``MEDIA_ROOT`` setting is::
-
-    from django.db import models
-    from django.core.files.storage import FileSystemStorage
-
-    fs = FileSystemStorage(location='/media/photos')
-
-    class Car(models.Model):
-        ...
-        photo = models.ImageField(storage=fs)
-
-`Custom storage systems`_ work the same way: you can pass them in as the
-``storage`` argument to a ``FileField``.
-
-.. _custom storage systems: `writing a custom storage system`_
-
-Storage objects
----------------
-
-Though most of the time you'll want to use a ``File`` object (which delegates to
-the proper storage for that file), you can use file storage systems directly.
-You can create an instance of some custom file storage class, or -- often more
-useful -- you can use the global default storage system::
-
-    >>> from django.core.files.storage import default_storage
-
-    >>> path = default_storage.save('/path/to/file', 'new content')
-    >>> path
-    u'/path/to/file'
-
-    >>> default_storage.filesize(path)
-    11
-    >>> default_storage.open(path).read()
-    'new content'
-
-    >>> default_storage.delete(path)
-    >>> default_storage.exists(path)
-    False
-
-Storage objects define the following methods:
-
-``Storage.exists(name)``
-~~~~~~~~~~~~~~~~~~~~~~~~
-
-``True`` if a file exists given some ``name``.
-
-``Storage.path(name)``
-~~~~~~~~~~~~~~~~~~~~~~
-
-The local filesystem path where the file can be opened using Python's standard
-``open()``. For storage systems that aren't accessible from the local
-filesystem, this will raise ``NotImplementedError`` instead.
-
-``Storage.size(name)``
-~~~~~~~~~~~~~~~~~~~~~~
-
-Returns the total size, in bytes, of the file referenced by ``name``.
-
-``Storage.url(name)``
-~~~~~~~~~~~~~~~~~~~~~
-
-Returns the URL where the contents of the file referenced by ``name`` can be
-accessed.
-
-``Storage.open(name, mode='rb')``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Opens the file given by ``name``. Note that although the returned file is
-guaranteed to be a ``File`` object, it might actually be some subclass. In the
-case of remote file storage this means that reading/writing could be quite slow,
-so be warned.
-
-``Storage.save(name, content)``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Saves a new file using the storage system, preferably with the name specified.
-If there already exists a file with this name ``name``, the storage system may
-modify the filename as necessary to get a unique name. The actual name of the
-stored file will be returned.
-
-``Storage.delete(name)``
-~~~~~~~~~~~~~~~~~~~~~~~~
-
-Deletes the file referenced by ``name``. This method won't raise an exception if
-the file doesn't exist.
-
-Writing a custom storage system
-===============================
-
-If you need to provide custom file storage -- a common example is storing files
-on some remote system -- you can do so by defining a custom storage class.
-You'll need to follow these steps:
-
-#. Your custom storage system must be a subclass of
-   ``django.core.files.storage.Storage``::
-
-        from django.core.files.storage import Storage
-
-        class MyStorage(Storage):
-            ...
-
-#. Django must be able to instantiate your storage system without any arguments.
-   This means that any settings should be taken from ``django.conf.settings``::
-
-        from django.conf import settings
-        from django.core.files.storage import Storage
-
-        class MyStorage(Storage):
-            def __init__(self, option=None):
-                if not option:
-                    option = settings.CUSTOM_STORAGE_OPTIONS
-                ...
-
-#. Your storage class must implement the ``_open()`` and ``_save()`` methods,
-   along with any other methods appropriate to your storage class. See below for
-   more on these methods.
-
-   In addition, if your class provides local file storage, it must override
-   the ``path()`` method.
-
-Custom storage system methods
------------------------------
-
-Your custom storage system may override any of the storage methods explained
-above in `storage objects`_. However, it's usually better to use the hooks
-specifically designed for custom storage objects. These are:
-
-``_open(name, mode='rb')``
-~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-**Required**.
-
-Called by ``Storage.open()``, this is the actual mechanism the storage class
-uses to open the file. This must return a ``File`` object, though in most cases,
-you'll want to return some subclass here that implements logic specific to the
-backend storage system.
-
-``_save(name, content)``
-~~~~~~~~~~~~~~~~~~~~~~~~
-
-Called by ``Storage.save()``. The ``name`` will already have gone through
-``get_valid_name()`` and ``get_available_name()``, and the ``content`` will be a
-``File`` object itself. No return value is expected.
-
-``get_valid_name(name)``
-------------------------
-
-Returns a filename suitable for use with the underlying storage system. The
-``name`` argument passed to this method is the original filename sent to the
-server, after having any path information removed. Override this to customize
-how non-standard characters are converted to safe filenames.
-
-The code provided on ``Storage`` retains only alpha-numeric characters, periods
-and underscores from the original filename, removing everything else.
-
-``get_available_name(name)``
-----------------------------
-
-Returns a filename that is available in the storage mechanism, possibly taking
-the provided filename into account. The ``name`` argument passed to this method
-will have already cleaned to a filename valid for the storage system, according
-to the ``get_valid_name()`` method described above.
-
-The code provided on ``Storage`` simply appends underscores to the filename
-until it finds one that's available in the destination directory.

+ 0 - 95
docs/form_preview.txt

@@ -1,95 +0,0 @@
-============
-Form preview
-============
-
-Django comes with an optional "form preview" application that helps automate
-the following workflow:
-
-"Display an HTML form, force a preview, then do something with the submission."
-
-To force a preview of a form submission, all you have to do is write a short
-Python class.
-
-Overview
-=========
-
-Given a ``django.forms.Form`` subclass that you define, this application
-takes care of the following workflow:
-
-    1. Displays the form as HTML on a Web page.
-    2. Validates the form data when it's submitted via POST.
-       a. If it's valid, displays a preview page.
-       b. If it's not valid, redisplays the form with error messages.
-    3. When the "confirmation" form is submitted from the preview page, calls
-       a hook that you define -- a ``done()`` method that gets passed the valid
-       data.
-
-The framework enforces the required preview by passing a shared-secret hash to
-the preview page via hidden form fields. If somebody tweaks the form parameters
-on the preview page, the form submission will fail the hash-comparison test.
-
-How to use ``FormPreview``
-==========================
-
-    1. Point Django at the default FormPreview templates. There are two ways to
-       do this:
-
-       * Add ``'django.contrib.formtools'`` to your ``INSTALLED_APPS``
-         setting. This will work if your ``TEMPLATE_LOADERS`` setting includes
-         the ``app_directories`` template loader (which is the case by
-         default). See the `template loader docs`_ for more.
-
-       * Otherwise, determine the full filesystem path to the
-         ``django/contrib/formtools/templates`` directory, and add that
-         directory to your ``TEMPLATE_DIRS`` setting.
-
-    2. Create a ``FormPreview`` subclass that overrides the ``done()`` method::
-
-           from django.contrib.formtools.preview import FormPreview
-           from myapp.models import SomeModel
-
-           class SomeModelFormPreview(FormPreview):
-
-               def done(self, request, cleaned_data):
-                   # Do something with the cleaned_data, then redirect
-                   # to a "success" page.
-                   return HttpResponseRedirect('/form/success')
-
-       This method takes an ``HttpRequest`` object and a dictionary of the form
-       data after it has been validated and cleaned. It should return an
-       ``HttpResponseRedirect`` that is the end result of the form being
-       submitted.
-
-    3. Change your URLconf to point to an instance of your ``FormPreview``
-       subclass::
-
-           from myapp.preview import SomeModelFormPreview
-           from myapp.models import SomeModel
-           from django import forms
-
-       ...and add the following line to the appropriate model in your URLconf::
-
-           (r'^post/$', SomeModelFormPreview(SomeModelForm)),
-
-       where ``SomeModelForm`` is a Form or ModelForm class for the model.
-
-    4. Run the Django server and visit ``/post/`` in your browser.
-
-.. _template loader docs: ../templates_python/#loader-types
-
-``FormPreview`` classes
-=======================
-
-A ``FormPreview`` class is a simple Python class that represents the preview
-workflow.  ``FormPreview`` classes must subclass
-``django.contrib.formtools.preview.FormPreview`` and override the ``done()``
-method. They can live anywhere in your codebase.
-
-``FormPreview`` templates
-=========================
-
-By default, the form is rendered via the template ``formtools/form.html``, and
-the preview page is rendered via the template ``formtools.preview.html``.
-These values can be overridden for a particular form preview by setting
-``preview_template`` and ``form_template`` attributes on the FormPreview
-subclass. See ``django/contrib/formtools/templates`` for the default templates.

+ 0 - 304
docs/form_wizard.txt

@@ -1,304 +0,0 @@
-===========
-Form wizard
-===========
-
-**New in Django development version.**
-
-Django comes with an optional "form wizard" application that splits forms_
-across multiple Web pages. It maintains state in hashed HTML
-``<input type="hidden">`` fields, and the data isn't processed server-side
-until the final form is submitted.
-
-You might want to use this if you have a lengthy form that would be too
-unwieldy for display on a single page. The first page might ask the user for
-core information, the second page might ask for less important information,
-etc.
-
-The term "wizard," in this context, is `explained on Wikipedia`_.
-
-.. _explained on Wikipedia: http://en.wikipedia.org/wiki/Wizard_%28software%29
-.. _forms: ../forms/
-
-How it works
-============
-
-Here's the basic workflow for how a user would use a wizard:
-
-    1. The user visits the first page of the wizard, fills in the form and
-       submits it.
-    2. The server validates the data. If it's invalid, the form is displayed
-       again, with error messages. If it's valid, the server calculates a
-       secure hash of the data and presents the user with the next form,
-       saving the validated data and hash in ``<input type="hidden">`` fields.
-    3. Step 1 and 2 repeat, for every subsequent form in the wizard.
-    4. Once the user has submitted all the forms and all the data has been
-       validated, the wizard processes the data -- saving it to the database,
-       sending an e-mail, or whatever the application needs to do.
-
-Usage
-=====
-
-This application handles as much machinery for you as possible. Generally, you
-just have to do these things:
-
-    1. Define a number of ``django.forms`` ``Form`` classes -- one per wizard
-       page.
-    2. Create a ``FormWizard`` class that specifies what to do once all of your
-       forms have been submitted and validated. This also lets you override some
-       of the wizard's behavior.
-    3. Create some templates that render the forms. You can define a single,
-       generic template to handle every one of the forms, or you can define a
-       specific template for each form.
-    4. Point your URLconf at your ``FormWizard`` class.
-
-Defining ``Form`` classes
-=========================
-
-The first step in creating a form wizard is to create the ``Form`` classes.
-These should be standard ``django.forms`` ``Form`` classes, covered in the
-`forms documentation`_.
-
-These classes can live anywhere in your codebase, but convention is to put them
-in a file called ``forms.py`` in your application.
-
-For example, let's write a "contact form" wizard, where the first page's form
-collects the sender's e-mail address and subject, and the second page collects
-the message itself. Here's what the ``forms.py`` might look like::
-
-    from django import forms
-
-    class ContactForm1(forms.Form):
-        subject = forms.CharField(max_length=100)
-        sender = forms.EmailField()
-
-    class ContactForm2(forms.Form):
-        message = forms.CharField(widget=forms.Textarea)
-
-**Important limitation:** Because the wizard uses HTML hidden fields to store
-data between pages, you may not include a ``FileField`` in any form except the
-last one.
-
-.. _forms documentation: ../forms/
-
-Creating a ``FormWizard`` class
-===============================
-
-The next step is to create a ``FormWizard`` class, which should be a subclass
-of ``django.contrib.formtools.wizard.FormWizard``.
-
-As your ``Form`` classes, this ``FormWizard`` class can live anywhere in your
-codebase, but convention is to put it in ``forms.py``.
-
-The only requirement on this subclass is that it implement a ``done()`` method,
-which specifies what should happen when the data for *every* form is submitted
-and validated. This method is passed two arguments:
-
-    * ``request`` -- an HttpRequest_ object
-    * ``form_list`` -- a list of ``django.forms`` ``Form`` classes
-
-In this simplistic example, rather than perform any database operation, the
-method simply renders a template of the validated data::
-
-    from django.shortcuts import render_to_response
-    from django.contrib.formtools.wizard import FormWizard
-
-    class ContactWizard(FormWizard):
-        def done(self, request, form_list):
-            return render_to_response('done.html', {
-                'form_data': [form.cleaned_data for form in form_list],
-            })
-
-Note that this method will be called via ``POST``, so it really ought to be a
-good Web citizen and redirect after processing the data. Here's another
-example::
-
-    from django.http import HttpResponseRedirect
-    from django.contrib.formtools.wizard import FormWizard
-
-    class ContactWizard(FormWizard):
-        def done(self, request, form_list):
-            do_something_with_the_form_data(form_list)
-            return HttpResponseRedirect('/page-to-redirect-to-when-done/')
-
-See the section "Advanced ``FormWizard`` methods" below to learn about more
-``FormWizard`` hooks.
-
-.. _HttpRequest: request_response/#httprequest-objects
-
-Creating templates for the forms
-================================
-
-Next, you'll need to create a template that renders the wizard's forms. By
-default, every form uses a template called ``forms/wizard.html``. (You can
-change this template name by overriding ``FormWizard.get_template()``, which is
-documented below. This hook also allows you to use a different template for
-each form.)
-
-This template expects the following context:
-
-    * ``step_field`` -- The name of the hidden field containing the step.
-    * ``step0`` -- The current step (zero-based).
-    * ``step`` -- The current step (one-based).
-    * ``step_count`` -- The total number of steps.
-    * ``form`` -- The ``Form`` instance for the current step (either empty or
-      with errors).
-    * ``previous_fields`` -- A string representing every previous data field,
-      plus hashes for completed forms, all in the form of hidden fields. Note
-      that you'll need to run this through the ``safe`` template filter, to
-      prevent auto-escaping, because it's raw HTML.
-
-It will also be passed any objects in ``extra_context``, which is a dictionary
-you can specify that contains extra values to add to the context. You can
-specify it in two ways:
-
-    * Set the ``extra_context`` attribute on your ``FormWizard`` subclass to a
-      dictionary.
-
-    * Pass ``extra_context`` as extra parameters in the URLconf.
-
-Here's a full example template::
-
-    {% extends "base.html" %}
-
-    {% block content %}
-    <p>Step {{ step }} of {{ step_count }}</p>
-    <form action="." method="post">
-    <table>
-    {{ form }}
-    </table>
-    <input type="hidden" name="{{ step_field }}" value="{{ step0 }}" />
-    {{ previous_fields|safe }}
-    <input type="submit">
-    </form>
-    {% endblock %}
-
-Note that ``previous_fields``, ``step_field`` and ``step0`` are all required
-for the wizard to work properly.
-
-Hooking the wizard into a URLconf
-=================================
-
-Finally, give your new ``FormWizard`` object a URL in ``urls.py``. The wizard
-takes a list of your form objects as arguments::
-
-    from django.conf.urls.defaults import *
-    from mysite.testapp.forms import ContactForm1, ContactForm2, ContactWizard
-
-    urlpatterns = patterns('',
-        (r'^contact/$', ContactWizard([ContactForm1, ContactForm2])),
-    )
-
-Advanced ``FormWizard`` methods
-===============================
-
-Aside from the ``done()`` method, ``FormWizard`` offers a few advanced method
-hooks that let you customize how your wizard works.
-
-Some of these methods take an argument ``step``, which is a zero-based counter
-representing the current step of the wizard. (E.g., the first form is ``0`` and
-the second form is ``1``.)
-
-``prefix_for_step``
-~~~~~~~~~~~~~~~~~~~
-
-Given the step, returns a ``Form`` prefix to use. By default, this simply uses
-the step itself. For more, see the `form prefix documentation`_.
-
-Default implementation::
-
-    def prefix_for_step(self, step):
-        return str(step)
-
-.. _form prefix documentation: ../forms/#prefixes-for-forms
-
-``render_hash_failure``
-~~~~~~~~~~~~~~~~~~~~~~~
-
-Renders a template if the hash check fails. It's rare that you'd need to
-override this.
-
-Default implementation::
-
-    def render_hash_failure(self, request, step):
-        return self.render(self.get_form(step), request, step,
-            context={'wizard_error': 'We apologize, but your form has expired. Please continue filling out the form from this page.'})
-
-``security_hash``
-~~~~~~~~~~~~~~~~~
-
-Calculates the security hash for the given request object and ``Form`` instance.
-
-By default, this uses an MD5 hash of the form data and your
-`SECRET_KEY setting`_. It's rare that somebody would need to override this.
-
-Example::
-
-    def security_hash(self, request, form):
-        return my_hash_function(request, form)
-
-.. _SECRET_KEY setting: ../settings/#secret-key
-
-``parse_params``
-~~~~~~~~~~~~~~~~
-
-A hook for saving state from the request object and ``args`` / ``kwargs`` that
-were captured from the URL by your URLconf.
-
-By default, this does nothing.
-
-Example::
-
-    def parse_params(self, request, *args, **kwargs):
-        self.my_state = args[0]
-
-``get_template``
-~~~~~~~~~~~~~~~~
-
-Returns the name of the template that should be used for the given step.
-
-By default, this returns ``'forms/wizard.html'``, regardless of step.
-
-Example::
-
-    def get_template(self, step):
-        return 'myapp/wizard_%s.html' % step
-
-If ``get_template`` returns a list of strings, then the wizard will use the
-template system's ``select_template()`` function, `explained in the template docs`_.
-This means the system will use the first template that exists on the filesystem.
-For example::
-
-    def get_template(self, step):
-        return ['myapp/wizard_%s.html' % step, 'myapp/wizard.html']
-
-.. _explained in the template docs: ../templates_python/#the-python-api
-
-``render_template``
-~~~~~~~~~~~~~~~~~~~
-
-Renders the template for the given step, returning an ``HttpResponse`` object.
-
-Override this method if you want to add a custom context, return a different
-MIME type, etc. If you only need to override the template name, use
-``get_template()`` instead.
-
-The template will be rendered with the context documented in the
-"Creating templates for the forms" section above.
-
-``process_step``
-~~~~~~~~~~~~~~~~
-
-Hook for modifying the wizard's internal state, given a fully validated ``Form``
-object. The Form is guaranteed to have clean, valid data.
-
-This method should *not* modify any of that data. Rather, it might want to set
-``self.extra_context`` or dynamically alter ``self.form_list``, based on
-previously submitted forms.
-
-Note that this method is called every time a page is rendered for *all*
-submitted steps.
-
-The function signature::
-
-    def process_step(self, request, form, step):
-        # ...

+ 0 - 2468
docs/forms.txt

@@ -1,2468 +0,0 @@
-=================
-The forms library
-=================
-
-``django.forms`` is Django's form-handling library.
-
-.. admonition:: Looking for oldforms?
-
-    ``django.forms`` was once called ``newforms`` since it replaced Django's
-    original form/manipulator/validation framework. The old form handling
-    library is still available as `django.oldforms`_, but will be removed
-    in a future version of Django.
-
-.. _django.oldforms: ../oldforms/
-
-Overview
-========
-
-``django.forms`` is intended to handle HTML form display, data processing
-(validation) and redisplay. It's what you use if you want to perform
-server-side validation for an HTML form.
-
-For example, if your Web site has a contact form that visitors can use to
-send you e-mail, you'd use this library to implement the display of the HTML
-form fields, along with the form validation. Any time you need to use an HTML
-``<form>``, you can use this library.
-
-The library deals with these concepts:
-
-    * **Widget** -- A class that corresponds to an HTML form widget, e.g.
-      ``<input type="text">`` or ``<textarea>``. This handles rendering of the
-      widget as HTML.
-
-    * **Field** -- A class that is responsible for doing validation, e.g.
-      an ``EmailField`` that makes sure its data is a valid e-mail address.
-
-    * **Form** -- A collection of fields that knows how to validate itself and
-      display itself as HTML.
-
-    * **Media** -- A definition of the CSS and JavaScript resources that are
-      required to render a form.
-
-The library is decoupled from the other Django components, such as the database
-layer, views and templates. It relies only on Django settings, a couple of
-``django.utils`` helper functions and Django's internationalization hooks (but
-you're not required to be using internationalization features to use this
-library).
-
-Form objects
-============
-
-The primary way of using the ``forms`` library is to create a form object.
-Do this by subclassing ``django.forms.Form`` and specifying the form's
-fields, in a declarative style that you'll be familiar with if you've used
-Django database models. In this section, we'll iteratively develop a form
-object that you might use to implement "contact me" functionality on your
-personal Web site.
-
-Start with this basic ``Form`` subclass, which we'll call ``ContactForm``::
-
-    from django import forms
-
-    class ContactForm(forms.Form):
-        subject = forms.CharField(max_length=100)
-        message = forms.CharField()
-        sender = forms.EmailField()
-        cc_myself = forms.BooleanField(required=False)
-
-A form is composed of ``Field`` objects. In this case, our form has four
-fields: ``subject``, ``message``, ``sender`` and ``cc_myself``. We'll explain
-the different types of fields -- e.g., ``CharField`` and ``EmailField`` --
-shortly.
-
-Creating ``Form`` instances
----------------------------
-
-A ``Form`` instance is either **bound** to a set of data, or **unbound**.
-
-    * If it's **bound** to a set of data, it's capable of validating that data
-      and rendering the form as HTML with the data displayed in the HTML.
-
-    * If it's **unbound**, it cannot do validation (because there's no data to
-      validate!), but it can still render the blank form as HTML.
-
-To create an unbound ``Form`` instance, simply instantiate the class::
-
-    >>> f = ContactForm()
-
-To bind data to a form, pass the data as a dictionary as the first parameter to
-your ``Form`` class constructor::
-
-    >>> data = {'subject': 'hello',
-    ...         'message': 'Hi there',
-    ...         'sender': 'foo@example.com',
-    ...         'cc_myself': True}
-    >>> f = ContactForm(data)
-
-In this dictionary, the keys are the field names, which correspond to the
-attributes in your ``Form`` class. The values are the data you're trying
-to validate. These will usually be strings, but there's no requirement that
-they be strings; the type of data you pass depends on the ``Field``, as we'll
-see in a moment.
-
-If you need to distinguish between bound and unbound form instances at runtime,
-check the value of the form's ``is_bound`` attribute::
-
-    >>> f = ContactForm()
-    >>> f.is_bound
-    False
-    >>> f = ContactForm({'subject': 'hello'})
-    >>> f.is_bound
-    True
-
-Note that passing an empty dictionary creates a *bound* form with empty data::
-
-    >>> f = ContactForm({})
-    >>> f.is_bound
-    True
-
-If you have a bound ``Form`` instance and want to change the data somehow, or
-if you want to bind an unbound ``Form`` instance to some data, create another
-``Form`` instance. There is no way to change data in a ``Form`` instance. Once
-a ``Form`` instance has been created, you should consider its data immutable,
-whether it has data or not.
-
-Using forms to validate data
-----------------------------
-
-The primary task of a ``Form`` object is to validate data. With a bound
-``Form`` instance, call the ``is_valid()`` method to run validation and return
-a boolean designating whether the data was valid::
-
-    >>> data = {'subject': 'hello',
-    ...         'message': 'Hi there',
-    ...         'sender': 'foo@example.com',
-    ...         'cc_myself': True}
-    >>> f = ContactForm(data)
-    >>> f.is_valid()
-    True
-
-Let's try with some invalid data. In this case, ``subject`` is blank (an error,
-because all fields are required by default) and ``sender`` is not a valid
-e-mail address::
-
-    >>> data = {'subject': '',
-    ...         'message': 'Hi there',
-    ...         'sender': 'invalid e-mail address',
-    ...         'cc_myself': True}
-    >>> f = ContactForm(data)
-    >>> f.is_valid()
-    False
-
-Access the ``errors`` attribute to get a dictionary of error messages::
-
-    >>> f.errors
-    {'sender': [u'Enter a valid e-mail address.'], 'subject': [u'This field is required.']}
-
-In this dictionary, the keys are the field names, and the values are lists of
-Unicode strings representing the error messages. The error messages are stored
-in lists because a field can have multiple error messages.
-
-You can access ``errors`` without having to call ``is_valid()`` first. The
-form's data will be validated the first time either you call ``is_valid()`` or
-access ``errors``.
-
-The validation routines will only get called once, regardless of how many times
-you access ``errors`` or call ``is_valid()``. This means that if validation has
-side effects, those side effects will only be triggered once.
-
-Behavior of unbound forms
-~~~~~~~~~~~~~~~~~~~~~~~~~
-
-It's meaningless to validate a form with no data, but, for the record, here's
-what happens with unbound forms::
-
-    >>> f = ContactForm()
-    >>> f.is_valid()
-    False
-    >>> f.errors
-    {}
-
-Accessing "clean" data
-----------------------
-
-Each ``Field`` in a ``Form`` class is responsible not only for validating data,
-but also for "cleaning" it -- normalizing it to a consistent format. This is a
-nice feature, because it allows data for a particular field to be input in
-a variety of ways, always resulting in consistent output.
-
-For example, ``DateField`` normalizes input into a Python ``datetime.date``
-object. Regardless of whether you pass it a string in the format
-``'1994-07-15'``, a ``datetime.date`` object or a number of other formats,
-``DateField`` will always normalize it to a ``datetime.date`` object as long as
-it's valid.
-
-Once you've created a ``Form`` instance with a set of data and validated it,
-you can access the clean data via the ``cleaned_data`` attribute of the ``Form``
-object::
-
-    >>> data = {'subject': 'hello',
-    ...         'message': 'Hi there',
-    ...         'sender': 'foo@example.com',
-    ...         'cc_myself': True}
-    >>> f = ContactForm(data)
-    >>> f.is_valid()
-    True
-    >>> f.cleaned_data
-    {'cc_myself': True, 'message': u'Hi there', 'sender': u'foo@example.com', 'subject': u'hello'}
-
-.. note::
-    **New in Django development version** The ``cleaned_data`` attribute was
-    called ``clean_data`` in earlier releases.
-
-Note that any text-based field -- such as ``CharField`` or ``EmailField`` --
-always cleans the input into a Unicode string. We'll cover the encoding
-implications later in this document.
-
-If your data does *not* validate, your ``Form`` instance will not have a
-``cleaned_data`` attribute::
-
-    >>> data = {'subject': '',
-    ...         'message': 'Hi there',
-    ...         'sender': 'invalid e-mail address',
-    ...         'cc_myself': True}
-    >>> f = ContactForm(data)
-    >>> f.is_valid()
-    False
-    >>> f.cleaned_data
-    Traceback (most recent call last):
-    ...
-    AttributeError: 'ContactForm' object has no attribute 'cleaned_data'
-
-``cleaned_data`` will always *only* contain a key for fields defined in the
-``Form``, even if you pass extra data when you define the ``Form``. In this
-example, we pass a bunch of extra fields to the ``ContactForm`` constructor,
-but ``cleaned_data`` contains only the form's fields::
-
-    >>> data = {'subject': 'hello',
-    ...         'message': 'Hi there',
-    ...         'sender': 'foo@example.com',
-    ...         'cc_myself': True,
-    ...         'extra_field_1': 'foo',
-    ...         'extra_field_2': 'bar',
-    ...         'extra_field_3': 'baz'}
-    >>> f = ContactForm(data)
-    >>> f.is_valid()
-    True
-    >>> f.cleaned_data # Doesn't contain extra_field_1, etc.
-    {'cc_myself': True, 'message': u'Hi there', 'sender': u'foo@example.com', 'subject': u'hello'}
-
-``cleaned_data`` will include a key and value for *all* fields defined in the
-``Form``, even if the data didn't include a value for fields that are not
-required. In this example, the data dictionary doesn't include a value for the
-``nick_name`` field, but ``cleaned_data`` includes it, with an empty value::
-
-    >>> class OptionalPersonForm(Form):
-    ...     first_name = CharField()
-    ...     last_name = CharField()
-    ...     nick_name = CharField(required=False)
-    >>> data = {'first_name': u'John', 'last_name': u'Lennon'}
-    >>> f = OptionalPersonForm(data)
-    >>> f.is_valid()
-    True
-    >>> f.cleaned_data
-    {'nick_name': u'', 'first_name': u'John', 'last_name': u'Lennon'}
-
-In this above example, the ``cleaned_data`` value for ``nick_name`` is set to an
-empty string, because ``nick_name`` is ``CharField``, and ``CharField``\s treat
-empty values as an empty string. Each field type knows what its "blank" value
-is -- e.g., for ``DateField``, it's ``None`` instead of the empty string. For
-full details on each field's behavior in this case, see the "Empty value" note
-for each field in the "Built-in ``Field`` classes" section below.
-
-You can write code to perform validation for particular form fields (based on
-their name) or for the form as a whole (considering combinations of various
-fields). More information about this is in the `Custom form and field
-validation`_ section, below.
-
-Behavior of unbound forms
-~~~~~~~~~~~~~~~~~~~~~~~~~
-
-It's meaningless to request "cleaned" data in a form with no data, but, for the
-record, here's what happens with unbound forms::
-
-    >>> f = ContactForm()
-    >>> f.cleaned_data
-    Traceback (most recent call last):
-    ...
-    AttributeError: 'ContactForm' object has no attribute 'cleaned_data'
-
-Outputting forms as HTML
-------------------------
-
-The second task of a ``Form`` object is to render itself as HTML. To do so,
-simply ``print`` it::
-
-    >>> f = ContactForm()
-    >>> print f
-    <tr><th><label for="id_subject">Subject:</label></th><td><input id="id_subject" type="text" name="subject" maxlength="100" /></td></tr>
-    <tr><th><label for="id_message">Message:</label></th><td><input type="text" name="message" id="id_message" /></td></tr>
-    <tr><th><label for="id_sender">Sender:</label></th><td><input type="text" name="sender" id="id_sender" /></td></tr>
-    <tr><th><label for="id_cc_myself">Cc myself:</label></th><td><input type="checkbox" name="cc_myself" id="id_cc_myself" /></td></tr>
-
-If the form is bound to data, the HTML output will include that data
-appropriately. For example, if a field is represented by an
-``<input type="text">``, the data will be in the ``value`` attribute. If a
-field is represented by an ``<input type="checkbox">``, then that HTML will
-include ``checked="checked"`` if appropriate::
-
-    >>> data = {'subject': 'hello',
-    ...         'message': 'Hi there',
-    ...         'sender': 'foo@example.com',
-    ...         'cc_myself': True}
-    >>> f = ContactForm(data)
-    >>> print f
-    <tr><th><label for="id_subject">Subject:</label></th><td><input id="id_subject" type="text" name="subject" maxlength="100" value="hello" /></td></tr>
-    <tr><th><label for="id_message">Message:</label></th><td><input type="text" name="message" id="id_message" value="Hi there" /></td></tr>
-    <tr><th><label for="id_sender">Sender:</label></th><td><input type="text" name="sender" id="id_sender" value="foo@example.com" /></td></tr>
-    <tr><th><label for="id_cc_myself">Cc myself:</label></th><td><input type="checkbox" name="cc_myself" id="id_cc_myself" checked="checked" /></td></tr>
-
-This default output is a two-column HTML table, with a ``<tr>`` for each field.
-Notice the following:
-
-    * For flexibility, the output does *not* include the ``<table>`` and
-      ``</table>`` tags, nor does it include the ``<form>`` and ``</form>``
-      tags or an ``<input type="submit">`` tag. It's your job to do that.
-
-    * Each field type has a default HTML representation. ``CharField`` and
-      ``EmailField`` are represented by an ``<input type="text">``.
-      ``BooleanField`` is represented by an ``<input type="checkbox">``. Note
-      these are merely sensible defaults; you can specify which HTML to use for
-      a given field by using widgets, which we'll explain shortly.
-
-    * The HTML ``name`` for each tag is taken directly from its attribute name
-      in the ``ContactForm`` class.
-
-    * The text label for each field -- e.g. ``'Subject:'``, ``'Message:'`` and
-      ``'Cc myself:'`` is generated from the field name by converting all
-      underscores to spaces and upper-casing the first letter. Again, note
-      these are merely sensible defaults; you can also specify labels manually.
-
-    * Each text label is surrounded in an HTML ``<label>`` tag, which points
-      to the appropriate form field via its ``id``. Its ``id``, in turn, is
-      generated by prepending ``'id_'`` to the field name. The ``id``
-      attributes and ``<label>`` tags are included in the output by default, to
-      follow best practices, but you can change that behavior.
-
-Although ``<table>`` output is the default output style when you ``print`` a
-form, other output styles are available. Each style is available as a method on
-a form object, and each rendering method returns a Unicode object.
-
-``as_p()``
-~~~~~~~~~~
-
-``Form.as_p()`` renders the form as a series of ``<p>`` tags, with each ``<p>``
-containing one field::
-
-    >>> f = ContactForm()
-    >>> f.as_p()
-    u'<p><label for="id_subject">Subject:</label> <input id="id_subject" type="text" name="subject" maxlength="100" /></p>\n<p><label for="id_message">Message:</label> <input type="text" name="message" id="id_message" /></p>\n<p><label for="id_sender">Sender:</label> <input type="text" name="sender" id="id_sender" /></p>\n<p><label for="id_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_cc_myself" /></p>'
-    >>> print f.as_p()
-    <p><label for="id_subject">Subject:</label> <input id="id_subject" type="text" name="subject" maxlength="100" /></p>
-    <p><label for="id_message">Message:</label> <input type="text" name="message" id="id_message" /></p>
-    <p><label for="id_sender">Sender:</label> <input type="text" name="sender" id="id_sender" /></p>
-    <p><label for="id_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_cc_myself" /></p>
-
-``as_ul()``
-~~~~~~~~~~~
-
-``Form.as_ul()`` renders the form as a series of ``<li>`` tags, with each
-``<li>`` containing one field. It does *not* include the ``<ul>`` or ``</ul>``,
-so that you can specify any HTML attributes on the ``<ul>`` for flexibility::
-
-    >>> f = ContactForm()
-    >>> f.as_ul()
-    u'<li><label for="id_subject">Subject:</label> <input id="id_subject" type="text" name="subject" maxlength="100" /></li>\n<li><label for="id_message">Message:</label> <input type="text" name="message" id="id_message" /></li>\n<li><label for="id_sender">Sender:</label> <input type="text" name="sender" id="id_sender" /></li>\n<li><label for="id_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_cc_myself" /></li>'
-    >>> print f.as_ul()
-    <li><label for="id_subject">Subject:</label> <input id="id_subject" type="text" name="subject" maxlength="100" /></li>
-    <li><label for="id_message">Message:</label> <input type="text" name="message" id="id_message" /></li>
-    <li><label for="id_sender">Sender:</label> <input type="text" name="sender" id="id_sender" /></li>
-    <li><label for="id_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_cc_myself" /></li>
-
-``as_table()``
-~~~~~~~~~~~~~~
-
-Finally, ``Form.as_table()`` outputs the form as an HTML ``<table>``. This is
-exactly the same as ``print``. In fact, when you ``print`` a form object, it
-calls its ``as_table()`` method behind the scenes::
-
-    >>> f = ContactForm()
-    >>> f.as_table()
-    u'<tr><th><label for="id_subject">Subject:</label></th><td><input id="id_subject" type="text" name="subject" maxlength="100" /></td></tr>\n<tr><th><label for="id_message">Message:</label></th><td><input type="text" name="message" id="id_message" /></td></tr>\n<tr><th><label for="id_sender">Sender:</label></th><td><input type="text" name="sender" id="id_sender" /></td></tr>\n<tr><th><label for="id_cc_myself">Cc myself:</label></th><td><input type="checkbox" name="cc_myself" id="id_cc_myself" /></td></tr>'
-    >>> print f.as_table()
-    <tr><th><label for="id_subject">Subject:</label></th><td><input id="id_subject" type="text" name="subject" maxlength="100" /></td></tr>
-    <tr><th><label for="id_message">Message:</label></th><td><input type="text" name="message" id="id_message" /></td></tr>
-    <tr><th><label for="id_sender">Sender:</label></th><td><input type="text" name="sender" id="id_sender" /></td></tr>
-    <tr><th><label for="id_cc_myself">Cc myself:</label></th><td><input type="checkbox" name="cc_myself" id="id_cc_myself" /></td></tr>
-
-Configuring HTML ``<label>`` tags
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-An HTML ``<label>`` tag designates which label text is associated with which
-form element. This small enhancement makes forms more usable and more accessible
-to assistive devices. It's always a good idea to use ``<label>`` tags.
-
-By default, the form rendering methods include HTML ``id`` attributes on the
-form elements and corresponding ``<label>`` tags around the labels. The ``id``
-attribute values are generated by prepending ``id_`` to the form field names.
-This behavior is configurable, though, if you want to change the ``id``
-convention or remove HTML ``id`` attributes and ``<label>`` tags entirely.
-
-Use the ``auto_id`` argument to the ``Form`` constructor to control the label
-and ``id`` behavior. This argument must be ``True``, ``False`` or a string.
-
-If ``auto_id`` is ``False``, then the form output will not include ``<label>``
-tags nor ``id`` attributes::
-
-    >>> f = ContactForm(auto_id=False)
-    >>> print f.as_table()
-    <tr><th>Subject:</th><td><input type="text" name="subject" maxlength="100" /></td></tr>
-    <tr><th>Message:</th><td><input type="text" name="message" /></td></tr>
-    <tr><th>Sender:</th><td><input type="text" name="sender" /></td></tr>
-    <tr><th>Cc myself:</th><td><input type="checkbox" name="cc_myself" /></td></tr>
-    >>> print f.as_ul()
-    <li>Subject: <input type="text" name="subject" maxlength="100" /></li>
-    <li>Message: <input type="text" name="message" /></li>
-    <li>Sender: <input type="text" name="sender" /></li>
-    <li>Cc myself: <input type="checkbox" name="cc_myself" /></li>
-    >>> print f.as_p()
-    <p>Subject: <input type="text" name="subject" maxlength="100" /></p>
-    <p>Message: <input type="text" name="message" /></p>
-    <p>Sender: <input type="text" name="sender" /></p>
-    <p>Cc myself: <input type="checkbox" name="cc_myself" /></p>
-
-If ``auto_id`` is set to ``True``, then the form output *will* include
-``<label>`` tags and will simply use the field name as its ``id`` for each form
-field::
-
-    >>> f = ContactForm(auto_id=True)
-    >>> print f.as_table()
-    <tr><th><label for="subject">Subject:</label></th><td><input id="subject" type="text" name="subject" maxlength="100" /></td></tr>
-    <tr><th><label for="message">Message:</label></th><td><input type="text" name="message" id="message" /></td></tr>
-    <tr><th><label for="sender">Sender:</label></th><td><input type="text" name="sender" id="sender" /></td></tr>
-    <tr><th><label for="cc_myself">Cc myself:</label></th><td><input type="checkbox" name="cc_myself" id="cc_myself" /></td></tr>
-    >>> print f.as_ul()
-    <li><label for="subject">Subject:</label> <input id="subject" type="text" name="subject" maxlength="100" /></li>
-    <li><label for="message">Message:</label> <input type="text" name="message" id="message" /></li>
-    <li><label for="sender">Sender:</label> <input type="text" name="sender" id="sender" /></li>
-    <li><label for="cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="cc_myself" /></li>
-    >>> print f.as_p()
-    <p><label for="subject">Subject:</label> <input id="subject" type="text" name="subject" maxlength="100" /></p>
-    <p><label for="message">Message:</label> <input type="text" name="message" id="message" /></p>
-    <p><label for="sender">Sender:</label> <input type="text" name="sender" id="sender" /></p>
-    <p><label for="cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="cc_myself" /></p>
-
-If ``auto_id`` is set to a string containing the format character ``'%s'``,
-then the form output will include ``<label>`` tags, and will generate ``id``
-attributes based on the format string. For example, for a format string
-``'field_%s'``, a field named ``subject`` will get the ``id`` value
-``'field_subject'``. Continuing our example::
-
-    >>> f = ContactForm(auto_id='id_for_%s')
-    >>> print f.as_table()
-    <tr><th><label for="id_for_subject">Subject:</label></th><td><input id="id_for_subject" type="text" name="subject" maxlength="100" /></td></tr>
-    <tr><th><label for="id_for_message">Message:</label></th><td><input type="text" name="message" id="id_for_message" /></td></tr>
-    <tr><th><label for="id_for_sender">Sender:</label></th><td><input type="text" name="sender" id="id_for_sender" /></td></tr>
-    <tr><th><label for="id_for_cc_myself">Cc myself:</label></th><td><input type="checkbox" name="cc_myself" id="id_for_cc_myself" /></td></tr>
-    >>> print f.as_ul()
-    <li><label for="id_for_subject">Subject:</label> <input id="id_for_subject" type="text" name="subject" maxlength="100" /></li>
-    <li><label for="id_for_message">Message:</label> <input type="text" name="message" id="id_for_message" /></li>
-    <li><label for="id_for_sender">Sender:</label> <input type="text" name="sender" id="id_for_sender" /></li>
-    <li><label for="id_for_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_for_cc_myself" /></li>
-    >>> print f.as_p()
-    <p><label for="id_for_subject">Subject:</label> <input id="id_for_subject" type="text" name="subject" maxlength="100" /></p>
-    <p><label for="id_for_message">Message:</label> <input type="text" name="message" id="id_for_message" /></p>
-    <p><label for="id_for_sender">Sender:</label> <input type="text" name="sender" id="id_for_sender" /></p>
-    <p><label for="id_for_cc_myself">Cc myself:</label> <input type="checkbox" name="cc_myself" id="id_for_cc_myself" /></p>
-
-If ``auto_id`` is set to any other true value -- such as a string that doesn't
-include ``%s`` -- then the library will act as if ``auto_id`` is ``True``.
-
-By default, ``auto_id`` is set to the string ``'id_%s'``.
-
-Normally, a colon (``:``) will be appended after any label name when a form is
-rendered. It's possible to change the colon to another character, or omit it
-entirely, using the ``label_suffix`` parameter::
-
-    >>> f = ContactForm(auto_id='id_for_%s', label_suffix='')
-    >>> print f.as_ul()
-    <li><label for="id_for_subject">Subject</label> <input id="id_for_subject" type="text" name="subject" maxlength="100" /></li>
-    <li><label for="id_for_message">Message</label> <input type="text" name="message" id="id_for_message" /></li>
-    <li><label for="id_for_sender">Sender</label> <input type="text" name="sender" id="id_for_sender" /></li>
-    <li><label for="id_for_cc_myself">Cc myself</label> <input type="checkbox" name="cc_myself" id="id_for_cc_myself" /></li>
-    >>> f = ContactForm(auto_id='id_for_%s', label_suffix=' ->')
-    >>> print f.as_ul()
-    <li><label for="id_for_subject">Subject -></label> <input id="id_for_subject" type="text" name="subject" maxlength="100" /></li>
-    <li><label for="id_for_message">Message -></label> <input type="text" name="message" id="id_for_message" /></li>
-    <li><label for="id_for_sender">Sender -></label> <input type="text" name="sender" id="id_for_sender" /></li>
-    <li><label for="id_for_cc_myself">Cc myself -></label> <input type="checkbox" name="cc_myself" id="id_for_cc_myself" /></li>
-
-Note that the label suffix is added only if the last character of the
-label isn't a punctuation character (``.``, ``!``, ``?`` or ``:``)
-
-Notes on field ordering
-~~~~~~~~~~~~~~~~~~~~~~~
-
-In the ``as_p()``, ``as_ul()`` and ``as_table()`` shortcuts, the fields are
-displayed in the order in which you define them in your form class. For
-example, in the ``ContactForm`` example, the fields are defined in the order
-``subject``, ``message``, ``sender``, ``cc_myself``. To reorder the HTML
-output, just change the order in which those fields are listed in the class.
-
-How errors are displayed
-~~~~~~~~~~~~~~~~~~~~~~~~
-
-If you render a bound ``Form`` object, the act of rendering will automatically
-run the form's validation if it hasn't already happened, and the HTML output
-will include the validation errors as a ``<ul class="errorlist">`` near the
-field. The particular positioning of the error messages depends on the output
-method you're using::
-
-    >>> data = {'subject': '',
-    ...         'message': 'Hi there',
-    ...         'sender': 'invalid e-mail address',
-    ...         'cc_myself': True}
-    >>> f = ContactForm(data, auto_id=False)
-    >>> print f.as_table()
-    <tr><th>Subject:</th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="text" name="subject" maxlength="100" /></td></tr>
-    <tr><th>Message:</th><td><input type="text" name="message" value="Hi there" /></td></tr>
-    <tr><th>Sender:</th><td><ul class="errorlist"><li>Enter a valid e-mail address.</li></ul><input type="text" name="sender" value="invalid e-mail address" /></td></tr>
-    <tr><th>Cc myself:</th><td><input checked="checked" type="checkbox" name="cc_myself" /></td></tr>
-    >>> print f.as_ul()
-    <li><ul class="errorlist"><li>This field is required.</li></ul>Subject: <input type="text" name="subject" maxlength="100" /></li>
-    <li>Message: <input type="text" name="message" value="Hi there" /></li>
-    <li><ul class="errorlist"><li>Enter a valid e-mail address.</li></ul>Sender: <input type="text" name="sender" value="invalid e-mail address" /></li>
-    <li>Cc myself: <input checked="checked" type="checkbox" name="cc_myself" /></li>
-    >>> print f.as_p()
-    <p><ul class="errorlist"><li>This field is required.</li></ul></p>
-    <p>Subject: <input type="text" name="subject" maxlength="100" /></p>
-    <p>Message: <input type="text" name="message" value="Hi there" /></p>
-    <p><ul class="errorlist"><li>Enter a valid e-mail address.</li></ul></p>
-    <p>Sender: <input type="text" name="sender" value="invalid e-mail address" /></p>
-    <p>Cc myself: <input checked="checked" type="checkbox" name="cc_myself" /></p>
-
-Customizing the error list format
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-By default, forms use ``django.forms.util.ErrorList`` to format validation
-errors. If you'd like to use an alternate class for displaying errors, you can
-pass that in at construction time::
-
-    >>> from django.forms.util import ErrorList
-    >>> class DivErrorList(ErrorList):
-    ...     def __unicode__(self):
-    ...         return self.as_divs()
-    ...     def as_divs(self):
-    ...         if not self: return u''
-    ...         return u'<div class="errorlist">%s</div>' % ''.join([u'<div class="error">%s</div>' % e for e in self])
-    >>> f = ContactForm(data, auto_id=False, error_class=DivErrorList)
-    >>> f.as_p()
-    <div class="errorlist"><div class="error">This field is required.</div></div>
-    <p>Subject: <input type="text" name="subject" maxlength="100" /></p>
-    <p>Message: <input type="text" name="message" value="Hi there" /></p>
-    <div class="errorlist"><div class="error">Enter a valid e-mail address.</div></div>
-    <p>Sender: <input type="text" name="sender" value="invalid e-mail address" /></p>
-    <p>Cc myself: <input checked="checked" type="checkbox" name="cc_myself" /></p>
-
-More granular output
-~~~~~~~~~~~~~~~~~~~~
-
-The ``as_p()``, ``as_ul()`` and ``as_table()`` methods are simply shortcuts for
-lazy developers -- they're not the only way a form object can be displayed.
-
-To display the HTML for a single field in your form, use dictionary lookup
-syntax using the field's name as the key, and print the resulting object::
-
-    >>> f = ContactForm()
-    >>> print f['subject']
-    <input id="id_subject" type="text" name="subject" maxlength="100" />
-    >>> print f['message']
-    <input type="text" name="message" id="id_message" />
-    >>> print f['sender']
-    <input type="text" name="sender" id="id_sender" />
-    >>> print f['cc_myself']
-    <input type="checkbox" name="cc_myself" id="id_cc_myself" />
-
-Call ``str()`` or ``unicode()`` on the field to get its rendered HTML as a
-string or Unicode object, respectively::
-
-    >>> str(f['subject'])
-    '<input id="id_subject" type="text" name="subject" maxlength="100" />'
-    >>> unicode(f['subject'])
-    u'<input id="id_subject" type="text" name="subject" maxlength="100" />'
-
-The field-specific output honors the form object's ``auto_id`` setting::
-
-    >>> f = ContactForm(auto_id=False)
-    >>> print f['message']
-    <input type="text" name="message" />
-    >>> f = ContactForm(auto_id='id_%s')
-    >>> print f['message']
-    <input type="text" name="message" id="id_message" />
-
-For a field's list of errors, access the field's ``errors`` attribute. This
-is a list-like object that is displayed as an HTML ``<ul class="errorlist">``
-when printed::
-
-    >>> data = {'subject': 'hi', 'message': '', 'sender': '', 'cc_myself': ''}
-    >>> f = ContactForm(data, auto_id=False)
-    >>> print f['message']
-    <input type="text" name="message" />
-    >>> f['message'].errors
-    [u'This field is required.']
-    >>> print f['message'].errors
-    <ul class="errorlist"><li>This field is required.</li></ul>
-    >>> f['subject'].errors
-    []
-    >>> print f['subject'].errors
-
-    >>> str(f['subject'].errors)
-    ''
-
-Using forms in views and templates
-----------------------------------
-
-Let's put this all together and use the ``ContactForm`` example in a Django
-view and template.
-
-Simple view example
-~~~~~~~~~~~~~~~~~~~
-
-This example view displays the contact form by default and validates/processes
-it if accessed via a POST request::
-
-    def contact(request):
-        if request.method == 'POST':
-            form = ContactForm(request.POST)
-            if form.is_valid():
-                # Do form processing here...
-                return HttpResponseRedirect('/url/on_success/')
-        else:
-            form = ContactForm()
-        return render_to_response('contact.html', {'form': form})
-
-Simple template example
-~~~~~~~~~~~~~~~~~~~~~~~
-
-The template in the above view example, ``contact.html``, is responsible for
-displaying the form as HTML. To do this, we can use the techniques outlined in
-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" action="">
-    <table>{{ form }}</table>
-    <input type="submit" />
-    </form>
-
-The above template code will display the form as an HTML table, using the
-``form.as_table()`` method explained previously. This works because Django's
-template system displays an object's ``__str__()`` value, and the ``Form``
-class' ``__str__()`` method calls its ``as_table()`` method.
-
-The following is equivalent but a bit more explicit::
-
-    <form method="post" action="">
-    <table>{{ form.as_table }}</table>
-    <input type="submit" />
-    </form>
-
-``form.as_ul`` and ``form.as_p`` are also available, as you may expect.
-
-Note that in the above two examples, we included the ``<form>``, ``<table>``
-``<input type="submit" />``, ``</table>`` and ``</form>`` tags. The form
-convenience methods (``as_table()``, ``as_ul()`` and ``as_p()``) do not include
-that HTML.
-
-Complex template output
-~~~~~~~~~~~~~~~~~~~~~~~
-
-As we've stressed several times, the ``as_table()``, ``as_ul()`` and ``as_p()``
-methods are just shortcuts for the common case. You can also work with the
-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" action="">
-    <dl>
-    {% for field in form %}
-        <dt>{{ field.label_tag }}</dt>
-        <dd>{{ field }}</dd>
-        {% if field.help_text %}<dd>{{ field.help_text }}</dd>{% endif %}
-        {% if field.errors %}<dd class="myerrors">{{ field.errors }}</dd>{% endif %}
-    {% endfor %}
-    </dl>
-    <input type="submit" />
-    </form>
-
-This iteration technique is useful if you want to apply the same HTML
-formatting to each field, or if you don't know the names of the form fields
-ahead of time. Note that the fields will be iterated over in the order in which
-they're defined in the ``Form`` class.
-
-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" action="">
-    <ul class="myformclass">
-        <li>{{ form.sender.label_tag }} {{ form.sender }}</li>
-        <li class="helptext">{{ form.sender.help_text }}</li>
-        {% if form.sender.errors %}<ul class="errorlist">{{ form.sender.errors }}</ul>{% endif %}
-
-        <li>{{ form.subject.label_tag }} {{ form.subject }}</li>
-        <li class="helptext">{{ form.subject.help_text }}</li>
-        {% if form.subject.errors %}<ul class="errorlist">{{ form.subject.errors }}</ul>{% endif %}
-
-        ...
-    </ul>
-    </form>
-
-Highlighting required fields in templates
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-It's common to show a user which fields are required. Here's an example of how
-to do that, using the above example modified to insert an asterisk after the
-label of each required field::
-
-    <form method="post" action="">
-    <dl>
-    {% for field in form %}
-        <dt>{{ field.label_tag }}{% if field.field.required %}*{% endif %}</dt>
-        <dd>{{ field }}</dd>
-        {% if field.help_text %}<dd>{{ field.help_text }}</dd>{% endif %}
-        {% if field.errors %}<dd class="myerrors">{{ field.errors }}</dd>{% endif %}
-    {% endfor %}
-    </dl>
-    <input type="submit" />
-    </form>
-
-The ``{% if field.field.required %}*{% endif %}`` fragment is the relevant
-addition here. It adds the asterisk only if the field is required.
-
-Note that we check ``field.field.required`` and not ``field.required``. In the
-template, ``field`` is a ``forms.forms.BoundField`` instance, which holds
-the actual ``Field`` instance in its ``field`` attribute.
-
-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
-    >>> from django.core.files.uploadedfile import SimpleUploadedFile
-    >>> data = {'subject': 'hello',
-    ...         'message': 'Hi there',
-    ...         'sender': 'foo@example.com',
-    ...         'cc_myself': True}
-    >>> file_data = {'mugshot': SimpleUploadedFile('face.jpg', <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()
-
-Testing for multipart forms
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-If you're writing reusable views or templates, you may not know ahead of time
-whether your form is a multipart form or not. The ``is_multipart()`` method
-tells you whether the form requires multipart encoding for submission::
-
-    >>> f = ContactFormWithMugshot()
-    >>> f.is_multipart()
-    True
-
-Here's an example of how you might use this in a template::
-
-    {% if form.is_multipart %}
-        <form enctype="multipart/form-data" method="post" action="/foo/">
-    {% else %}
-        <form method="post" action="/foo/">
-    {% endif %}
-    {{ form }}
-    </form>
-
-Subclassing forms
------------------
-
-If you have multiple ``Form`` classes that share fields, you can use
-subclassing to remove redundancy.
-
-When you subclass a custom ``Form`` class, the resulting subclass will
-include all fields of the parent class(es), followed by the fields you define
-in the subclass.
-
-In this example, ``ContactFormWithPriority`` contains all the fields from
-``ContactForm``, plus an additional field, ``priority``. The ``ContactForm``
-fields are ordered first::
-
-    >>> class ContactFormWithPriority(ContactForm):
-    ...     priority = forms.CharField()
-    >>> f = ContactFormWithPriority(auto_id=False)
-    >>> print f.as_ul()
-    <li>Subject: <input type="text" name="subject" maxlength="100" /></li>
-    <li>Message: <input type="text" name="message" /></li>
-    <li>Sender: <input type="text" name="sender" /></li>
-    <li>Cc myself: <input type="checkbox" name="cc_myself" /></li>
-    <li>Priority: <input type="text" name="priority" /></li>
-
-It's possible to subclass multiple forms, treating forms as "mix-ins." In this
-example, ``BeatleForm`` subclasses both ``PersonForm`` and ``InstrumentForm``
-(in that order), and its field list includes the fields from the parent
-classes::
-
-    >>> class PersonForm(Form):
-    ...     first_name = CharField()
-    ...     last_name = CharField()
-    >>> class InstrumentForm(Form):
-    ...     instrument = CharField()
-    >>> class BeatleForm(PersonForm, InstrumentForm):
-    ...     haircut_type = CharField()
-    >>> b = BeatleForm(auto_id=False)
-    >>> print b.as_ul()
-    <li>First name: <input type="text" name="first_name" /></li>
-    <li>Last name: <input type="text" name="last_name" /></li>
-    <li>Instrument: <input type="text" name="instrument" /></li>
-    <li>Haircut type: <input type="text" name="haircut_type" /></li>
-
-Prefixes for forms
-------------------
-
-You can put several Django forms inside one ``<form>`` tag. To give each
-``Form`` its own namespace, use the ``prefix`` keyword argument::
-
-    >>> mother = PersonForm(prefix="mother")
-    >>> father = PersonForm(prefix="father")
-    >>> print mother.as_ul()
-    <li><label for="id_mother-first_name">First name:</label> <input type="text" name="mother-first_name" id="id_mother-first_name" /></li>
-    <li><label for="id_mother-last_name">Last name:</label> <input type="text" name="mother-last_name" id="id_mother-last_name" /></li>
-    >>> print father.as_ul()
-    <li><label for="id_father-first_name">First name:</label> <input type="text" name="father-first_name" id="id_father-first_name" /></li>
-    <li><label for="id_father-last_name">Last name:</label> <input type="text" name="father-last_name" id="id_father-last_name" /></li>
-
-Fields
-======
-
-When you create a ``Form`` class, the most important part is defining the
-fields of the form. Each field has custom validation logic, along with a few
-other hooks.
-
-Although the primary way you'll use ``Field`` classes is in ``Form`` classes,
-you can also instantiate them and use them directly to get a better idea of
-how they work. Each ``Field`` instance has a ``clean()`` method, which takes
-a single argument and either raises a ``django.forms.ValidationError``
-exception or returns the clean value::
-
-    >>> f = forms.EmailField()
-    >>> f.clean('foo@example.com')
-    u'foo@example.com'
-    >>> f.clean(u'foo@example.com')
-    u'foo@example.com'
-    >>> f.clean('invalid e-mail address')
-    Traceback (most recent call last):
-    ...
-    ValidationError: [u'Enter a valid e-mail address.']
-
-If you've used Django's old forms/validation framework, take care in noticing
-this ``ValidationError`` is different than the previous ``ValidationError``.
-This one lives at ``django.forms.ValidationError`` rather than
-``django.core.validators.ValidationError``.
-
-Core field arguments
---------------------
-
-Each ``Field`` class constructor takes at least these arguments. Some
-``Field`` classes take additional, field-specific arguments, but the following
-should *always* be accepted:
-
-``required``
-~~~~~~~~~~~~
-
-By default, each ``Field`` class assumes the value is required, so if you pass
-an empty value -- either ``None`` or the empty string (``""``) -- then
-``clean()`` will raise a ``ValidationError`` exception::
-
-    >>> f = forms.CharField()
-    >>> f.clean('foo')
-    u'foo'
-    >>> f.clean('')
-    Traceback (most recent call last):
-    ...
-    ValidationError: [u'This field is required.']
-    >>> f.clean(None)
-    Traceback (most recent call last):
-    ...
-    ValidationError: [u'This field is required.']
-    >>> f.clean(' ')
-    u' '
-    >>> f.clean(0)
-    u'0'
-    >>> f.clean(True)
-    u'True'
-    >>> f.clean(False)
-    u'False'
-
-To specify that a field is *not* required, pass ``required=False`` to the
-``Field`` constructor::
-
-    >>> f = forms.CharField(required=False)
-    >>> f.clean('foo')
-    u'foo'
-    >>> f.clean('')
-    u''
-    >>> f.clean(None)
-    u''
-    >>> f.clean(0)
-    u'0'
-    >>> f.clean(True)
-    u'True'
-    >>> f.clean(False)
-    u'False'
-
-If a ``Field`` has ``required=False`` and you pass ``clean()`` an empty value,
-then ``clean()`` will return a *normalized* empty value rather than raising
-``ValidationError``. For ``CharField``, this will be a Unicode empty string.
-For other ``Field`` classes, it might be ``None``. (This varies from field to
-field.)
-
-``label``
-~~~~~~~~~
-
-The ``label`` argument lets you specify the "human-friendly" label for this
-field. This is used when the ``Field`` is displayed in a ``Form``.
-
-As explained in "Outputting forms as HTML" above, the default label for a
-``Field`` is generated from the field name by converting all underscores to
-spaces and upper-casing the first letter. Specify ``label`` if that default
-behavior doesn't result in an adequate label.
-
-Here's a full example ``Form`` that implements ``label`` for two of its fields.
-We've specified ``auto_id=False`` to simplify the output::
-
-    >>> class CommentForm(forms.Form):
-    ...     name = forms.CharField(label='Your name')
-    ...     url = forms.URLField(label='Your Web site', required=False)
-    ...     comment = forms.CharField()
-    >>> f = CommentForm(auto_id=False)
-    >>> print f
-    <tr><th>Your name:</th><td><input type="text" name="name" /></td></tr>
-    <tr><th>Your Web site:</th><td><input type="text" name="url" /></td></tr>
-    <tr><th>Comment:</th><td><input type="text" name="comment" /></td></tr>
-
-``initial``
-~~~~~~~~~~~
-
-The ``initial`` argument lets you specify the initial value to use when
-rendering this ``Field`` in an unbound ``Form``.
-
-The use-case for this is when you want to display an "empty" form in which a
-field is initialized to a particular value. For example::
-
-    >>> class CommentForm(forms.Form):
-    ...     name = forms.CharField(initial='Your name')
-    ...     url = forms.URLField(initial='http://')
-    ...     comment = forms.CharField()
-    >>> f = CommentForm(auto_id=False)
-    >>> print f
-    <tr><th>Name:</th><td><input type="text" name="name" value="Your name" /></td></tr>
-    <tr><th>Url:</th><td><input type="text" name="url" value="http://" /></td></tr>
-    <tr><th>Comment:</th><td><input type="text" name="comment" /></td></tr>
-
-You may be thinking, why not just pass a dictionary of the initial values as
-data when displaying the form? Well, if you do that, you'll trigger validation,
-and the HTML output will include any validation errors::
-
-    >>> class CommentForm(forms.Form):
-    ...     name = forms.CharField()
-    ...     url = forms.URLField()
-    ...     comment = forms.CharField()
-    >>> default_data = {'name': 'Your name', 'url': 'http://'}
-    >>> f = CommentForm(default_data, auto_id=False)
-    >>> print f
-    <tr><th>Name:</th><td><input type="text" name="name" value="Your name" /></td></tr>
-    <tr><th>Url:</th><td><ul class="errorlist"><li>Enter a valid URL.</li></ul><input type="text" name="url" value="http://" /></td></tr>
-    <tr><th>Comment:</th><td><ul class="errorlist"><li>This field is required.</li></ul><input type="text" name="comment" /></td></tr>
-
-This is why ``initial`` values are only displayed for unbound forms. For bound
-forms, the HTML output will use the bound data.
-
-Also note that ``initial`` values are *not* used as "fallback" data in
-validation if a particular field's value is not given. ``initial`` values are
-*only* intended for initial form display::
-
-    >>> class CommentForm(forms.Form):
-    ...     name = forms.CharField(initial='Your name')
-    ...     url = forms.URLField(initial='http://')
-    ...     comment = forms.CharField()
-    >>> data = {'name': '', 'url': '', 'comment': 'Foo'}
-    >>> f = CommentForm(data)
-    >>> f.is_valid()
-    False
-    # The form does *not* fall back to using the initial values.
-    >>> f.errors
-    {'url': [u'This field is required.'], 'name': [u'This field is required.']}
-
-``widget``
-~~~~~~~~~~
-
-The ``widget`` argument lets you specify a ``Widget`` class to use when
-rendering this ``Field``. See `Widgets`_ below for more information.
-
-``help_text``
-~~~~~~~~~~~~~
-
-The ``help_text`` argument lets you specify descriptive text for this
-``Field``. If you provide ``help_text``, it will be displayed next to the
-``Field`` when the ``Field`` is rendered by one of the convenience ``Form``
-methods (e.g., ``as_ul()``).
-
-Here's a full example ``Form`` that implements ``help_text`` for two of its
-fields. We've specified ``auto_id=False`` to simplify the output::
-
-    >>> class HelpTextContactForm(forms.Form):
-    ...     subject = forms.CharField(max_length=100, help_text='100 characters max.')
-    ...     message = forms.CharField()
-    ...     sender = forms.EmailField(help_text='A valid e-mail address, please.')
-    ...     cc_myself = forms.BooleanField(required=False)
-    >>> f = HelpTextContactForm(auto_id=False)
-    >>> print f.as_table()
-    <tr><th>Subject:</th><td><input type="text" name="subject" maxlength="100" /><br />100 characters max.</td></tr>
-    <tr><th>Message:</th><td><input type="text" name="message" /></td></tr>
-    <tr><th>Sender:</th><td><input type="text" name="sender" /><br />A valid e-mail address, please.</td></tr>
-    <tr><th>Cc myself:</th><td><input type="checkbox" name="cc_myself" /></td></tr>
-    >>> print f.as_ul()
-    <li>Subject: <input type="text" name="subject" maxlength="100" /> 100 characters max.</li>
-    <li>Message: <input type="text" name="message" /></li>
-    <li>Sender: <input type="text" name="sender" /> A valid e-mail address, please.</li>
-    <li>Cc myself: <input type="checkbox" name="cc_myself" /></li>
-    >>> print f.as_p()
-    <p>Subject: <input type="text" name="subject" maxlength="100" /> 100 characters max.</p>
-    <p>Message: <input type="text" name="message" /></p>
-    <p>Sender: <input type="text" name="sender" /> A valid e-mail address, please.</p>
-    <p>Cc myself: <input type="checkbox" name="cc_myself" /></p>
-
-``error_messages``
-~~~~~~~~~~~~~~~~~~
-
-**New in Django development version**
-
-The ``error_messages`` argument lets you override the default messages that the
-field will raise. Pass in a dictionary with keys matching the error messages you
-want to override. For example, here is the default error message::
-
-    >>> generic = forms.CharField()
-    >>> generic.clean('')
-    Traceback (most recent call last):
-      ...
-    ValidationError: [u'This field is required.']
-
-And here is a custom error message::
-
-    >>> name = forms.CharField(error_messages={'required': 'Please enter your name'})
-    >>> name.clean('')
-    Traceback (most recent call last):
-      ...
-    ValidationError: [u'Please enter your name']
-
-In the `built-in Field classes`_ section below, each ``Field`` defines the
-error message keys it uses.
-
-Dynamic initial values
-----------------------
-
-The ``initial`` argument to ``Field`` (explained above) lets you hard-code the
-initial value for a ``Field`` -- but what if you want to declare the initial
-value at runtime? For example, you might want to fill in a ``username`` field
-with the username of the current session.
-
-To accomplish this, use the ``initial`` argument to a ``Form``. This argument,
-if given, should be a dictionary mapping field names to initial values. Only
-include the fields for which you're specifying an initial value; it's not
-necessary to include every field in your form. For example::
-
-    >>> class CommentForm(forms.Form):
-    ...     name = forms.CharField()
-    ...     url = forms.URLField()
-    ...     comment = forms.CharField()
-    >>> f = CommentForm(initial={'name': 'your username'}, auto_id=False)
-    >>> print f
-    <tr><th>Name:</th><td><input type="text" name="name" value="your username" /></td></tr>
-    <tr><th>Url:</th><td><input type="text" name="url" /></td></tr>
-    <tr><th>Comment:</th><td><input type="text" name="comment" /></td></tr>
-    >>> f = CommentForm(initial={'name': 'another username'}, auto_id=False)
-    >>> print f
-    <tr><th>Name:</th><td><input type="text" name="name" value="another username" /></td></tr>
-    <tr><th>Url:</th><td><input type="text" name="url" /></td></tr>
-    <tr><th>Comment:</th><td><input type="text" name="comment" /></td></tr>
-
-Just like the ``initial`` parameter to ``Field``, these values are only
-displayed for unbound forms, and they're not used as fallback values if a
-particular value isn't provided.
-
-Finally, note that if a ``Field`` defines ``initial`` *and* you include
-``initial`` when instantiating the ``Form``, then the latter ``initial`` will
-have precedence. In this example, ``initial`` is provided both at the field
-level and at the form instance level, and the latter gets precedence::
-
-    >>> class CommentForm(forms.Form):
-    ...     name = forms.CharField(initial='class')
-    ...     url = forms.URLField()
-    ...     comment = forms.CharField()
-    >>> f = CommentForm(initial={'name': 'instance'}, auto_id=False)
-    >>> print f
-    <tr><th>Name:</th><td><input type="text" name="name" value="instance" /></td></tr>
-    <tr><th>Url:</th><td><input type="text" name="url" /></td></tr>
-    <tr><th>Comment:</th><td><input type="text" name="comment" /></td></tr>
-
-Built-in ``Field`` classes
---------------------------
-
-Naturally, the ``forms`` library comes with a set of ``Field`` classes that
-represent common validation needs. This section documents each built-in field.
-
-For each field, we describe the default widget used if you don't specify
-``widget``. We also specify the value returned when you provide an empty value
-(see the section on ``required`` above to understand what that means).
-
-``BooleanField``
-~~~~~~~~~~~~~~~~
-
-    * Default widget: ``CheckboxInput``
-    * Empty value: ``False``
-    * Normalizes to: A Python ``True`` or ``False`` value.
-    * Validates that the check box is checked (i.e. the value is ``True``) if
-      the field has ``required=True``.
-    * Error message keys: ``required``
-
-**New in Django development version:** The empty value for a ``CheckboxInput``
-(and hence the standard ``BooleanField``) has changed to return ``False``
-instead of ``None`` in the development version.
-
-.. note::
-    Since all ``Field`` subclasses have ``required=True`` by default, the
-    validation condition here is important. If you want to include a checkbox
-    in your form that can be either checked or unchecked, you must remember to
-    pass in ``required=False`` when creating the ``BooleanField``.
-
-``CharField``
-~~~~~~~~~~~~~
-
-    * Default widget: ``TextInput``
-    * Empty value: ``''`` (an empty string)
-    * Normalizes to: A Unicode object.
-    * Validates ``max_length`` or ``min_length``, if they are provided.
-      Otherwise, all inputs are valid.
-    * Error message keys: ``required``, ``max_length``, ``min_length``
-
-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.
-
-``ChoiceField``
-~~~~~~~~~~~~~~~
-
-    * Default widget: ``Select``
-    * Empty value: ``''`` (an empty string)
-    * Normalizes to: A Unicode object.
-    * Validates that the given value exists in the list of choices.
-    * Error message keys: ``required``, ``invalid_choice``
-
-Takes one extra argument, ``choices``, which is an iterable (e.g., a list or
-tuple) of 2-tuples to use as choices for this field. This argument accepts
-the same formats as the ``choices`` argument to a model field. See the
-`model API documentation on choices`_ for more details.
-
-.. _model API documentation on choices: ../model-api#choices
-
-``DateField``
-~~~~~~~~~~~~~
-
-    * Default widget: ``TextInput``
-    * Empty value: ``None``
-    * Normalizes to: A Python ``datetime.date`` object.
-    * Validates that the given value is either a ``datetime.date``,
-      ``datetime.datetime`` or string formatted in a particular date format.
-    * Error message keys: ``required``, ``invalid``
-
-Takes one optional argument, ``input_formats``, which is a list of formats used
-to attempt to convert a string to a valid ``datetime.date`` object.
-
-If no ``input_formats`` argument is provided, the default input formats are::
-
-    '%Y-%m-%d', '%m/%d/%Y', '%m/%d/%y', # '2006-10-25', '10/25/2006', '10/25/06'
-    '%b %d %Y', '%b %d, %Y',            # 'Oct 25 2006', 'Oct 25, 2006'
-    '%d %b %Y', '%d %b, %Y',            # '25 Oct 2006', '25 Oct, 2006'
-    '%B %d %Y', '%B %d, %Y',            # 'October 25 2006', 'October 25, 2006'
-    '%d %B %Y', '%d %B, %Y',            # '25 October 2006', '25 October, 2006'
-
-``DateTimeField``
-~~~~~~~~~~~~~~~~~
-
-    * Default widget: ``DateTimeInput``
-    * Empty value: ``None``
-    * Normalizes to: A Python ``datetime.datetime`` object.
-    * Validates that the given value is either a ``datetime.datetime``,
-      ``datetime.date`` or string formatted in a particular datetime format.
-    * Error message keys: ``required``, ``invalid``
-
-Takes one optional argument, ``input_formats``, which is a list of formats used
-to attempt to convert a string to a valid ``datetime.datetime`` object.
-
-If no ``input_formats`` argument is provided, the default input formats are::
-
-    '%Y-%m-%d %H:%M:%S',     # '2006-10-25 14:30:59'
-    '%Y-%m-%d %H:%M',        # '2006-10-25 14:30'
-    '%Y-%m-%d',              # '2006-10-25'
-    '%m/%d/%Y %H:%M:%S',     # '10/25/2006 14:30:59'
-    '%m/%d/%Y %H:%M',        # '10/25/2006 14:30'
-    '%m/%d/%Y',              # '10/25/2006'
-    '%m/%d/%y %H:%M:%S',     # '10/25/06 14:30:59'
-    '%m/%d/%y %H:%M',        # '10/25/06 14:30'
-    '%m/%d/%y',              # '10/25/06'
-
-**New in Django development version:** The ``DateTimeField`` used to use a
-``TextInput`` widget by default. This has now changed.
-
-``DecimalField``
-~~~~~~~~~~~~~~~~
-
-**New in Django development version**
-
-    * Default widget: ``TextInput``
-    * Empty value: ``None``
-    * Normalizes to: A Python ``decimal``.
-    * Validates that the given value is a decimal. Leading and trailing
-      whitespace is ignored.
-    * Error message keys: ``required``, ``invalid``, ``max_value``,
-      ``min_value``, ``max_digits``, ``max_decimal_places``,
-      ``max_whole_digits``
-
-Takes four optional arguments: ``max_value``, ``min_value``, ``max_digits``,
-and ``decimal_places``. The first two define the limits for the fields value.
-``max_digits`` is the maximum number of digits (those before the decimal
-point plus those after the decimal point, with leading zeros stripped)
-permitted in the value, whilst ``decimal_places`` is the maximum number of
-decimal places permitted.
-
-``EmailField``
-~~~~~~~~~~~~~~
-
-    * Default widget: ``TextInput``
-    * Empty value: ``''`` (an empty string)
-    * Normalizes to: A Unicode object.
-    * Validates that the given value is a valid e-mail address, using a
-      moderately complex regular expression.
-    * Error message keys: ``required``, ``invalid``
-
-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.
-    * Error message keys: ``required``, ``invalid``, ``missing``, ``empty``
-
-To learn more about the ``UploadedFile`` object, see the `file uploads documentation`_.
-
-When you use a ``FileField`` in a form, you must also remember to
-`bind the file data to the form`_.
-
-.. _file uploads documentation: ../upload_handling/
-.. _`bind the file data to the form`: `Binding uploaded files to a form`_
-
-``FilePathField``
-~~~~~~~~~~~~~~~~~
-
-**New in Django development version**
-
-    * Default widget: ``Select``
-    * Empty value: ``None``
-    * Normalizes to: A unicode object
-    * Validates that the selected choice exists in the list of choices.
-    * Error message keys: ``required``, ``invalid_choice``
-
-The field allows choosing from files inside a certain directory. It takes three
-extra arguments:
-
-    ==============  ==========  ===============================================
-    Argument        Required?   Description
-    ==============  ==========  ===============================================
-    ``path``        Yes         The absolute path to the directory whose
-                                contents you want listed. This directory must
-                                exist.
-
-    ``recursive``   No          If ``False`` (the default) only the direct
-                                contents of ``path`` will be offered as choices.
-                                If ``True``, the directory will be descended
-                                into recursively and all descendants will be
-                                listed as choices.
-
-    ``match``       No          A regular expression pattern; only files with
-                                names matching this expression will be allowed
-                                as choices.
-    ==============  ==========  ===============================================
-
-``FloatField``
-~~~~~~~~~~~~~~
-
-    * Default widget: ``TextInput``
-    * Empty value: ``None``
-    * Normalizes to: A Python float.
-    * Validates that the given value is an float. Leading and trailing
-      whitespace is allowed, as in Python's ``float()`` function.
-    * Error message keys: ``required``, ``invalid``, ``max_value``,
-      ``min_value``
-
-Takes two optional arguments for validation, ``max_value`` and ``min_value``.
-These control the range of values permitted in the field.
-
-``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.
-    * Error message keys: ``required``, ``invalid``, ``missing``, ``empty``,
-      ``invalid_image``
-
-Using an ImageField requires that the `Python Imaging Library`_ is installed.
-
-When you use an ``ImageField`` in a form, you must also remember to
-`bind the file data to the form`_.
-
-.. _Python Imaging Library: http://www.pythonware.com/products/pil/
-
-``IntegerField``
-~~~~~~~~~~~~~~~~
-
-    * Default widget: ``TextInput``
-    * Empty value: ``None``
-    * Normalizes to: A Python integer or long integer.
-    * Validates that the given value is an integer. Leading and trailing
-      whitespace is allowed, as in Python's ``int()`` function.
-    * Error message keys: ``required``, ``invalid``, ``max_value``,
-      ``min_value``
-
-Takes two optional arguments for validation, ``max_value`` and ``min_value``.
-These control the range of values permitted in the field.
-
-``IPAddressField``
-~~~~~~~~~~~~~~~~~~
-
-    * Default widget: ``TextInput``
-    * Empty value: ``''`` (an empty string)
-    * Normalizes to: A Unicode object.
-    * Validates that the given value is a valid IPv4 address, using a regular
-      expression.
-    * Error message keys: ``required``, ``invalid``
-
-``MultipleChoiceField``
-~~~~~~~~~~~~~~~~~~~~~~~
-
-    * Default widget: ``SelectMultiple``
-    * Empty value: ``[]`` (an empty list)
-    * Normalizes to: A list of Unicode objects.
-    * Validates that every value in the given list of values exists in the list
-      of choices.
-    * Error message keys: ``required``, ``invalid_choice``, ``invalid_list``
-
-Takes one extra argument, ``choices``, which is an iterable (e.g., a list or
-tuple) of 2-tuples to use as choices for this field. This argument accepts
-the same formats as the ``choices`` argument to a model field. See the
-`model API documentation on choices`_ for more details.
-
-``NullBooleanField``
-~~~~~~~~~~~~~~~~~~~~
-
-    * Default widget: ``NullBooleanSelect``
-    * Empty value: ``None``
-    * Normalizes to: A Python ``True``, ``False`` or ``None`` value.
-    * Validates nothing (i.e., it never raises a ``ValidationError``).
-
-``RegexField``
-~~~~~~~~~~~~~~
-
-    * Default widget: ``TextInput``
-    * Empty value: ``''`` (an empty string)
-    * Normalizes to: A Unicode object.
-    * Validates that the given value matches against a certain regular
-      expression.
-    * Error message keys: ``required``, ``invalid``
-
-Takes one required argument, ``regex``, which is a regular expression specified
-either as a string or a compiled regular expression object.
-
-Also takes the following optional arguments:
-
-    ======================  =====================================================
-    Argument                Description
-    ======================  =====================================================
-    ``max_length``          Ensures the string has at most this many characters.
-    ``min_length``          Ensures the string has at least this many characters.
-    ======================  =====================================================
-
-The optional argument ``error_message`` is also accepted for backwards
-compatibility. The preferred way to provide an error message is to use the
-``error_messages`` argument, passing a dictionary with ``'invalid'`` as a key
-and the error message as the value.
-
-``TimeField``
-~~~~~~~~~~~~~
-
-    * Default widget: ``TextInput``
-    * Empty value: ``None``
-    * Normalizes to: A Python ``datetime.time`` object.
-    * Validates that the given value is either a ``datetime.time`` or string
-      formatted in a particular time format.
-    * Error message keys: ``required``, ``invalid``
-
-Takes one optional argument, ``input_formats``, which is a list of formats used
-to attempt to convert a string to a valid ``datetime.time`` object.
-
-If no ``input_formats`` argument is provided, the default input formats are::
-
-    '%H:%M:%S',     # '14:30:59'
-    '%H:%M',        # '14:30'
-
-``URLField``
-~~~~~~~~~~~~
-
-    * Default widget: ``TextInput``
-    * Empty value: ``''`` (an empty string)
-    * Normalizes to: A Unicode object.
-    * Validates that the given value is a valid URL.
-    * Error message keys: ``required``, ``invalid``, ``invalid_link``
-
-Takes the following optional arguments:
-
-    ========================  =====================================================
-    Argument                  Description
-    ========================  =====================================================
-    ``max_length``            Ensures the string has at most this many characters.
-    ``min_length``            Ensures the string has at least this many characters.
-    ``verify_exists``         If ``True``, the validator will attempt to load the
-                              given URL, raising ``ValidationError`` if the page
-                              gives a 404. Defaults to ``False``.
-    ``validator_user_agent``  String used as the user-agent used when checking for
-                              a URL's existence. Defaults to the value of the
-                              ``URL_VALIDATOR_USER_AGENT`` setting.
-    ========================  =====================================================
-
-Slightly complex built-in ``Field`` classes
--------------------------------------------
-
-The following are not yet documented here. See the unit tests, linked-to from
-the bottom of this document, for examples of their use.
-
-``ComboField``
-~~~~~~~~~~~~~~
-
-``MultiValueField``
-~~~~~~~~~~~~~~~~~~~
-
-``SplitDateTimeField``
-~~~~~~~~~~~~~~~~~~~~~~
-
-Fields which handle relationships
----------------------------------
-
-For representing relationships between models, two fields are
-provided which can derive their choices from a ``QuerySet``, and which
-place one or more model objects into the ``cleaned_data`` dictionary
-of forms in which they're used. Both of these fields have an
-additional required argument:
-
-``queryset``
-    A ``QuerySet`` of model objects from which the choices for the
-    field will be derived, and which will be used to validate the
-    user's selection.
-
-``ModelChoiceField``
-~~~~~~~~~~~~~~~~~~~~
-
-Allows the selection of a single model object, suitable for
-representing a foreign key.
-
-The ``__unicode__`` method of the model will be called to generate
-string representations of the objects for use in the field's choices;
-to provide customized representations, subclass ``ModelChoiceField``
-and override ``label_from_instance``. This method will receive a model
-object, and should return a string suitable for representing it. For
-example::
-
-    class MyModelChoiceField(ModelChoiceField):
-        def label_from_instance(self, obj):
-            return "My Object #%i" % obj.id
-
-``ModelMultipleChoiceField``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Allows the selection of one or more model objects, suitable for
-representing a many-to-many relation. As with ``ModelChoiceField``,
-you can use ``label_from_instance`` to customize the object
-representations.
-
-Creating custom fields
-----------------------
-
-If the built-in ``Field`` classes don't meet your needs, you can easily create
-custom ``Field`` classes. To do this, just create a subclass of
-``django.forms.Field``. Its only requirements are that it implement a
-``clean()`` method and that its ``__init__()`` method accept the core arguments
-mentioned above (``required``, ``label``, ``initial``, ``widget``,
-``help_text``).
-
-Custom form and field validation
----------------------------------
-
-Form validation happens when the data is cleaned. If you want to customize
-this process, there are various places you can change, each one serving a
-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()``
-directly), but normally they won't be needed.
-
-In general, any cleaning method can raise ``ValidationError`` if there is a
-problem with the data it is processing, passing the relevant error message to
-the ``ValidationError`` constructor. If no ``ValidationError`` is raised, the
-method should return the cleaned (normalized) data as a Python object.
-
-If you detect multiple errors during a cleaning method and wish to signal all
-of them to the form submitter, it is possible to pass a list of errors to the
-``ValidationError`` constructor.
-
-The three types of cleaning methods are:
-
-    * The ``clean()`` method on a Field subclass. This is responsible
-      for cleaning the data in a way that is generic for that type of field.
-      For example, a FloatField will turn the data into a Python ``float`` or
-      raise a ``ValidationError``.
-
-    * The ``clean_<fieldname>()`` method in a form subclass -- where
-      ``<fieldname>`` is replaced with the name of the form field attribute.
-      This method does any cleaning that is specific to that particular
-      attribute, unrelated to the type of field that it is. This method is not
-      passed any parameters. You will need to look up the value of the field
-      in ``self.cleaned_data`` and remember that it will be a Python object
-      at this point, not the original string submitted in the form (it will be
-      in ``cleaned_data`` because the general field ``clean()`` method, above,
-      has already cleaned the data once).
-
-      For example, if you wanted to validate that the contents of a
-      ``CharField`` called ``serialnumber`` was unique,
-      ``clean_serialnumber()`` would be the right place to do this. You don't
-      need a specific field (it's just a ``CharField``), but you want a
-      formfield-specific piece of validation and, possibly,
-      cleaning/normalizing the data.
-
-    * The Form subclass's ``clean()`` method. This method can perform
-      any validation that requires access to multiple fields from the form at
-      once. This is where you might put in things to check that if field ``A``
-      is supplied, field ``B`` must contain a valid e-mail address and the
-      like. The data that this method returns is the final ``cleaned_data``
-      attribute for the form, so don't forget to return the full list of
-      cleaned data if you override this method (by default, ``Form.clean()``
-      just returns ``self.cleaned_data``).
-
-      Note that any errors raised by your ``Form.clean()`` override will not
-      be associated with any field in particular. They go into a special
-      "field" (called ``__all__``), which you can access via the
-      ``non_field_errors()`` method if you need to.
-
-These methods are run in the order given above, one field at a time.  That is,
-for each field in the form (in the order they are declared in the form
-definition), the ``Field.clean()`` method (or its override) is run, then
-``clean_<fieldname>()``. Finally, once those two methods are run for every
-field, the ``Form.clean()`` method, or its override, is executed.
-
-As mentioned above, any of these methods can raise a ``ValidationError``. For
-any field, if the ``Field.clean()`` method raises a ``ValidationError``, any
-field-specific cleaning method is not called. However, the cleaning methods
-for all remaining fields are still executed.
-
-The ``clean()`` method for the ``Form`` class or subclass is always run. If
-that method raises a ``ValidationError``, ``cleaned_data`` will be an empty
-dictionary.
-
-The previous paragraph means that if you are overriding ``Form.clean()``, you
-should iterate through ``self.cleaned_data.items()``, possibly considering the
-``_errors`` dictionary attribute on the form as well. In this way, you will
-already know which fields have passed their individual validation requirements.
-
-A simple example
-~~~~~~~~~~~~~~~~
-
-Here's a simple example of a custom field that validates its input is a string
-containing comma-separated e-mail addresses, with at least one address. We'll
-keep it simple and assume e-mail validation is contained in a function called
-``is_valid_email()``. The full class::
-
-    from django import forms
-
-    class MultiEmailField(forms.Field):
-        def clean(self, value):
-            if not value:
-                raise forms.ValidationError('Enter at least one e-mail address.')
-            emails = value.split(',')
-            for email in emails:
-                if not is_valid_email(email):
-                    raise forms.ValidationError('%s is not a valid e-mail address.' % email)
-            return emails
-
-Let's alter the ongoing ``ContactForm`` example to demonstrate how you'd use
-this in a form. Simply use ``MultiEmailField`` instead of ``forms.EmailField``,
-like so::
-
-    class ContactForm(forms.Form):
-        subject = forms.CharField(max_length=100)
-        message = forms.CharField()
-        senders = MultiEmailField()
-        cc_myself = forms.BooleanField(required=False)
-
-Widgets
-=======
-
-A widget is Django's representation of a HTML input element. The widget
-handles the rendering of the HTML, and the extraction of data from a GET/POST
-dictionary that corresponds to the widget.
-
-Django provides a representation of all the basic HTML widgets, plus some
-commonly used groups of widgets:
-
-    ============================  ===========================================
-    Widget                        HTML Equivalent
-    ============================  ===========================================
-    ``TextInput``                 ``<input type='text' ...``
-    ``PasswordInput``             ``<input type='password' ...``
-    ``HiddenInput``               ``<input type='hidden' ...``
-    ``MultipleHiddenInput``       Multiple ``<input type='hidden' ...``
-                                  instances.
-    ``FileInput``                 ``<input type='file' ...``
-    ``DateTimeInput``             ``<input type='text' ...``
-    ``Textarea``                  ``<textarea>...</textarea>``
-    ``CheckboxInput``             ``<input type='checkbox' ...``
-    ``Select``                    ``<select><option ...``
-    ``NullBooleanSelect``         Select widget with options 'Unknown',
-                                  'Yes' and 'No'
-    ``SelectMultiple``            ``<select multiple='multiple'><option ...``
-    ``RadioSelect``               ``<ul><li><input type='radio' ...``
-    ``CheckboxSelectMultiple``    ``<ul><li><input type='checkbox' ...``
-    ``MultiWidget``               Wrapper around multiple other widgets
-    ``SplitDateTimeWidget``       Wrapper around two ``TextInput`` widgets:
-                                  one for the Date, and one for the Time.
-    ============================  ===========================================
-
-**New in Django development version:** The ``DateTimeInput`` has been added
-since the last release.
-
-Specifying widgets
-------------------
-
-Whenever you specify a field on a form, Django will use a default widget
-that is appropriate to the type of data that is to be displayed. To find
-which widget is used on which field, see the documentation for the
-built-in Field classes.
-
-However, if you want to use a different widget for a field, you can -
-just use the 'widget' argument on the field definition. For example::
-
-    class CommentForm(forms.Form):
-        name = forms.CharField()
-        url = forms.URLField()
-        comment = forms.CharField(widget=forms.Textarea)
-
-This would specify a form with a comment that uses a larger Textarea widget,
-rather than the default TextInput widget.
-
-Customizing widget instances
-----------------------------
-
-When Django renders a widget as HTML, it only renders the bare minimum
-HTML - Django doesn't add a class definition, or any other widget-specific
-attributes. This means that all 'TextInput' widgets will appear the same
-on your Web page.
-
-If you want to make one widget look different to another, you need to
-specify additional attributes for each widget. When you specify a
-widget, you can provide a list of attributes that will be added to the
-rendered HTML for the widget.
-
-For example, take the following simple form::
-
-    class CommentForm(forms.Form):
-        name = forms.CharField()
-        url = forms.URLField()
-        comment = forms.CharField()
-
-This form will include three default TextInput widgets, with default rendering -
-no CSS class, no extra attributes. This means that the input boxes provided for
-each widget will be rendered exactly the same::
-
-    >>> f = CommentForm(auto_id=False)
-    >>> f.as_table()
-    <tr><th>Name:</th><td><input type="text" name="name" /></td></tr>
-    <tr><th>Url:</th><td><input type="text" name="url"/></td></tr>
-    <tr><th>Comment:</th><td><input type="text" name="comment" /></td></tr>
-
-On a real Web page, you probably don't want every widget to look the same. You
-might want a larger input element for the comment, and you might want the
-'name' widget to have some special CSS class. To do this, you specify a
-custom widget for your fields, and specify some attributes to use
-when rendering those widgets::
-
-    class CommentForm(forms.Form):
-        name = forms.CharField(
-                    widget=forms.TextInput(attrs={'class':'special'}))
-        url = forms.URLField()
-        comment = forms.CharField(
-                   widget=forms.TextInput(attrs={'size':'40'}))
-
-Django will then include the extra attributes in the rendered output::
-
-    >>> f = CommentForm(auto_id=False)
-    >>> f.as_table()
-    <tr><th>Name:</th><td><input type="text" name="name" class="special"/></td></tr>
-    <tr><th>Url:</th><td><input type="text" name="url"/></td></tr>
-    <tr><th>Comment:</th><td><input type="text" name="comment" size="40"/></td></tr>
-
-Custom Widgets
---------------
-
-When you start to write a lot of forms, you will probably find that you will
-reuse certain sets of widget attributes over and over again. Rather than
-repeat these attribute definitions every time you need them, Django allows
-you to capture those definitions as a custom widget.
-
-For example, if you find that you are including a lot of comment fields on
-forms, you could capture the idea of a ``TextInput`` with a specific
-default ``size`` attribute as a custom extension to the ``TextInput`` widget::
-
-    class CommentWidget(forms.TextInput):
-        def __init__(self, *args, **kwargs):
-            attrs = kwargs.setdefault('attrs',{})
-            if 'size' not in attrs:
-                attrs['size'] = 40
-            super(CommentWidget, self).__init__(*args, **kwargs)
-
-We allow the ``size`` attribute to be overridden by the user, but, by default,
-this widget will behave as if ``attrs={'size': 40}`` was always passed into the
-constructor.
-
-Then you can use this widget in your forms::
-
-    class CommentForm(forms.Form):
-        name = forms.CharField()
-        url = forms.URLField()
-        comment = forms.CharField(widget=CommentWidget)
-
-You can even customize your custom widget, in the same way as you would
-any other widget. Adding a once-off class to your ``CommentWidget`` is as
-simple as adding an attribute definition::
-
-    class CommentForm(forms.Form):
-        name = forms.CharField(max_length=20)
-        url = forms.URLField()
-        comment = forms.CharField(
-                    widget=CommentWidget(attrs={'class': 'special'}))
-
-Django also makes it easy to specify a custom field type that uses your custom
-widget. For example, you could define a customized field type for comments
-by defining::
-
-    class CommentInput(forms.CharField):
-        widget = CommentWidget
-
-You can then use this field whenever you have a form that requires a comment::
-
-    class CommentForm(forms.Form):
-        name = forms.CharField()
-        url = forms.URLField()
-        comment = CommentInput()
-
-Generating forms for models
-===========================
-
-The prefered way of generating forms that work with models is explained in the
-`ModelForms documentation`_.
-
-.. _ModelForms documentation: ../modelforms/
-
-Media
-=====
-
-Rendering an attractive and easy-to-use web form requires more than just
-HTML - it also requires CSS stylesheets, and if you want to use fancy
-"Web2.0" widgets, you may also need to include some JavaScript on each
-page. The exact combination of CSS and JavaScript that is required for
-any given page will depend upon the widgets that are in use on that page.
-
-This is where Django media definitions come in. Django allows you to
-associate different media files with the forms and widgets that require
-that media. For example, if you want to use a calendar to render DateFields,
-you can define a custom Calendar widget. This widget can then be associated
-with the CSS and JavaScript that is required to render the calendar. When
-the Calendar widget is used on a form, Django is able to identify the CSS and
-JavaScript files that are required, and provide the list of file names
-in a form suitable for easy inclusion on your web page.
-
-.. admonition:: Media and Django Admin
-
-    The Django Admin application defines a number of customized widgets
-    for calendars, filtered selections, and so on. These widgets define
-    media requirements, and the Django Admin uses the custom widgets
-    in place of the Django defaults. The Admin templates will only include
-    those media files that are required to render the widgets on any
-    given page.
-
-    If you like the widgets that the Django Admin application uses,
-    feel free to use them in your own application! They're all stored
-    in ``django.contrib.admin.widgets``.
-
-.. admonition:: Which JavaScript toolkit?
-
-    Many JavaScript toolkits exist, and many of them include widgets (such
-    as calendar widgets) that can be used to enhance your application.
-    Django has deliberately avoided blessing any one JavaScript toolkit.
-    Each toolkit has its own relative strengths and weaknesses - use
-    whichever toolkit suits your requirements. Django is able to integrate
-    with any JavaScript toolkit.
-
-Media as a static definition
-----------------------------
-
-The easiest way to define media is as a static definition. Using this method,
-the media declaration is an inner class. The properties of the inner class
-define the media requirements.
-
-Here's a simple example::
-
-    class CalendarWidget(forms.TextInput):
-        class Media:
-            css = {
-                'all': ('pretty.css',)
-            }
-            js = ('animations.js', 'actions.js')
-
-This code defines a ``CalendarWidget``, which will be based on ``TextInput``.
-Every time the CalendarWidget is used on a form, that form will be directed
-to include the CSS file ``pretty.css``, and the JavaScript files
-``animations.js`` and ``actions.js``.
-
-This static media definition is converted at runtime into a widget property
-named ``media``. The media for a CalendarWidget instance can be retrieved
-through this property::
-
-    >>> w = CalendarWidget()
-    >>> print w.media
-    <link href="http://media.example.com/pretty.css" type="text/css" media="all" rel="stylesheet" />
-    <script type="text/javascript" src="http://media.example.com/animations.js"></script>
-    <script type="text/javascript" src="http://media.example.com/actions.js"></script>
-
-Here's a list of all possible ``Media`` options. There are no required options.
-
-``css``
-~~~~~~~
-
-A dictionary describing the CSS files required for various forms of output
-media.
-
-The values in the dictionary should be a tuple/list of file names. See
-`the section on media paths`_ for details of how to specify paths to media
-files.
-
-.. _the section on media paths: `Paths in media definitions`_
-
-The keys in the dictionary are the output media types. These are the same
-types accepted by CSS files in media declarations: 'all', 'aural', 'braille',
-'embossed', 'handheld', 'print', 'projection', 'screen', 'tty' and 'tv'. If
-you need to have different stylesheets for different media types, provide
-a list of CSS files for each output medium. The following example would
-provide two CSS options -- one for the screen, and one for print::
-
-    class Media:
-        css = {
-            'screen': ('pretty.css',),
-            'print': ('newspaper.css',)
-        }
-
-If a group of CSS files are appropriate for multiple output media types,
-the dictionary key can be a comma separated list of output media types.
-In the following example, TV's and projectors will have the same media
-requirements::
-
-    class Media:
-        css = {
-            'screen': ('pretty.css',),
-            'tv,projector': ('lo_res.css',),
-            'print': ('newspaper.css',)
-        }
-
-If this last CSS definition were to be rendered, it would become the following HTML::
-
-    <link href="http://media.example.com/pretty.css" type="text/css" media="screen" rel="stylesheet" />
-    <link href="http://media.example.com/lo_res.css" type="text/css" media="tv,projector" rel="stylesheet" />
-    <link href="http://media.example.com/newspaper.css" type="text/css" media="print" rel="stylesheet" />
-
-``js``
-~~~~~~
-
-A tuple describing the required JavaScript files. See
-`the section on media paths`_ for details of how to specify paths to media
-files.
-
-``extend``
-~~~~~~~~~~
-
-A boolean defining inheritance behavior for media declarations.
-
-By default, any object using a static media definition will inherit all the
-media associated with the parent widget. This occurs regardless of how the
-parent defines its media requirements. For example, if we were to extend our
-basic Calendar widget from the example above::
-
-    class FancyCalendarWidget(CalendarWidget):
-        class Media:
-            css = {
-                'all': ('fancy.css',)
-            }
-            js = ('whizbang.js',)
-
-    >>> w = FancyCalendarWidget()
-    >>> print w.media
-    <link href="http://media.example.com/pretty.css" type="text/css" media="all" rel="stylesheet" />
-    <link href="http://media.example.com/fancy.css" type="text/css" media="all" rel="stylesheet" />
-    <script type="text/javascript" src="http://media.example.com/animations.js"></script>
-    <script type="text/javascript" src="http://media.example.com/actions.js"></script>
-    <script type="text/javascript" src="http://media.example.com/whizbang.js"></script>
-
-The FancyCalendar widget inherits all the media from it's parent widget. If
-you don't want media to be inherited in this way, add an ``extend=False``
-declaration to the media declaration::
-
-    class FancyCalendar(Calendar):
-        class Media:
-            extend = False
-            css = {
-                'all': ('fancy.css',)
-            }
-            js = ('whizbang.js',)
-
-    >>> w = FancyCalendarWidget()
-    >>> print w.media
-    <link href="http://media.example.com/fancy.css" type="text/css" media="all" rel="stylesheet" />
-    <script type="text/javascript" src="http://media.example.com/whizbang.js"></script>
-
-If you require even more control over media inheritance, define your media
-using a `dynamic property`_. Dynamic properties give you complete control over
-which media files are inherited, and which are not.
-
-.. _dynamic property: `Media as a dynamic property`_
-
-Media as a dynamic property
----------------------------
-
-If you need to perform some more sophisticated manipulation of media
-requirements, you can define the media property directly. This is done
-by defining a model property that returns an instance of ``forms.Media``.
-The constructor for ``forms.Media`` accepts ``css`` and ``js`` keyword
-arguments in the same format as that used in a static media definition.
-
-For example, the static media definition for our Calendar Widget could
-also be defined in a dynamic fashion::
-
-    class CalendarWidget(forms.TextInput):
-        def _media(self):
-            return forms.Media(css={'all': ('pretty.css',)},
-                               js=('animations.js', 'actions.js'))
-        media = property(_media)
-
-See the section on `Media objects`_ for more details on how to construct
-return values for dynamic media properties.
-
-Paths in media definitions
---------------------------
-
-Paths used to specify media can be either relative or absolute. If a path
-starts with '/', 'http://' or 'https://', it will be interpreted as an absolute
-path, and left as-is. All other paths will be prepended with the value of
-``settings.MEDIA_URL``. For example, if the MEDIA_URL for your site was
-``http://media.example.com/``::
-
-    class CalendarWidget(forms.TextInput):
-        class Media:
-            css = {
-                'all': ('/css/pretty.css',),
-            }
-            js = ('animations.js', 'http://othersite.com/actions.js')
-
-    >>> w = CalendarWidget()
-    >>> print w.media
-    <link href="/css/pretty.css" type="text/css" media="all" rel="stylesheet" />
-    <script type="text/javascript" src="http://media.example.com/animations.js"></script>
-    <script type="text/javascript" src="http://othersite.com/actions.js"></script>
-
-Media objects
--------------
-
-When you interrogate the media attribute of a widget or form, the value that
-is returned is a ``forms.Media`` object. As we have already seen, the string
-representation of a Media object is the HTML required to include media
-in the ``<head>`` block of your HTML page.
-
-However, Media objects have some other interesting properties.
-
-Media subsets
-~~~~~~~~~~~~~
-
-If you only want media of a particular type, you can use the subscript operator
-to filter out a medium of interest. For example::
-
-    >>> w = CalendarWidget()
-    >>> print w.media
-    <link href="http://media.example.com/pretty.css" type="text/css" media="all" rel="stylesheet" />
-    <script type="text/javascript" src="http://media.example.com/animations.js"></script>
-    <script type="text/javascript" src="http://media.example.com/actions.js"></script>
-
-    >>> print w.media['css']
-    <link href="http://media.example.com/pretty.css" type="text/css" media="all" rel="stylesheet" />
-
-When you use the subscript operator, the value that is returned is a new
-Media object -- but one that only contains the media of interest.
-
-Combining media objects
-~~~~~~~~~~~~~~~~~~~~~~~
-
-Media objects can also be added together. When two media objects are added,
-the resulting Media object contains the union of the media from both files::
-
-    class CalendarWidget(forms.TextInput):
-        class Media:
-            css = {
-                'all': ('pretty.css',)
-            }
-            js = ('animations.js', 'actions.js')
-
-    class OtherWidget(forms.TextInput):
-        class Media:
-            js = ('whizbang.js',)
-
-    >>> w1 = CalendarWidget()
-    >>> w2 = OtherWidget()
-    >>> print w1.media + w2.media
-    <link href="http://media.example.com/pretty.css" type="text/css" media="all" rel="stylesheet" />
-    <script type="text/javascript" src="http://media.example.com/animations.js"></script>
-    <script type="text/javascript" src="http://media.example.com/actions.js"></script>
-    <script type="text/javascript" src="http://media.example.com/whizbang.js"></script>
-
-Media on Forms
---------------
-
-Widgets aren't the only objects that can have media definitions -- forms
-can also define media. The rules for media definitions on forms are the
-same as the rules for widgets: declarations can be static or dynamic;
-path and inheritance rules for those declarations are exactly the same.
-
-Regardless of whether you define a media declaration, *all* Form objects
-have a media property. The default value for this property is the result
-of adding the media definitions for all widgets that are part of the form::
-
-    class ContactForm(forms.Form):
-        date = DateField(widget=CalendarWidget)
-        name = CharField(max_length=40, widget=OtherWidget)
-
-    >>> f = ContactForm()
-    >>> f.media
-    <link href="http://media.example.com/pretty.css" type="text/css" media="all" rel="stylesheet" />
-    <script type="text/javascript" src="http://media.example.com/animations.js"></script>
-    <script type="text/javascript" src="http://media.example.com/actions.js"></script>
-    <script type="text/javascript" src="http://media.example.com/whizbang.js"></script>
-
-If you want to associate additional media with a form -- for example, CSS for form
-layout -- simply add a media declaration to the form::
-
-    class ContactForm(forms.Form):
-        date = DateField(widget=CalendarWidget)
-        name = CharField(max_length=40, widget=OtherWidget)
-
-        class Media:
-            css = {
-                'all': ('layout.css',)
-            }
-
-    >>> f = ContactForm()
-    >>> f.media
-    <link href="http://media.example.com/pretty.css" type="text/css" media="all" rel="stylesheet" />
-    <link href="http://media.example.com/layout.css" type="text/css" media="all" rel="stylesheet" />
-    <script type="text/javascript" src="http://media.example.com/animations.js"></script>
-    <script type="text/javascript" src="http://media.example.com/actions.js"></script>
-    <script type="text/javascript" src="http://media.example.com/whizbang.js"></script>
-
-Formsets
-========
-
-A formset is a layer of abstraction to working with multiple forms on the same
-page. It can be best compared to a data grid. Let's say you have the following
-form::
-
-    >>> from django import forms
-    >>> class ArticleForm(forms.Form):
-    ...     title = forms.CharField()
-    ...     pub_date = forms.DateField()
-
-You might want to allow the user to create several articles at once. To create
-a formset out of an ``ArticleForm`` you would do::
-
-    >>> from django.forms.formsets import formset_factory
-    >>> ArticleFormSet = formset_factory(ArticleForm)
-
-You now have created a formset named ``ArticleFormSet``. The formset gives you
-the ability to iterate over the forms in the formset and display them as you
-would with a regular form::
-
-    >>> formset = ArticleFormSet()
-    >>> for form in formset.forms:
-    ...     print form.as_table()
-    <tr><th><label for="id_form-0-title">Title:</label></th><td><input type="text" name="form-0-title" id="id_form-0-title" /></td></tr>
-    <tr><th><label for="id_form-0-pub_date">Pub date:</label></th><td><input type="text" name="form-0-pub_date" id="id_form-0-pub_date" /></td></tr>
-
-As you can see it only displayed one form. This is because by default the
-``formset_factory`` defines one extra form. This can be controlled with the
-``extra`` parameter::
-
-    >>> ArticleFormSet = formset_factory(ArticleForm, extra=2)
-
-Using initial data with a formset
----------------------------------
-
-Initial data is what drives the main usability of a formset. As shown above
-you can define the number of extra forms. What this means is that you are
-telling the formset how many additional forms to show in addition to the
-number of forms it generates from the initial data. Lets take a look at an
-example::
-
-    >>> ArticleFormSet = formset_factory(ArticleForm, extra=2)
-    >>> formset = ArticleFormSet(initial=[
-    ...     {'title': u'Django is now open source',
-    ...      'pub_date': datetime.date.today()},
-    ... ])
-
-    >>> for form in formset.forms:
-    ...     print form.as_table()
-    <tr><th><label for="id_form-0-title">Title:</label></th><td><input type="text" name="form-0-title" value="Django is now open source" id="id_form-0-title" /></td></tr>
-    <tr><th><label for="id_form-0-pub_date">Pub date:</label></th><td><input type="text" name="form-0-pub_date" value="2008-05-12" id="id_form-0-pub_date" /></td></tr>
-    <tr><th><label for="id_form-1-title">Title:</label></th><td><input type="text" name="form-1-title" id="id_form-1-title" /></td></tr>
-    <tr><th><label for="id_form-1-pub_date">Pub date:</label></th><td><input type="text" name="form-1-pub_date" id="id_form-1-pub_date" /></td></tr>
-    <tr><th><label for="id_form-2-title">Title:</label></th><td><input type="text" name="form-2-title" id="id_form-2-title" /></td></tr>
-    <tr><th><label for="id_form-2-pub_date">Pub date:</label></th><td><input type="text" name="form-2-pub_date" id="id_form-2-pub_date" /></td></tr>
-
-There are now a total of three forms showing above. One for the initial data
-that was passed in and two extra forms. Also note that we are passing in a
-list of dictionaries as the initial data.
-
-Limiting the maximum number of forms
-------------------------------------
-
-The ``max_num`` parameter to ``formset_factory`` gives you the ability to
-force the maximum number of forms the formset will display::
-
-    >>> ArticleFormSet = formset_factory(ArticleForm, extra=2, max_num=1)
-    >>> formset = ArticleFormset()
-    >>> for form in formset.forms:
-    ...     print form.as_table()
-    <tr><th><label for="id_form-0-title">Title:</label></th><td><input type="text" name="form-0-title" id="id_form-0-title" /></td></tr>
-    <tr><th><label for="id_form-0-pub_date">Pub date:</label></th><td><input type="text" name="form-0-pub_date" id="id_form-0-pub_date" /></td></tr>
-
-The default value of ``max_num`` is ``0`` which is the same as saying put no
-limit on the number forms displayed.
-
-Formset validation
-------------------
-
-Validation with a formset is about identical to a regular ``Form``. There is
-an ``is_valid`` method on the formset to provide a convenient way to validate
-each form in the formset::
-
-    >>> ArticleFormSet = formset_factory(ArticleForm)
-    >>> formset = ArticleFormSet({})
-    >>> formset.is_valid()
-    True
-
-We passed in no data to the formset which is resulting in a valid form. The
-formset is smart enough to ignore extra forms that were not changed. If we
-attempt to provide an article, but fail to do so::
-
-    >>> data = {
-    ...     'form-TOTAL_FORMS': u'1',
-    ...     'form-INITIAL_FORMS': u'1',
-    ...     'form-0-title': u'Test',
-    ...     'form-0-pub_date': u'',
-    ... }
-    >>> formset = ArticleFormSet(data)
-    >>> formset.is_valid()
-    False
-    >>> formset.errors
-    [{'pub_date': [u'This field is required.']}]
-
-As we can see the formset properly performed validation and gave us the
-expected errors.
-
-Understanding the ManagementForm
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-You may have noticed the additional data that was required in the formset's
-data above. This data is coming from the ``ManagementForm``. This form is
-dealt with internally to the formset. If you don't use it, it will result in
-an exception::
-
-    >>> data = {
-    ...     'form-0-title': u'Test',
-    ...     'form-0-pub_date': u'',
-    ... }
-    >>> formset = ArticleFormSet(data)
-    Traceback (most recent call last):
-    ...
-    django.forms.util.ValidationError: [u'ManagementForm data is missing or has been tampered with']
-
-It is used to keep track of how many form instances are being displayed. If
-you are adding new forms via JavaScript, you should increment the count fields
-in this form as well.
-
-Custom formset validation
-~~~~~~~~~~~~~~~~~~~~~~~~~
-
-A formset has a ``clean`` method similar to the one on a ``Form`` class. This
-is where you define your own validation that deals at the formset level::
-
-    >>> from django.forms.formsets import BaseFormSet
-
-    >>> class BaseArticleFormSet(BaseFormSet):
-    ...     def clean(self):
-    ...         raise forms.ValidationError, u'An error occured.'
-
-    >>> ArticleFormSet = formset_factory(ArticleForm, formset=BaseArticleFormSet)
-    >>> formset = ArticleFormSet({})
-    >>> formset.is_valid()
-    False
-    >>> formset.non_form_errors()
-    [u'An error occured.']
-
-The formset ``clean`` method is called after all the ``Form.clean`` methods
-have been called. The errors will be found using the ``non_form_errors()``
-method on the formset.
-
-Dealing with ordering and deletion of forms
--------------------------------------------
-
-Common use cases with a formset is dealing with ordering and deletion of the
-form instances. This has been dealt with for you. The ``formset_factory``
-provides two optional parameters ``can_order`` and ``can_delete`` that will do
-the extra work of adding the extra fields and providing simpler ways of
-getting to that data.
-
-``can_order``
-~~~~~~~~~~~~~
-
-Default: ``False``
-
-Lets create a formset with the ability to order::
-
-    >>> ArticleFormSet = formset_factory(ArticleForm, can_order=True)
-    >>> formset = ArticleFormSet(initial=[
-    ...     {'title': u'Article #1', 'pub_date': datetime.date(2008, 5, 10)},
-    ...     {'title': u'Article #2', 'pub_date': datetime.date(2008, 5, 11)},
-    ... ])
-    >>> for form in formset.forms:
-    ...     print form.as_table()
-    <tr><th><label for="id_form-0-title">Title:</label></th><td><input type="text" name="form-0-title" value="Article #1" id="id_form-0-title" /></td></tr>
-    <tr><th><label for="id_form-0-pub_date">Pub date:</label></th><td><input type="text" name="form-0-pub_date" value="2008-05-10" id="id_form-0-pub_date" /></td></tr>
-    <tr><th><label for="id_form-0-ORDER">Order:</label></th><td><input type="text" name="form-0-ORDER" value="1" id="id_form-0-ORDER" /></td></tr>
-    <tr><th><label for="id_form-1-title">Title:</label></th><td><input type="text" name="form-1-title" value="Article #2" id="id_form-1-title" /></td></tr>
-    <tr><th><label for="id_form-1-pub_date">Pub date:</label></th><td><input type="text" name="form-1-pub_date" value="2008-05-11" id="id_form-1-pub_date" /></td></tr>
-    <tr><th><label for="id_form-1-ORDER">Order:</label></th><td><input type="text" name="form-1-ORDER" value="2" id="id_form-1-ORDER" /></td></tr>
-    <tr><th><label for="id_form-2-title">Title:</label></th><td><input type="text" name="form-2-title" id="id_form-2-title" /></td></tr>
-    <tr><th><label for="id_form-2-pub_date">Pub date:</label></th><td><input type="text" name="form-2-pub_date" id="id_form-2-pub_date" /></td></tr>
-    <tr><th><label for="id_form-2-ORDER">Order:</label></th><td><input type="text" name="form-2-ORDER" id="id_form-2-ORDER" /></td></tr>
-
-This adds an additional field to each form. This new field is named ``ORDER``
-and is an ``forms.IntegerField``. For the forms that came from the initial
-data it automatically assigned them a numeric value. Lets look at what will
-happen when the user changes these values::
-
-    >>> data = {
-    ...     'form-TOTAL_FORMS': u'3',
-    ...     'form-INITIAL_FORMS': u'2',
-    ...     'form-0-title': u'Article #1',
-    ...     'form-0-pub_date': u'2008-05-10',
-    ...     'form-0-ORDER': u'2',
-    ...     'form-1-title': u'Article #2',
-    ...     'form-1-pub_date': u'2008-05-11',
-    ...     'form-1-ORDER': u'1',
-    ...     'form-2-title': u'Article #3',
-    ...     'form-2-pub_date': u'2008-05-01',
-    ...     'form-2-ORDER': u'0',
-    ... }
-
-    >>> formset = ArticleFormSet(data, initial=[
-    ...     {'title': u'Article #1', 'pub_date': datetime.date(2008, 5, 10)},
-    ...     {'title': u'Article #2', 'pub_date': datetime.date(2008, 5, 11)},
-    ... ])
-    >>> formset.is_valid()
-    True
-    >>> for form in formset.ordered_forms:
-    ...     print form.cleaned_data
-    {'pub_date': datetime.date(2008, 5, 1), 'ORDER': 0, 'title': u'Article #3'}
-    {'pub_date': datetime.date(2008, 5, 11), 'ORDER': 1, 'title': u'Article #2'}
-    {'pub_date': datetime.date(2008, 5, 10), 'ORDER': 2, 'title': u'Article #1'}
-
-``can_delete``
-~~~~~~~~~~~~~~
-
-Default: ``False``
-
-Lets create a formset with the ability to delete::
-
-    >>> ArticleFormSet = formset_factory(ArticleForm, can_delete=True)
-    >>> formset = ArticleFormSet(initial=[
-    ...     {'title': u'Article #1', 'pub_date': datetime.date(2008, 5, 10)},
-    ...     {'title': u'Article #2', 'pub_date': datetime.date(2008, 5, 11)},
-    ... ])
-    >>> for form in formset.forms:
-    ....    print form.as_table()
-    <input type="hidden" name="form-TOTAL_FORMS" value="3" id="id_form-TOTAL_FORMS" /><input type="hidden" name="form-INITIAL_FORMS" value="2" id="id_form-INITIAL_FORMS" />
-    <tr><th><label for="id_form-0-title">Title:</label></th><td><input type="text" name="form-0-title" value="Article #1" id="id_form-0-title" /></td></tr>
-    <tr><th><label for="id_form-0-pub_date">Pub date:</label></th><td><input type="text" name="form-0-pub_date" value="2008-05-10" id="id_form-0-pub_date" /></td></tr>
-    <tr><th><label for="id_form-0-DELETE">Delete:</label></th><td><input type="checkbox" name="form-0-DELETE" id="id_form-0-DELETE" /></td></tr>
-    <tr><th><label for="id_form-1-title">Title:</label></th><td><input type="text" name="form-1-title" value="Article #2" id="id_form-1-title" /></td></tr>
-    <tr><th><label for="id_form-1-pub_date">Pub date:</label></th><td><input type="text" name="form-1-pub_date" value="2008-05-11" id="id_form-1-pub_date" /></td></tr>
-    <tr><th><label for="id_form-1-DELETE">Delete:</label></th><td><input type="checkbox" name="form-1-DELETE" id="id_form-1-DELETE" /></td></tr>
-    <tr><th><label for="id_form-2-title">Title:</label></th><td><input type="text" name="form-2-title" id="id_form-2-title" /></td></tr>
-    <tr><th><label for="id_form-2-pub_date">Pub date:</label></th><td><input type="text" name="form-2-pub_date" id="id_form-2-pub_date" /></td></tr>
-    <tr><th><label for="id_form-2-DELETE">Delete:</label></th><td><input type="checkbox" name="form-2-DELETE" id="id_form-2-DELETE" /></td></tr>
-
-Similar to ``can_order`` this adds a new field to each form named ``DELETE``
-and is a ``forms.BooleanField``. When data comes through marking any of the
-delete fields you can access them with ``deleted_forms``::
-
-    >>> data = {
-    ...     'form-TOTAL_FORMS': u'3',
-    ...     'form-INITIAL_FORMS': u'2',
-    ...     'form-0-title': u'Article #1',
-    ...     'form-0-pub_date': u'2008-05-10',
-    ...     'form-0-DELETE': u'on',
-    ...     'form-1-title': u'Article #2',
-    ...     'form-1-pub_date': u'2008-05-11',
-    ...     'form-1-DELETE': u'',
-    ...     'form-2-title': u'',
-    ...     'form-2-pub_date': u'',
-    ...     'form-2-DELETE': u'',
-    ... }
-
-    >>> formset = ArticleFormSet(data, initial=[
-    ...     {'title': u'Article #1', 'pub_date': datetime.date(2008, 5, 10)},
-    ...     {'title': u'Article #2', 'pub_date': datetime.date(2008, 5, 11)},
-    ... ])
-    >>> [form.cleaned_data for form in formset.deleted_forms]
-    [{'DELETE': True, 'pub_date': datetime.date(2008, 5, 10), 'title': u'Article #1'}]
-
-Adding additional fields to a formset
--------------------------------------
-
-If you need to add additional fields to the formset this can be easily
-accomplished. The formset base class provides an ``add_fields`` method. You
-can simply override this method to add your own fields or even redefine the
-default fields/attributes of the order and deletion fields::
-
-    >>> class BaseArticleFormSet(BaseFormSet):
-    ...     def add_fields(self, form, index):
-    ...         super(BaseArticleFormSet, self).add_fields(form, index)
-    ...         form.fields["my_field"] = forms.CharField()
-
-    >>> ArticleFormSet = formset_factory(ArticleForm, formset=BaseArticleFormSet)
-    >>> formset = ArticleFormSet()
-    >>> for form in formset.forms:
-    ...     print form.as_table()
-    <tr><th><label for="id_form-0-title">Title:</label></th><td><input type="text" name="form-0-title" id="id_form-0-title" /></td></tr>
-    <tr><th><label for="id_form-0-pub_date">Pub date:</label></th><td><input type="text" name="form-0-pub_date" id="id_form-0-pub_date" /></td></tr>
-    <tr><th><label for="id_form-0-my_field">My field:</label></th><td><input type="text" name="form-0-my_field" id="id_form-0-my_field" /></td></tr>
-
-Using a formset in views and templates
---------------------------------------
-
-Using a formset inside a view is as easy as using a regular ``Form`` class.
-The only thing you will want to be aware of is making sure to use the
-management form inside the template. Lets look at a sample view::
-
-    def manage_articles(request):
-        ArticleFormSet = formset_factory(ArticleForm)
-        if request.method == 'POST':
-            formset = ArticleFormSet(request.POST, request.FILES)
-            if formset.is_valid():
-                # do something with the formset.cleaned_data
-        else:
-            formset = ArticleFormSet()
-        return render_to_response('manage_articles.html', {'formset': formset})
-
-The ``manage_articles.html`` template might look like this::
-
-    <form method="POST" action="">
-        {{ formset.management_form }}
-        <table>
-            {% for form in formset.forms %}
-            {{ form }}
-            {% endfor %}
-        </table>
-    </form>
-
-However the above can be slightly shortcutted and let the formset itself deal
-with the management form::
-
-    <form method="POST" action="">
-        <table>
-            {{ formset }}
-        </table>
-    </form>
-
-The above ends up calling the ``as_table`` method on the formset class.

+ 0 - 1273
docs/generic_views.txt

@@ -1,1273 +0,0 @@
-=============
-Generic views
-=============
-
-Writing Web applications can be monotonous, because we repeat certain patterns
-again and again. In Django, the most common of these patterns have been
-abstracted into "generic views" that let you quickly provide common views of
-an object without actually needing to write any Python code.
-
-Django's generic views contain the following:
-
-    * A set of views for doing list/detail interfaces (for example,
-      Django's `documentation index`_ and `detail pages`_).
-
-    * A set of views for year/month/day archive pages and associated
-      detail and "latest" pages (for example, the Django weblog's year_,
-      month_, day_, detail_, and latest_ pages).
-
-    * A set of views for creating, editing, and deleting objects.
-
-.. _`documentation index`: http://www.djangoproject.com/documentation/
-.. _`detail pages`: http://www.djangoproject.com/documentation/faq/
-.. _year: http://www.djangoproject.com/weblog/2005/
-.. _month: http://www.djangoproject.com/weblog/2005/jul/
-.. _day: http://www.djangoproject.com/weblog/2005/jul/20/
-.. _detail: http://www.djangoproject.com/weblog/2005/jul/20/autoreload/
-.. _latest: http://www.djangoproject.com/weblog/
-
-All of these views are used by creating configuration dictionaries in
-your URLconf files and passing those dictionaries as the third member of the
-URLconf tuple for a given pattern. For example, here's the URLconf for the
-simple weblog app that drives the blog on djangoproject.com::
-
-    from django.conf.urls.defaults import *
-    from django_website.apps.blog.models import Entry
-
-    info_dict = {
-        'queryset': Entry.objects.all(),
-        'date_field': 'pub_date',
-    }
-
-    urlpatterns = patterns('django.views.generic.date_based',
-       (r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/(?P<day>\w{1,2})/(?P<slug>[-\w]+)/$', 'object_detail', info_dict),
-       (r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/(?P<day>\w{1,2})/$',               'archive_day',   info_dict),
-       (r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/$',                                'archive_month', info_dict),
-       (r'^(?P<year>\d{4})/$',                                                    'archive_year',  info_dict),
-       (r'^$',                                                                    'archive_index', info_dict),
-    )
-
-As you can see, this URLconf defines a few options in ``info_dict``.
-``'queryset'`` gives the generic view a ``QuerySet`` of objects to use (in this
-case, all of the ``Entry`` objects) and tells the generic view which model is
-being used.
-
-Documentation of each generic view follows, along with a list of all keyword
-arguments that a generic view expects. Remember that as in the example above,
-arguments may either come from the URL pattern (as ``month``, ``day``,
-``year``, etc. do above) or from the additional-information dictionary (as for
-``queryset``, ``date_field``, etc.).
-
-Most generic views require the ``queryset`` key, which is a ``QuerySet``
-instance; see the `database API docs`_ for more information about ``Queryset``
-objects.
-
-Most views also take an optional ``extra_context`` dictionary that you can use
-to pass any auxiliary information you wish to the view. The values in the
-``extra_context`` dictionary can be either functions (or other callables) or
-other objects. Functions are evaluated just before they are passed to the
-template. However, note that QuerySets retrieve and cache their data when they
-are first evaluated, so if you want to pass in a QuerySet via
-``extra_context`` that is always fresh you need to wrap it in a function or
-lambda that returns the QuerySet.
-
-.. _database API docs: ../db-api/
-
-"Simple" generic views
-======================
-
-The ``django.views.generic.simple`` module contains simple views to handle a
-couple of common cases: rendering a template when no view logic is needed,
-and issuing a redirect.
-
-``django.views.generic.simple.direct_to_template``
---------------------------------------------------
-
-Description
-~~~~~~~~~~~
-
-Renders a given template, passing it a ``{{ params }}`` template variable,
-which is a dictionary of the parameters captured in the URL.
-
-Required arguments
-~~~~~~~~~~~~~~~~~~
-
-``template``
-    The full name of a template to use.
-
-Optional arguments
-~~~~~~~~~~~~~~~~~~
-
-``extra_context``
-    A dictionary of values to add to the template context. By default, this is
-    an empty dictionary. If a value in the dictionary is callable, the generic
-    view will call it just before rendering the template.
-
-``mimetype``
-    The MIME type to use for the resulting document. Defaults to the value of
-    the ``DEFAULT_CONTENT_TYPE`` setting.
-
-**Example:**
-
-Given the following URL patterns::
-
-    urlpatterns = patterns('django.views.generic.simple',
-        (r'^foo/$',             'direct_to_template', {'template': 'foo_index.html'}),
-        (r'^foo/(?P<id>\d+)/$', 'direct_to_template', {'template': 'foo_detail.html'}),
-    )
-
-... a request to ``/foo/`` would render the template ``foo_index.html``, and a
-request to ``/foo/15/`` would render the ``foo_detail.html`` with a context
-variable ``{{ params.id }}`` that is set to ``15``.
-
-``django.views.generic.simple.redirect_to``
--------------------------------------------
-
-Description
-~~~~~~~~~~~
-
-Redirects to a given URL.
-
-The given URL may contain dictionary-style string formatting, which will be
-interpolated against the parameters captured in the URL.
-
-If the given URL is ``None``, Django will return an ``HttpResponseGone`` (410).
-
-Required arguments
-~~~~~~~~~~~~~~~~~~
-
-``url``
-    The URL to redirect to, as a string. Or ``None`` to raise a 410 (Gone)
-    HTTP error.
-
-**Example:**
-
-This example redirects from ``/foo/<id>/`` to ``/bar/<id>/``::
-
-    urlpatterns = patterns('django.views.generic.simple',
-        ('^foo/(?P<id>\d+)/$', 'redirect_to', {'url': '/bar/%(id)s/'}),
-    )
-
-This example returns a 410 HTTP error for requests to ``/bar/``::
-
-    urlpatterns = patterns('django.views.generic.simple',
-        ('^bar/$', 'redirect_to', {'url': None}),
-    )
-
-Date-based generic views
-========================
-
-Date-based generic views (in the module ``django.views.generic.date_based``)
-are views for displaying drilldown pages for date-based data.
-
-``django.views.generic.date_based.archive_index``
--------------------------------------------------
-
-Description
-~~~~~~~~~~~
-
-A top-level index page showing the "latest" objects, by date. Objects with
-a date in the *future* are not included unless you set ``allow_future`` to
-``True``.
-
-Required arguments
-~~~~~~~~~~~~~~~~~~
-
-``queryset``
-    A ``QuerySet`` of objects for which the archive serves.
-
-``date_field``
-    The name of the ``DateField`` or ``DateTimeField`` in the ``QuerySet``'s
-    model that the date-based archive should use to determine the objects on
-    the page.
-
-Optional arguments
-~~~~~~~~~~~~~~~~~~
-
-``num_latest``
-    The number of latest objects to send to the template context. By default,
-    it's 15.
-
-``template_name``
-    The full name of a template to use in rendering the page. This lets you
-    override the default template name (see below).
-
-``template_loader``
-    The template loader to use when loading the template. By default, it's
-    ``django.template.loader``.
-
-``extra_context``
-    A dictionary of values to add to the template context. By default, this is
-    an empty dictionary. If a value in the dictionary is callable, the generic
-    view will call it just before rendering the template.
-
-``allow_empty``
-    A boolean specifying whether to display the page if no objects are
-    available. If this is ``False`` and no objects are available, the view will
-    raise a 404 instead of displaying an empty page. By default, this is
-    ``True``.
-
-``context_processors``
-    A list of template-context processors to apply to the view's template. See
-    the `RequestContext docs`_.
-
-``mimetype``
-    The MIME type to use for the resulting document. Defaults to the value of
-    the ``DEFAULT_CONTENT_TYPE`` setting.
-
-``allow_future``
-    A boolean specifying whether to include "future" objects on this page,
-    where "future" means objects in which the field specified in ``date_field``
-    is greater than the current date/time. By default, this is ``False``.
-
-``template_object_name`` (**New in Django development version**)
-    Designates the name of the template variable to use in the template
-    context. By default, this is ``'latest'``.
-
-Template name
-~~~~~~~~~~~~~
-
-If ``template_name`` isn't specified, this view will use the template
-``<app_label>/<model_name>_archive.html`` by default, where:
-
-    * ``<model_name>`` is your model's name in all lowercase. For a model
-      ``StaffMember``, that'd be ``staffmember``.
-
-    * ``<app_label>`` is the right-most part of the full Python path to
-      your model's app. For example, if your model lives in
-      ``apps/blog/models.py``, that'd be ``blog``.
-
-Template context
-~~~~~~~~~~~~~~~~
-
-In addition to ``extra_context``, the template's context will be:
-
-``date_list``
-    A list of ``datetime.date`` objects representing all years that have
-    objects available according to ``queryset``. These are ordered in reverse.
-    This is equivalent to ``queryset.dates(date_field, 'year')[::-1]``.
-
-``latest``
-    The ``num_latest`` objects in the system, ordered descending by
-    ``date_field``. For example, if ``num_latest`` is ``10``, then ``latest``
-    will be a list of the latest 10 objects in ``queryset``.
-
-    **New in Django development version:** This variable's name depends on the
-    ``template_object_name`` parameter, which is ``'latest'`` by default.
-    If ``template_object_name`` is ``'foo'``, this variable's name will be
-    ``foo``.
-
-.. _RequestContext docs: ../templates_python/#subclassing-context-requestcontext
-
-``django.views.generic.date_based.archive_year``
-------------------------------------------------
-
-Description
-~~~~~~~~~~~
-
-A yearly archive page showing all available months in a given year. Objects
-with a date in the *future* are not displayed unless you set ``allow_future``
-to ``True``.
-
-Required arguments
-~~~~~~~~~~~~~~~~~~
-
-``year``
-    The four-digit year for which the archive serves.
-
-``queryset``
-    A ``QuerySet`` of objects for which the archive serves.
-
-``date_field``
-    The name of the ``DateField`` or ``DateTimeField`` in the ``QuerySet``'s
-    model that the date-based archive should use to determine the objects on
-    the page.
-
-Optional arguments
-~~~~~~~~~~~~~~~~~~
-
-``template_name``
-    The full name of a template to use in rendering the page. This lets you
-    override the default template name (see below).
-
-``template_loader``
-    The template loader to use when loading the template. By default, it's
-    ``django.template.loader``.
-
-``extra_context``
-    A dictionary of values to add to the template context. By default, this is
-    an empty dictionary. If a value in the dictionary is callable, the generic
-    view will call it just before rendering the template.
-
-``allow_empty``
-    A boolean specifying whether to display the page if no objects are
-    available. If this is ``False`` and no objects are available, the view will
-    raise a 404 instead of displaying an empty page. By default, this is
-    ``False``.
-
-``context_processors``
-    A list of template-context processors to apply to the view's template. See
-    the `RequestContext docs`_.
-
-``template_object_name``
-    Designates the name of the template variable to use in the template
-    context. By default, this is ``'object'``. The view will append ``'_list'``
-    to the value of this parameter in determining the variable's name.
-
-``make_object_list``
-    A boolean specifying whether to retrieve the full  list of objects for this
-    year and pass those to the template. If ``True``, this list of objects will
-    be made available to the template as ``object_list``. (The name
-    ``object_list`` may be different; see the docs for ``object_list`` in the
-    "Template context" section below.) By default, this is ``False``.
-
-``mimetype``
-    The MIME type to use for the resulting document. Defaults to the value of
-    the ``DEFAULT_CONTENT_TYPE`` setting.
-
-``allow_future``
-    A boolean specifying whether to include "future" objects on this page,
-    where "future" means objects in which the field specified in ``date_field``
-    is greater than the current date/time. By default, this is ``False``.
-
-Template name
-~~~~~~~~~~~~~
-
-If ``template_name`` isn't specified, this view will use the template
-``<app_label>/<model_name>_archive_year.html`` by default.
-
-Template context
-~~~~~~~~~~~~~~~~
-
-In addition to ``extra_context``, the template's context will be:
-
-``date_list``
-    A list of ``datetime.date`` objects representing all months that have
-    objects available in the given year, according to ``queryset``, in
-    ascending order.
-
-``year``
-    The given year, as a four-character string.
-
-``object_list``
-    If the ``make_object_list`` parameter is ``True``, this will be set to a
-    list of objects available for the given year, ordered by the date field.
-    This variable's name depends on the ``template_object_name`` parameter,
-    which is ``'object'`` by default. If ``template_object_name`` is ``'foo'``,
-    this variable's name will be ``foo_list``.
-
-    If ``make_object_list`` is ``False``, ``object_list`` will be passed to the
-    template as an empty list.
-
-``django.views.generic.date_based.archive_month``
--------------------------------------------------
-
-Description
-~~~~~~~~~~~
-
-A monthly archive page showing all objects in a given month. Objects with a
-date in the *future* are not displayed unless you set ``allow_future`` to
-``True``.
-
-Required arguments
-~~~~~~~~~~~~~~~~~~
-
-``year``
-    The four-digit year for which the archive serves (a string).
-
-``month``
-    The month for which the archive serves, formatted according to the
-    ``month_format`` argument.
-
-``queryset``
-    A ``QuerySet`` of objects for which the archive serves.
-
-``date_field``
-    The name of the ``DateField`` or ``DateTimeField`` in the ``QuerySet``'s
-    model that the date-based archive should use to determine the objects on
-    the page.
-
-Optional arguments
-~~~~~~~~~~~~~~~~~~
-
-``month_format``
-    A format string that regulates what format the ``month`` parameter uses.
-    This should be in the syntax accepted by Python's ``time.strftime``. (See
-    the `strftime docs`_.) It's set to ``"%b"`` by default, which is a three-
-    letter month abbreviation. To change it to use numbers, use ``"%m"``.
-
-``template_name``
-    The full name of a template to use in rendering the page. This lets you
-    override the default template name (see below).
-
-``template_loader``
-    The template loader to use when loading the template. By default, it's
-    ``django.template.loader``.
-
-``extra_context``
-    A dictionary of values to add to the template context. By default, this is
-    an empty dictionary. If a value in the dictionary is callable, the generic
-    view will call it just before rendering the template.
-
-``allow_empty``
-    A boolean specifying whether to display the page if no objects are
-    available. If this is ``False`` and no objects are available, the view will
-    raise a 404 instead of displaying an empty page. By default, this is
-    ``False``.
-
-``context_processors``
-    A list of template-context processors to apply to the view's template. See
-    the `RequestContext docs`_.
-
-``template_object_name``
-    Designates the name of the template variable to use in the template
-    context. By default, this is ``'object'``. The view will append ``'_list'``
-    to the value of this parameter in determining the variable's name.
-
-``mimetype``
-    The MIME type to use for the resulting document. Defaults to the value of
-    the ``DEFAULT_CONTENT_TYPE`` setting.
-
-``allow_future``
-    A boolean specifying whether to include "future" objects on this page,
-    where "future" means objects in which the field specified in ``date_field``
-    is greater than the current date/time. By default, this is ``False``.
-
-Template name
-~~~~~~~~~~~~~
-
-If ``template_name`` isn't specified, this view will use the template
-``<app_label>/<model_name>_archive_month.html`` by default.
-
-Template context
-~~~~~~~~~~~~~~~~
-
-In addition to ``extra_context``, the template's context will be:
-
-``month``
-    A ``datetime.date`` object representing the given month.
-
-``next_month``
-    A ``datetime.date`` object representing the first day of the next month. If
-     the next month is in the future, this will be ``None``.
-
-``previous_month``
-    A ``datetime.date`` object representing the first day of the previous
-    month. Unlike ``next_month``, this will never be ``None``.
-
-``object_list``
-    A list of objects available for the given month. This variable's name
-    depends on the ``template_object_name`` parameter, which is ``'object'`` by
-    default. If ``template_object_name`` is ``'foo'``, this variable's name
-    will be ``foo_list``.
-
-.. _strftime docs: http://www.python.org/doc/current/lib/module-time.html#l2h-1941
-
-``django.views.generic.date_based.archive_week``
-------------------------------------------------
-
-Description
-~~~~~~~~~~~
-
-A weekly archive page showing all objects in a given week. Objects with a date
-in the *future* are not displayed unless you set ``allow_future`` to ``True``.
-
-Required arguments
-~~~~~~~~~~~~~~~~~~
-
-``year``
-    The four-digit year for which the archive serves (a string).
-
-``week``
-    The week of the year for which the archive serves (a string). Weeks start
-    with Sunday.
-
-``queryset``
-    A ``QuerySet`` of objects for which the archive serves.
-
-``date_field``
-    The name of the ``DateField`` or ``DateTimeField`` in the ``QuerySet``'s
-    model that the date-based archive should use to determine the objects on
-    the page.
-
-Optional arguments
-~~~~~~~~~~~~~~~~~~
-
-``template_name``
-    The full name of a template to use in rendering the page. This lets you
-    override the default template name (see below).
-
-``template_loader``
-    The template loader to use when loading the template. By default, it's
-    ``django.template.loader``.
-
-``extra_context``
-    A dictionary of values to add to the template context. By default, this is
-    an empty dictionary. If a value in the dictionary is callable, the generic
-    view will call it just before rendering the template.
-
-``allow_empty``
-    A boolean specifying whether to display the page if no objects are
-    available. If this is ``False`` and no objects are available, the view will
-    raise a 404 instead of displaying an empty page. By default, this is
-    ``True``.
-
-``context_processors``
-    A list of template-context processors to apply to the view's template. See
-    the `RequestContext docs`_.
-
-``template_object_name``
-    Designates the name of the template variable to use in the template
-    context. By default, this is ``'object'``. The view will append ``'_list'``
-    to the value of this parameter in determining the variable's name.
-
-``mimetype``
-    The MIME type to use for the resulting document. Defaults to the value of
-    the ``DEFAULT_CONTENT_TYPE`` setting.
-
-``allow_future``
-    A boolean specifying whether to include "future" objects on this page,
-    where "future" means objects in which the field specified in ``date_field``
-    is greater than the current date/time. By default, this is ``False``.
-
-Template name
-~~~~~~~~~~~~~
-
-If ``template_name`` isn't specified, this view will use the template
-``<app_label>/<model_name>_archive_week.html`` by default.
-
-Template context
-~~~~~~~~~~~~~~~~
-
-In addition to ``extra_context``, the template's context will be:
-
-``week``
-    A ``datetime.date`` object representing the first day of the given week.
-
-``object_list``
-    A list of objects available for the given week. This variable's name
-    depends on the ``template_object_name`` parameter, which is ``'object'`` by
-    default. If ``template_object_name`` is ``'foo'``, this variable's name
-    will be ``foo_list``.
-
-``django.views.generic.date_based.archive_day``
------------------------------------------------
-
-Description
-~~~~~~~~~~~
-
-A day archive page showing all objects in a given day. Days in the future throw
-a 404 error, regardless of whether any objects exist for future days, unless
-you set ``allow_future`` to ``True``.
-
-Required arguments
-~~~~~~~~~~~~~~~~~~
-
-``year``
-    The four-digit year for which the archive serves (a string).
-
-``month``
-    The month for which the archive serves, formatted according to the
-    ``month_format`` argument.
-
-``day``
-    The day for which the archive serves, formatted according to the
-    ``day_format`` argument.
-
-``queryset``
-    A ``QuerySet`` of objects for which the archive serves.
-
-``date_field``
-    The name of the ``DateField`` or ``DateTimeField`` in the ``QuerySet``'s
-    model that the date-based archive should use to determine the objects on
-    the page.
-
-Optional arguments
-~~~~~~~~~~~~~~~~~~
-
-``month_format``
-    A format string that regulates what format the ``month`` parameter uses.
-    This should be in the syntax accepted by Python's ``time.strftime``. (See
-    the `strftime docs`_.) It's set to ``"%b"`` by default, which is a three-
-    letter month abbreviation. To change it to use numbers, use ``"%m"``.
-
-``day_format``
-    Like ``month_format``, but for the ``day`` parameter. It defaults to
-    ``"%d"`` (day of the month as a decimal number, 01-31).
-
-``template_name``
-    The full name of a template to use in rendering the page. This lets you
-    override the default template name (see below).
-
-``template_loader``
-    The template loader to use when loading the template. By default, it's
-    ``django.template.loader``.
-
-``extra_context``
-    A dictionary of values to add to the template context. By default, this is
-    an empty dictionary. If a value in the dictionary is callable, the generic
-    view will call it just before rendering the template.
-
-``allow_empty``
-    A boolean specifying whether to display the page if no objects are
-    available. If this is ``False`` and no objects are available, the view will
-    raise a 404 instead of displaying an empty page. By default, this is
-    ``False``.
-
-``context_processors``
-    A list of template-context processors to apply to the view's template. See
-    the `RequestContext docs`_.
-
-``template_object_name``
-     Designates the name of the template variable to use in the template
-     context. By default, this is ``'object'``. The view will append
-     ``'_list'`` to the value of this parameter in determining the variable's
-     name.
-
-``mimetype``
-    The MIME type to use for the resulting document. Defaults to the value of
-    the ``DEFAULT_CONTENT_TYPE`` setting.
-
-``allow_future``
-    A boolean specifying whether to include "future" objects on this page,
-    where "future" means objects in which the field specified in ``date_field``
-    is greater than the current date/time. By default, this is ``False``.
-
-Template name
-~~~~~~~~~~~~~
-
-If ``template_name`` isn't specified, this view will use the template
-``<app_label>/<model_name>_archive_day.html`` by default.
-
-Template context
-~~~~~~~~~~~~~~~~
-
-In addition to ``extra_context``, the template's context will be:
-
-``day``
-    A ``datetime.date`` object representing the given day.
-
-``next_day``
-    A ``datetime.date`` object representing the next day. If the next day is in
-    the future, this will be ``None``.
-
-``previous_day``
-    A ``datetime.date`` object representing the given day. Unlike ``next_day``,
-    this will never be ``None``.
-
-``object_list``
-    A list of objects available for the given day. This variable's name depends
-    on the ``template_object_name`` parameter, which is ``'object'`` by
-    default. If ``template_object_name`` is ``'foo'``, this variable's name
-    will be ``foo_list``.
-
-``django.views.generic.date_based.archive_today``
--------------------------------------------------
-
-Description
-~~~~~~~~~~~
-
-A day archive page showing all objects for *today*. This is exactly the same as
-``archive_day``, except the ``year``/``month``/``day`` arguments are not used,
-and today's date is used instead.
-
-``django.views.generic.date_based.object_detail``
--------------------------------------------------
-
-Description
-~~~~~~~~~~~
-
-A page representing an individual object. If the object has a date value in the
-future, the view will throw a 404 error by default, unless you set
-``allow_future`` to ``True``.
-
-Required arguments
-~~~~~~~~~~~~~~~~~~
-
-``year``
-    The object's four-digit year (a string).
-
-``month``
-    The object's month , formatted according to the ``month_format`` argument.
-
-``day``
-    The object's day , formatted according to the ``day_format`` argument.
-
-``queryset``
-    A ``QuerySet`` that contains the object.
-
-``date_field``
-    The name of the ``DateField`` or ``DateTimeField`` in the ``QuerySet``'s
-    model that the generic view should use to look up the object according to
-    ``year``, ``month`` and ``day``.
-
-Either ``object_id`` or (``slug`` *and* ``slug_field``) is required.
-    If you provide ``object_id``, it should be the value of the primary-key
-    field for the object being displayed on this page.
-
-    Otherwise, ``slug`` should be the slug of the given object, and
-    ``slug_field`` should be the name of the slug field in the ``QuerySet``'s
-    model. By default, ``slug_field`` is ``'slug'``.
-
-Optional arguments
-~~~~~~~~~~~~~~~~~~
-
-``month_format``
-    A format string that regulates what format the ``month`` parameter uses.
-    This should be in the syntax accepted by Python's ``time.strftime``. (See
-    the `strftime docs`_.) It's set to ``"%b"`` by default, which is a three-
-    letter month abbreviation. To change it to use numbers, use ``"%m"``.
-
-``day_format``
-    Like ``month_format``, but for the ``day`` parameter. It defaults to
-    ``"%d"`` (day of the month as a decimal number, 01-31).
-
-``template_name``
-    The full name of a template to use in rendering the page. This lets you
-    override the default template name (see below).
-
-``template_name_field``
-    The name of a field on the object whose value is the template name to use.
-    This lets you store template names in the data. In other words, if your
-    object has a field ``'the_template'`` that contains a string
-    ``'foo.html'``, and you set ``template_name_field`` to ``'the_template'``,
-    then the generic view for this object will use the template ``'foo.html'``.
-
-    It's a bit of a brain-bender, but it's useful in some cases.
-
-``template_loader``
-    The template loader to use when loading the  template. By default, it's
-    ``django.template.loader``.
-
-``extra_context``
-    A dictionary of values to add to the template context. By default, this is
-    an empty dictionary. If a value in the dictionary is callable, the generic
-    view will call it just before rendering the template.
-
-``context_processors``
-    A list of template-context processors to apply to the view's template. See
-    the `RequestContext docs`_.
-
-``template_object_name``
-    Designates the name of the template variable to use in the template
-    context. By default, this is ``'object'``.
-
-``mimetype``
-    The MIME type to use for the resulting document. Defaults to the value of
-    the ``DEFAULT_CONTENT_TYPE`` setting.
-
-``allow_future``
-    A boolean specifying whether to include "future" objects on this page,
-    where "future" means objects in which the field specified in ``date_field``
-    is greater than the current date/time. By default, this is ``False``.
-
-Template name
-~~~~~~~~~~~~~
-
-If ``template_name`` isn't specified, this view will use the template
-``<app_label>/<model_name>_detail.html`` by default.
-
-Template context
-~~~~~~~~~~~~~~~~
-
-In addition to ``extra_context``, the template's context will be:
-
-``object``
-    The object. This variable's name depends on the ``template_object_name``
-    parameter, which is ``'object'`` by default. If ``template_object_name`` is
-    ``'foo'``, this variable's name will be ``foo``.
-
-List/detail generic views
-=========================
-
-The list-detail generic-view framework (in the
-``django.views.generic.list_detail`` module) is similar to the date-based one,
-except the former simply has two views: a list of objects and an individual
-object page.
-
-``django.views.generic.list_detail.object_list``
-------------------------------------------------
-
-Description
-~~~~~~~~~~~
-
-A page representing a list of objects.
-
-Required arguments
-~~~~~~~~~~~~~~~~~~
-
-``queryset``
-    A ``QuerySet`` that represents the objects.
-
-Optional arguments
-~~~~~~~~~~~~~~~~~~
-
-``paginate_by``
-    An integer specifying how many objects should be displayed per page. If
-    this is given, the view will paginate objects with ``paginate_by`` objects
-    per page. The view will expect either a ``page`` query string parameter
-    (via ``GET``) or a ``page`` variable specified in the URLconf. See `Notes
-    on pagination`_ below.
-
-``page``
-    The current (1-based) page number, as an integer, or the string ``'last'``.
-    See `Notes on pagination`_ below.
-
-``template_name``
-    The full name of a template to use in rendering the page. This lets you
-    override the default template name (see below).
-
-``template_loader``
-    The template loader to use when loading the template. By default, it's
-    ``django.template.loader``.
-
-``extra_context``
-    A dictionary of values to add to the template context. By default, this is
-    an empty dictionary. If a value in the dictionary is callable, the generic
-    view will call it just before rendering the template.
-
-``allow_empty``
-    A boolean specifying whether to display the page if no objects are
-    available. If this is ``False`` and no objects are available, the view will
-    raise a 404 instead of displaying an empty page. By default, this is
-    ``True``.
-
-``context_processors``
-    A list of template-context processors to apply to the view's template. See
-    the `RequestContext docs`_.
-
-``template_object_name``
-    Designates the name of the template variable to use in the template
-    context. By default, this is ``'object'``. The view will append ``'_list'``
-    to the value of this parameter in determining the variable's name.
-
-``mimetype``
-    The MIME type to use for the resulting document. Defaults to the value of
-    the ``DEFAULT_CONTENT_TYPE`` setting.
-
-Template name
-~~~~~~~~~~~~~
-
-If ``template_name`` isn't specified, this view will use the template
-``<app_label>/<model_name>_list.html`` by default.
-
-Template context
-~~~~~~~~~~~~~~~~
-
-In addition to ``extra_context``, the template's context will be:
-
-``object_list``
-    The list of objects. This variable's name depends on the
-    ``template_object_name`` parameter, which is ``'object'`` by default. If
-    ``template_object_name`` is ``'foo'``, this variable's name will be
-    ``foo_list``.
-
-``is_paginated``
-    A boolean representing whether the results are paginated. Specifically,
-    this is set to ``False`` if the number of available objects is less than or
-    equal to ``paginate_by``.
-
-If the results are paginated, the context will contain these extra variables:
-
-``paginator`` (**New in Django development version**)
-    An instance of ``django.core.paginator.Paginator``.
-
-``page_obj`` (**New in Django development version**)
-    An instance of ``django.core.paginator.Page``.
-
-See the `pagination documentation`_ for more information on the ``Paginator``
-and ``Page`` objects.
-
-Notes on pagination
-~~~~~~~~~~~~~~~~~~~
-
-If ``paginate_by`` is specified, Django will paginate the results. You can
-specify the page number in the URL in one of two ways:
-
-    * Use the ``page`` parameter in the URLconf. For example, this is what
-      your URLconf might look like::
-
-        (r'^objects/page(?P<page>[0-9]+)/$', 'object_list', dict(info_dict))
-
-    * Pass the page number via the ``page`` query-string parameter. For
-      example, a URL would look like this::
-
-        /objects/?page=3
-
-    * To loop over all the available page numbers, use the ``page_range``
-      variable. You can iterate over the list provided by ``page_range``
-      to create a link to every page of results.
-
-These values and lists are 1-based, not 0-based, so the first page would be
-represented as page ``1``.
-
-For more on pagination, read the `pagination documentation`_.
-
-.. _`pagination documentation`: ../pagination/
-
-**New in Django development version:**
-
-As a special case, you are also permitted to use ``last`` as a value for
-``page``::
-
-    /objects/?page=last
-
-This allows you to access the final page of results without first having to
-determine how many pages there are.
-
-Note that ``page`` *must* be either a valid page number or the value ``last``;
-any other value for ``page`` will result in a 404 error.
-
-``django.views.generic.list_detail.object_detail``
---------------------------------------------------
-
-A page representing an individual object.
-
-Description
-~~~~~~~~~~~
-
-A page representing an individual object.
-
-Required arguments
-~~~~~~~~~~~~~~~~~~
-
-``queryset``
-    A ``QuerySet`` that contains the object.
-
-Either ``object_id`` or (``slug`` *and* ``slug_field``)
-    If you provide ``object_id``, it should be the value of the primary-key
-    field for the object being displayed on this page.
-
-    Otherwise, ``slug`` should be the slug of the given object, and
-    ``slug_field`` should be the name of the slug field in the ``QuerySet``'s
-    model. By default, ``slug_field`` is ``'slug'``.
-
-Optional arguments
-~~~~~~~~~~~~~~~~~~
-
-``template_name``
-    The full name of a template to use in rendering the page. This lets you
-    override the default template name (see below).
-
-``template_name_field``
-    The name of a field on the object whose value is the template name to use.
-    This lets you store template names in the data. In other words, if your
-    object has a field ``'the_template'`` that contains a string
-    ``'foo.html'``, and you set ``template_name_field`` to ``'the_template'``,
-    then the generic view for this object will use the template ``'foo.html'``.
-
-    It's a bit of a brain-bender, but it's useful in some cases.
-
-``template_loader``
-    The template loader to use when loading the template. By default, it's
-    ``django.template.loader``.
-
-``extra_context``
-    A dictionary of values to add to the template context. By default, this is
-    an empty dictionary. If a value in the dictionary is callable, the generic
-    view will call it just before rendering the template.
-
-``context_processors``
-    A list of template-context processors to apply to the view's template. See
-    the `RequestContext docs`_.
-
-``template_object_name``
-    Designates the name of the template variable to use in the template
-    context. By default, this is ``'object'``.
-
-``mimetype``
-    The MIME type to use for the resulting document. Defaults to the value of
-    the ``DEFAULT_CONTENT_TYPE`` setting.
-
-Template name
-~~~~~~~~~~~~~
-
-If ``template_name`` isn't specified, this view will use the template
-``<app_label>/<model_name>_detail.html`` by default.
-
-Template context
-~~~~~~~~~~~~~~~~
-
-In addition to ``extra_context``, the template's context will be:
-
-``object``
-    The object. This variable's name depends on the ``template_object_name``
-    parameter, which is ``'object'`` by default. If ``template_object_name`` is
-    ``'foo'``, this variable's name will be ``foo``.
-
-Create/update/delete generic views
-==================================
-
-The ``django.views.generic.create_update`` module contains a set of functions
-for creating, editing and deleting objects.
-
-**Changed in Django development version:**
-
-``django.views.generic.create_update.create_object`` and
-``django.views.generic.create_update.update_object`` now use the new `forms
-library`_ to build and display the form.
-
-.. _forms library: ../forms/
-
-``django.views.generic.create_update.create_object``
-----------------------------------------------------
-
-Description
-~~~~~~~~~~~
-
-A page that displays a form for creating an object, redisplaying the form with
-validation errors (if there are any) and saving the object.
-
-Required arguments
-~~~~~~~~~~~~~~~~~~
-
-Either ``form_class`` or ``model``
-    If you provide ``form_class``, it should be a ``django.forms.ModelForm``
-    subclass.  Use this argument when you need to customize the model's form.
-    See the `ModelForm docs`_ for more information.
-
-    Otherwise, ``model`` should be a Django model class and the form used will
-    be a standard ``ModelForm`` for ``model``.
-
-Optional arguments
-~~~~~~~~~~~~~~~~~~
-
-``post_save_redirect``
-    A URL to which the view will redirect after saving the object. By default,
-    it's ``object.get_absolute_url()``.
-
-    ``post_save_redirect`` may contain dictionary string formatting, which will
-    be interpolated against the object's field attributes. For example, you
-    could use ``post_save_redirect="/polls/%(slug)s/"``.
-
-``login_required``
-    A boolean that designates whether a user must be logged in, in order to see
-    the page and save changes. This hooks into the Django `authentication
-    system`_. By default, this is ``False``.
-
-    If this is ``True``, and a non-logged-in user attempts to visit this page
-    or save the form, Django will redirect the request to ``/accounts/login/``.
-
-``template_name``
-    The full name of a template to use in rendering the page. This lets you
-    override the default template name (see below).
-
-``template_loader``
-    The template loader to use when loading the template. By default, it's
-    ``django.template.loader``.
-
-``extra_context``
-    A dictionary of values to add to the template context. By default, this is
-    an empty dictionary. If a value in the dictionary is callable, the generic
-    view will call it just before rendering the template.
-
-``context_processors``
-    A list of template-context processors to apply to the view's template. See
-    the `RequestContext docs`_.
-
-Template name
-~~~~~~~~~~~~~
-
-If ``template_name`` isn't specified, this view will use the template
-``<app_label>/<model_name>_form.html`` by default.
-
-Template context
-~~~~~~~~~~~~~~~~
-
-In addition to ``extra_context``, the template's context will be:
-
-``form``
-    A ``django.forms.ModelForm`` instance representing the form for creating
-    the object. This lets you refer to form fields easily in the template
-    system.
-
-    For example, if the model has two fields, ``name`` and ``address``::
-
-        <form action="" method="post">
-        <p>{{ form.name.label_tag }} {{ form.name }}</p>
-        <p>{{ form.address.label_tag }} {{ form.address }}</p>
-        </form>
-
-    See the `forms documentation`_ for more information about using ``Form``
-    objects in templates.
-
-.. _authentication system: ../authentication/
-.. _ModelForm docs: ../modelforms/
-.. _forms documentation: ../forms/
-
-``django.views.generic.create_update.update_object``
-----------------------------------------------------
-
-Description
-~~~~~~~~~~~
-
-A page that displays a form for editing an existing object, redisplaying the
-form with validation errors (if there are any) and saving changes to the
-object. This uses a form automatically generated from the object's
-model class.
-
-Required arguments
-~~~~~~~~~~~~~~~~~~
-
-Either ``form_class`` or ``model``
-    If you provide ``form_class``, it should be a ``django.forms.ModelForm``
-    subclass.  Use this argument when you need to customize the model's form.
-    See the `ModelForm docs`_ for more information.
-
-    Otherwise, ``model`` should be a Django model class and the form used will
-    be a standard ``ModelForm`` for ``model``.
-
-Either ``object_id`` or (``slug`` *and* ``slug_field``)
-    If you provide ``object_id``, it should be the value of the primary-key
-    field for the object being displayed on this page.
-
-    Otherwise, ``slug`` should be the slug of the given object, and
-    ``slug_field`` should be the name of the slug field in the ``QuerySet``'s
-    model. By default, ``slug_field`` is ``'slug'``.
-
-Optional arguments
-~~~~~~~~~~~~~~~~~~
-
-``post_save_redirect``
-    A URL to which the view will redirect after saving the object. By default,
-    it's ``object.get_absolute_url()``.
-
-    ``post_save_redirect`` may contain dictionary string formatting, which will
-    be interpolated against the object's field attributes. For example, you
-    could use ``post_save_redirect="/polls/%(slug)s/"``.
-
-``login_required``
-    A boolean that designates whether a user must be logged in, in order to see
-    the page and save changes. This hooks into the Django `authentication
-    system`_. By default, this is ``False``.
-
-    If this is ``True``, and a non-logged-in user attempts to visit this page
-    or save the form, Django will redirect the request to ``/accounts/login/``.
-
-``template_name``
-    The full name of a template to use in rendering the page. This lets you
-    override the default template name (see below).
-
-``template_loader``
-    The template loader to use when loading the template. By default, it's
-    ``django.template.loader``.
-
-``extra_context``
-    A dictionary of values to add to the template context. By default, this is
-    an empty dictionary. If a value in the dictionary is callable, the generic
-    view will call it just before rendering the template.
-
-``context_processors``: A list of template-context processors to apply to
-      the view's template. See the `RequestContext docs`_.
-
-``template_object_name``
-    Designates the name of the template variable to use in the template
-    context. By default, this is ``'object'``.
-
-Template name
-~~~~~~~~~~~~~
-
-If ``template_name`` isn't specified, this view will use the template
-``<app_label>/<model_name>_form.html`` by default.
-
-Template context
-~~~~~~~~~~~~~~~~
-
-In addition to ``extra_context``, the template's context will be:
-
-``form``
-    A ``django.forms.ModelForm`` instance representing the form for editing the
-    object. This lets you refer to form fields easily in the template system.
-
-    For example, if the model has two fields, ``name`` and ``address``::
-
-        <form action="" method="post">
-        <p>{{ form.name.label_tag }} {{ form.name }}</p>
-        <p>{{ form.address.label_tag }} {{ form.address }}</p>
-        </form>
-
-    See the `forms documentation`_ for more information about using ``Form``
-    objects in templates.
-
-``object``
-    The original object being edited. This variable's name depends on the
-    ``template_object_name`` parameter, which is ``'object'`` by default. If
-    ``template_object_name`` is ``'foo'``, this variable's name will be
-    ``foo``.
-
-``django.views.generic.create_update.delete_object``
-----------------------------------------------------
-
-Description
-~~~~~~~~~~~
-
-A view that displays a confirmation page and deletes an existing object. The
-given object will only be deleted if the request method is ``POST``. If this
-view is fetched via ``GET``, it will display a confirmation page that should
-contain a form that POSTs to the same URL.
-
-Required arguments
-~~~~~~~~~~~~~~~~~~
-
-``model``
-    The Django model class of the object that the form will create.
-
-Either ``object_id`` or (``slug`` *and* ``slug_field``)
-    If you provide ``object_id``, it should be the value of the primary-key
-    field for the object being displayed on this page.
-
-    Otherwise, ``slug`` should be the slug of the given object, and
-    ``slug_field`` should be the name of the slug field in the ``QuerySet``'s
-    model. By default, ``slug_field`` is ``'slug'``.
-
-``post_delete_redirect``
-    A URL to which the view will redirect after deleting the object.
-
-Optional arguments
-~~~~~~~~~~~~~~~~~~
-
-``login_required``
-    A boolean that designates whether a user must be logged in, in order to see
-    the page and save changes. This hooks into the Django `authentication
-    system`_. By default, this is ``False``.
-
-    If this is ``True``, and a non-logged-in user attempts to visit this page
-    or save the form, Django will redirect the request to ``/accounts/login/``.
-
-``template_name``
-    The full name of a template to use in rendering the page. This lets you
-    override the default template name (see below).
-
-``template_loader``
-    The template loader to use when loading the template. By default, it's
-    ``django.template.loader``.
-
-``extra_context``
-    A dictionary of values to add to the template context. By default, this is
-    an empty dictionary. If a value in the dictionary is callable, the generic
-    view will call it just before rendering the template.
-
-``context_processors``
-    A list of template-context processors to apply to the view's template. See
-    the `RequestContext docs`_.
-
-``template_object_name``
-    Designates the name of the template variable to use in the template
-    context. By default, this is ``'object'``.
-
-Template name
-~~~~~~~~~~~~~
-
-If ``template_name`` isn't specified, this view will use the template
-``<app_label>/<model_name>_confirm_delete.html`` by default.
-
-Template context
-~~~~~~~~~~~~~~~~
-
-In addition to ``extra_context``, the template's context will be:
-
-``object``
-    The original object that's about to be deleted. This variable's name
-    depends on the ``template_object_name`` parameter, which is ``'object'`` by
-    default. If ``template_object_name`` is ``'foo'``, this variable's name
-    will be ``foo``.

+ 80 - 0
docs/glossary.txt

@@ -0,0 +1,80 @@
+.. _glossary:
+
+========
+Glossary
+========
+
+.. glossary::
+
+    field
+        An attribute on a :term:`model`; a given field usually maps directly to
+        a single database column.
+        
+        See :ref:`topics-db-models`.
+
+    generic view
+        A higher-order :term:`view` function that abstracts common idioms and patterns
+        found in view development and abstracts them.
+        
+        See :ref:`ref-generic-views`.
+
+    model
+        Models store your application's data.
+        
+        See :ref:`topics-db-models`.
+
+    MTV
+        See :ref:`mtv`.
+
+    MVC
+        `Model-view-controller`__; a software pattern. Django :ref:`follows MVC
+        to some extent <mtv>`.
+
+        __ http://en.wikipedia.org/wiki/Model-view-controller
+
+    project
+        A Python package -- i.e. a directory of code -- that contains all the
+        settings for an instance of Django. This would include database
+        configuration, Django-specific options and application-specific
+        settings.
+
+    property
+        Also known as "managed attributes", and a feature of Python since
+        version 2.2. From `the property documentation`__:
+        
+            Properties are a neat way to implement attributes whose usage
+            resembles attribute access, but whose implementation uses method
+            calls. [...] You
+            could only do this by overriding ``__getattr__`` and
+            ``__setattr__``; but overriding ``__setattr__`` slows down all
+            attribute assignments considerably, and overriding ``__getattr__``
+            is always a bit tricky to get right. Properties let you do this
+            painlessly, without having to override ``__getattr__`` or
+            ``__setattr__``.
+
+        __ http://www.python.org/download/releases/2.2/descrintro/#property
+
+    queryset
+        An object representing some set of rows to be fetched from the database.
+        
+        See :ref:`topics-db-queries`.
+
+    slug
+        A short label for something, containing only letters, numbers,
+        underscores or hyphens. They're generally used in URLs. For
+        example, in a typical blog entry URL:
+        
+        .. parsed-literal::
+        
+            http://www.djangoproject.com/weblog/2008/apr/12/**spring**/
+            
+        the last bit (``spring``) is the slug.
+
+    template
+        A chunk of text that separates the presentation of a document from its
+        data.
+        
+        See :ref:`topics-templates`.
+        
+    view
+        A function responsible for rending a page.

+ 15 - 9
docs/apache_auth.txt → docs/howto/apache-auth.txt

@@ -1,10 +1,13 @@
+.. _howto-apache-auth:
+
 =========================================================
 Authenticating against Django's user database from Apache
 =========================================================
 
 Since keeping multiple authentication databases in sync is a common problem when
 dealing with Apache, you can configuring Apache to authenticate against Django's
-`authentication system`_ directly.  For example, you could:
+:ref:`authentication system <topics-auth>` directly. For example, you
+could:
 
     * Serve static/media files directly from Apache only to authenticated users.
 
@@ -13,12 +16,17 @@ dealing with Apache, you can configuring Apache to authenticate against Django's
 
     * Allow certain users to connect to a WebDAV share created with mod_dav_.
 
+.. _Subversion: http://subversion.tigris.org/
+.. _mod_dav: http://httpd.apache.org/docs/2.0/mod/mod_dav.html
+
 Configuring Apache
 ==================
 
 To check against Django's authorization database from a Apache configuration
 file, you'll need to use mod_python's ``PythonAuthenHandler`` directive along
-with the standard ``Auth*`` and ``Require`` directives::
+with the standard ``Auth*`` and ``Require`` directives:
+
+.. code-block:: apache
 
     <Location /example/>
         AuthType Basic
@@ -43,6 +51,8 @@ with the standard ``Auth*`` and ``Require`` directives::
     the ``AuthUserFile`` directive and pointing it to ``/dev/null``. Depending
     on which other authentication modules you have loaded, you might need one
     or more of the following directives::
+    
+    .. code-block:: apache
 
         AuthBasicAuthoritative Off
         AuthDefaultAuthoritative Off
@@ -94,8 +104,9 @@ location to users marked as staff members.  You can use a set of
                                       Defaults to ``off``.
 
     ``DjangoPermissionName``          The name of a permission to require for
-                                      access. See `custom permissions`_ for
-                                      more information.
+                                      access. See :ref:`custom permissions
+                                      <custom-permissions>` for more
+                                      information.
 
                                       By default no specific permission will be
                                       required.
@@ -109,8 +120,3 @@ are equivalent::
 
     SetEnv DJANGO_SETTINGS_MODULE mysite.settings
     PythonOption DJANGO_SETTINGS_MODULE mysite.settings
-
-.. _authentication system: ../authentication/
-.. _Subversion: http://subversion.tigris.org/
-.. _mod_dav: http://httpd.apache.org/docs/2.0/mod/mod_dav.html
-.. _custom permissions: ../authentication/#custom-permissions

+ 78 - 0
docs/howto/custom-file-storage.txt

@@ -0,0 +1,78 @@
+.. _howto-custom-file-storage:
+
+Writing a custom storage system
+===============================
+
+If you need to provide custom file storage -- a common example is storing files
+on some remote system -- you can do so by defining a custom storage class.
+You'll need to follow these steps:
+
+#. Your custom storage system must be a subclass of
+   ``django.core.files.storage.Storage``::
+
+        from django.core.files.storage import Storage
+
+        class MyStorage(Storage):
+            ...
+
+#. Django must be able to instantiate your storage system without any arguments.
+   This means that any settings should be taken from ``django.conf.settings``::
+
+        from django.conf import settings
+        from django.core.files.storage import Storage
+
+        class MyStorage(Storage):
+            def __init__(self, option=None):
+                if not option:
+                    option = settings.CUSTOM_STORAGE_OPTIONS
+                ...
+
+#. Your storage class must implement the ``_open()`` and ``_save()`` methods,
+   along with any other methods appropriate to your storage class. See below for
+   more on these methods.
+
+   In addition, if your class provides local file storage, it must override
+   the ``path()`` method.
+
+Your custom storage system may override any of the storage methods explained in
+:ref:`ref-files-storage`. However, it's usually better to use the hooks
+specifically designed for custom storage objects. These are:
+
+``_open(name, mode='rb')``
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+**Required**.
+
+Called by ``Storage.open()``, this is the actual mechanism the storage class
+uses to open the file. This must return a ``File`` object, though in most cases,
+you'll want to return some subclass here that implements logic specific to the
+backend storage system.
+
+``_save(name, content)``
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Called by ``Storage.save()``. The ``name`` will already have gone through
+``get_valid_name()`` and ``get_available_name()``, and the ``content`` will be a
+``File`` object itself. No return value is expected.
+
+``get_valid_name(name)``
+------------------------
+
+Returns a filename suitable for use with the underlying storage system. The
+``name`` argument passed to this method is the original filename sent to the
+server, after having any path information removed. Override this to customize
+how non-standard characters are converted to safe filenames.
+
+The code provided on ``Storage`` retains only alpha-numeric characters, periods
+and underscores from the original filename, removing everything else.
+
+``get_available_name(name)``
+----------------------------
+
+Returns a filename that is available in the storage mechanism, possibly taking
+the provided filename into account. The ``name`` argument passed to this method
+will have already cleaned to a filename valid for the storage system, according
+to the ``get_valid_name()`` method described above.
+
+The code provided on ``Storage`` simply appends underscores to the filename
+until it finds one that's available in the destination directory.

+ 33 - 0
docs/howto/custom-management-commands.txt

@@ -0,0 +1,33 @@
+.. _howto-custom-management-commands:
+
+Writing custom django-admin commands
+====================================
+
+**New in Django development version**
+
+Applications can register their own actions with ``manage.py``. For example,
+you might want to add a ``manage.py`` action for a Django app that you're
+distributing.
+
+To do this, just add a ``management/commands`` directory to your application.
+Each Python module in that directory will be auto-discovered and registered as
+a command that can be executed as an action when you run ``manage.py``::
+
+    blog/
+        __init__.py
+        models.py
+        management/
+            __init__.py
+            commands/
+                __init__.py
+                explode.py
+        views.py
+
+In this example, the ``explode`` command will be made available to any project
+that includes the ``blog`` application in ``settings.INSTALLED_APPS``.
+
+The ``explode.py`` module has only one requirement -- it must define a class
+called ``Command`` that extends ``django.core.management.base.BaseCommand``.
+
+For more details on how to define your own commands, look at the code for the
+existing ``django-admin.py`` commands, in ``/django/core/management/commands``.

+ 196 - 174
docs/custom_model_fields.txt → docs/howto/custom-model-fields.txt

@@ -1,23 +1,28 @@
-===================
-Custom model fields
-===================
+.. _howto-custom-model-fields:
+
+===========================
+Writing custom model fields
+===========================
 
 **New in Django development version**
 
 Introduction
 ============
 
-The `model reference`_ documentation explains how to use Django's standard
-field classes -- ``CharField``, ``DateField``, etc. For many purposes, those
-classes are all you'll need. Sometimes, though, the Django version won't meet
-your precise requirements, or you'll want to use a field that is entirely
-different from those shipped with Django.
+The :ref:`model reference <topics-db-models>` documentation explains how to use
+Django's standard field classes -- :class:`~django.db.models.CharField`,
+:class:`~django.db.models.DateField`, etc. For many purposes, those classes are
+all you'll need. Sometimes, though, the Django version won't meet your precise
+requirements, or you'll want to use a field that is entirely different from
+those shipped with Django.
 
 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
+
 Alternatively, you may have a complex Python object that can somehow be
 serialized to fit into a standard database column type. This is another case
 where a ``Field`` subclass will help you use your object with your models.
@@ -40,9 +45,11 @@ Our class looks something like this::
             self.east = east
             self.south = south
             self.west = west
-
+        
         # ... (other possibly useful methods omitted) ...
 
+.. _Bridge: http://en.wikipedia.org/wiki/Contract_bridge
+
 This is just an ordinary Python class, with nothing Django-specific about it.
 We'd like to be able to do things like this in our models (we assume the
 ``hand`` attribute on the model is an instance of ``Hand``)::
@@ -68,10 +75,6 @@ model support for existing classes where you cannot change the source code.
     strings, or floats, for example. This case is similar to our ``Hand``
     example and we'll note any differences as we go along.
 
-.. _model reference: ../model_api/
-.. _PostgreSQL custom types: http://www.postgresql.org/docs/8.2/interactive/sql-createtype.html
-.. _Bridge: http://en.wikipedia.org/wiki/Contract_bridge
-
 Background theory
 =================
 
@@ -103,15 +106,13 @@ What does a field class do?
 ---------------------------
 
 All of Django's fields (and when we say *fields* in this document, we always
-mean model fields and not `form fields`_) are subclasses of
-``django.db.models.Field``. Most of the information that Django records about a
-field is common to all fields -- name, help text, validator lists, uniqueness
-and so forth. Storing all that information is handled by ``Field``. We'll get
-into the precise details of what ``Field`` can do later on; for now, suffice it
-to say that everything descends from ``Field`` and then customizes key pieces
-of the class behavior.
-
-.. _form fields: ../forms/#fields
+mean model fields and not :ref:`form fields <ref-forms-fields>`) are subclasses
+of :class:`django.db.models.Field`. Most of the information that Django records
+about a field is common to all fields -- name, help text, validator lists,
+uniqueness and so forth. Storing all that information is handled by ``Field``.
+We'll get into the precise details of what ``Field`` can do later on; for now,
+suffice it to say that everything descends from ``Field`` and then customizes
+key pieces of the class behavior.
 
 It's important to realize that a Django field class is not what is stored in
 your model attributes. The model attributes contain normal Python objects. The
@@ -120,7 +121,7 @@ when the model class is created (the precise details of how this is done are
 unimportant here). This is because the field classes aren't necessary when
 you're just creating and modifying attributes. Instead, they provide the
 machinery for converting between the attribute value and what is stored in the
-database or sent to the serializer.
+database or sent to the :ref:`serializer <topics-serialization>`.
 
 Keep this in mind when creating your own custom fields. The Django ``Field``
 subclass you write provides the machinery for converting between your Python
@@ -139,22 +140,25 @@ classes when you want a custom field:
       how to convert your first class back and forth between its permanent
       storage form and the Python form.
 
-Writing a ``Field`` subclass
-=============================
+Writing a field subclass
+========================
 
-When planning your ``Field`` subclass, first give some thought to which
-existing ``Field`` class your new field is most similar to. Can you subclass an
-existing Django field and save yourself some work? If not, you should subclass
-the ``Field`` class, from which everything is descended.
+When planning your :class:`~django.db.models.Field` subclass, first give some
+thought to which existing :class:`~django.db.models.Field` class your new field
+is most similar to. Can you subclass an existing Django field and save yourself
+some work? If not, you should subclass the :class:`~django.db.models.Field`
+class, from which everything is descended.
 
-Initializing your new field is a matter of separating out any arguments that
-are specific to your case from the common arguments and passing the latter to
-the ``__init__()`` method of ``Field`` (or your parent class).
+Initializing your new field is a matter of separating out any arguments that are
+specific to your case from the common arguments and passing the latter to the
+:meth:`~django.db.models.Field.__init__` method of
+:class:`~django.db.models.Field` (or your parent class).
 
 In our example, we'll call our field ``HandField``. (It's a good idea to call
-your ``Field`` subclass ``(Something)Field``, so it's easily identifiable as a
-``Field`` subclass.) It doesn't behave like any existing field, so we'll
-subclass directly from ``Field``::
+your :class:`~django.db.models.Field` subclass ``<Something>Field``, so it's
+easily identifiable as a :class:`~django.db.models.Field` subclass.) It doesn't
+behave like any existing field, so we'll subclass directly from
+:class:`~django.db.models.Field`::
 
     from django.db import models
 
@@ -169,10 +173,13 @@ card values plus their suits; 104 characters in total.
 
 .. note::
     Many of Django's model fields accept options that they don't do anything
-    with. For example, you can pass both ``editable`` and ``auto_now`` to a
-    ``DateField`` and it will simply ignore the ``editable`` parameter
-    (``auto_now`` being set implies ``editable=False``). No error is raised in
-    this case.
+    with. For example, you can pass both
+    :attr:`~django.db.models.Field.editable` and
+    :attr:`~django.db.models.Field.auto_now` to a
+    :class:`django.db.models.DateField` and it will simply ignore the
+    :attr:`~django.db.models.Field.editable` parameter
+    (:attr:`~django.db.models.Field.auto_now` being set implies
+    ``editable=False``). No error is raised in this case.
 
     This behavior simplifies the field classes, because they don't need to
     check for options that aren't necessary. They just pass all the options to
@@ -180,41 +187,42 @@ card values plus their suits; 104 characters in total.
     you want your fields to be more strict about the options they select, or
     to use the simpler, more permissive behavior of the current fields.
 
-The ``Field.__init__()`` method takes the following parameters, in this
-order:
-
-    * ``verbose_name``
-    * ``name``
-    * ``primary_key``
-    * ``max_length``
-    * ``unique``
-    * ``blank``
-    * ``null``
-    * ``db_index``
-    * ``core``
-    * ``rel``: Used for related fields (like ``ForeignKey``). For advanced use
-      only.
-    * ``default``
-    * ``editable``
-    * ``serialize``: If ``False``, the field will not be serialized when the
-      model is passed to Django's serializers_. Defaults to ``True``.
-    * ``prepopulate_from``
-    * ``unique_for_date``
-    * ``unique_for_month``
-    * ``unique_for_year``
-    * ``validator_list``
-    * ``choices``
-    * ``help_text``
-    * ``db_column``
-    * ``db_tablespace``: Currently only used with the Oracle backend and only
-      for index creation. You can usually ignore this option.
+The :meth:`~django.db.models.Field.__init__` method takes the following
+parameters:
+
+    * :attr:`~django.db.models.Field.verbose_name`
+    * :attr:`~django.db.models.Field.name`
+    * :attr:`~django.db.models.Field.primary_key`
+    * :attr:`~django.db.models.Field.max_length`
+    * :attr:`~django.db.models.Field.unique`
+    * :attr:`~django.db.models.Field.blank`
+    * :attr:`~django.db.models.Field.null`
+    * :attr:`~django.db.models.Field.db_index`
+    * :attr:`~django.db.models.Field.core`
+    * :attr:`~django.db.models.Field.rel`: Used for related fields (like
+      :attr:`~django.db.models.Field.ForeignKey`). For advanced use only.
+    * :attr:`~django.db.models.Field.default`
+    * :attr:`~django.db.models.Field.editable`
+    * :attr:`~django.db.models.Field.serialize`: If
+      :attr:`~django.db.models.Field.False`, the field will not be serialized
+      when the model is passed to Django's :ref:`serializers
+      <topics-serialization>`. Defaults to
+      :attr:`~django.db.models.Field.True`.
+    * :attr:`~django.db.models.Field.prepopulate_from`
+    * :attr:`~django.db.models.Field.unique_for_date`
+    * :attr:`~django.db.models.Field.unique_for_month`
+    * :attr:`~django.db.models.Field.unique_for_year`
+    * :attr:`~django.db.models.Field.validator_list`
+    * :attr:`~django.db.models.Field.choices`
+    * :attr:`~django.db.models.Field.help_text`
+    * :attr:`~django.db.models.Field.db_column`
+    * :attr:`~django.db.models.Field.db_tablespace`: Currently only used with
+      the Oracle backend and only for index creation. You can usually ignore
+      this option.
 
 All of the options without an explanation in the above list have the same
-meaning they do for normal Django fields. See the `model documentation`_ for
-examples and details.
-
-.. _serializers: ../serialization/
-.. _model documentation: ../model-api/
+meaning they do for normal Django fields. See the :ref:`field documentation
+<ref-models-fields>` for examples and details.
 
 The ``SubfieldBase`` metaclass
 ------------------------------
@@ -226,13 +234,16 @@ possible. If you're only working with custom database column types and your
 model fields appear in Python as standard Python types direct from the
 database backend, you don't need to worry about this section.
 
-If you're handling custom Python types, such as our ``Hand`` class, we need
-to make sure that when Django initializes an instance of our model and assigns
-a database value to our custom field attribute, we convert that value into the
+If you're handling custom Python types, such as our ``Hand`` class, we need to
+make sure that when Django initializes an instance of our model and assigns a
+database value to our custom field attribute, we convert that value into the
 appropriate Python object. The details of how this happens internally are a
 little complex, but the code you need to write in your ``Field`` class is
-simple: make sure your field subclass uses ``django.db.models.SubfieldBase`` as
-its metaclass::
+simple: make sure your field subclass uses a special metaclass:
+
+.. class:: django.db.models.SubfieldBase
+
+For example::
 
     class HandField(models.Field):
         __metaclass__ = models.SubfieldBase
@@ -240,27 +251,27 @@ its metaclass::
         def __init__(self, *args, **kwargs):
             # ...
 
-This ensures that the ``to_python()`` method, documented below_, will always be
+This ensures that the :meth:`to_python` method, documented below, will always be
 called when the attribute is initialized.
 
-.. _below: #to-python-self-value
-
 Useful methods
 --------------
 
-Once you've created your ``Field`` subclass and set up up the
-``__metaclass__``, you might consider overriding a few standard methods,
+Once you've created your :class:`~django.db.models.Field` subclass and set up up
+the ``__metaclass__``, you might consider overriding a few standard methods,
 depending on your field's behavior. The list of methods below is in
 approximately decreasing order of importance, so start from the top.
 
-``db_type(self)``
-~~~~~~~~~~~~~~~~~
+Custom database types
+~~~~~~~~~~~~~~~~~~~~~
+
+.. method:: db_type(self)
 
-Returns the database column data type for the ``Field``, taking into account
-the current ``DATABASE_ENGINE`` setting.
+Returns the database column data type for the :class:`~django.db.models.Field`,
+taking into account the current :setting:`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()``
+field with Django by subclassing ``Field`` and implementing the :meth:`db_type`
 method, like so::
 
     from django.db import models
@@ -281,7 +292,7 @@ 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.
+import the Django settings module and check the :setting:`DATABASE_ENGINE` setting.
 For example::
 
     class MyDateField(models.Field):
@@ -292,11 +303,11 @@ For example::
             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.
+The :meth:`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 :setting:`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,
@@ -316,7 +327,7 @@ sense to have a ``CharMaxlength25Field``, shown here::
 
 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::
+:meth:`django.db.models.Field.__init__`, like so::
 
     # This is a much more flexible example.
     class BetterCharField(models.Field):
@@ -333,13 +344,15 @@ time -- i.e., when the class is instantiated. To do that, just implement
         my_field = BetterCharField(25)
 
 Finally, if your column requires truly complex SQL setup, return ``None`` from
-``db_type()``. This will cause Django's SQL creation code to skip over this
+:meth:`db_type`. This will cause Django's SQL creation code to skip over this
 field. You are then responsible for creating the column in the right table in
-some other way, of course, but this gives you a way to tell Django to get out
-of the way.
+some other way, of course, but this gives you a way to tell Django to get out of
+the way.
 
-``to_python(self, value)``
-~~~~~~~~~~~~~~~~~~~~~~~~~~
+Converting database values to Python objects
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. method:: to_python(self, value)
 
 Converts a value as returned by your database (or a serializer) to a Python
 object.
@@ -348,10 +361,10 @@ The default implementation simply returns ``value``, for the common case in
 which the database backend already returns data in the correct format (as a
 Python string, for example).
 
-If your custom ``Field`` class deals with data structures that are more complex
-than strings, dates, integers or floats, then you'll need to override this
-method. As a general rule, the method should deal gracefully with any of the
-following arguments:
+If your custom :class:`~django.db.models.Field` class deals with data structures
+that are more complex than strings, dates, integers or floats, then you'll need
+to override this method. As a general rule, the method should deal gracefully
+with any of the following arguments:
 
     * An instance of the correct type (e.g., ``Hand`` in our ongoing example).
 
@@ -361,7 +374,7 @@ following arguments:
 
 In our ``HandField`` class, we're storing the data as a VARCHAR field in the
 database, so we need to be able to process strings and ``Hand`` instances in
-``to_python()``::
+:meth:`to_python`::
 
     import re
 
@@ -381,18 +394,20 @@ database, so we need to be able to process strings and ``Hand`` instances in
 Notice that we always return a ``Hand`` instance from this method. That's the
 Python object type we want to store in the model's attribute.
 
-**Remember:** If your custom field needs the ``to_python()`` method to be
+**Remember:** If your custom field needs the :meth:`to_python` method to be
 called when it is created, you should be using `The SubfieldBase metaclass`_
-mentioned earlier. Otherwise ``to_python()`` won't be called automatically.
+mentioned earlier. Otherwise :meth:`to_python` won't be called automatically.
 
-``get_db_prep_value(self, value)``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Converting Python objects to database values
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-This is the reverse of ``to_python()`` when working with the database backends
+.. method:: get_db_prep_value(self, value)
+
+This is the reverse of :meth:`to_python` when working with the database backends
 (as opposed to serialization). The ``value`` parameter is the current value of
 the model's attribute (a field has no reference to its containing model, so it
-cannot retrieve the value itself), and the method should return data in a
-format that can be used as a parameter in a query for the database backend.
+cannot retrieve the value itself), and the method should return data in a format
+that can be used as a parameter in a query for the database backend.
 
 For example::
 
@@ -403,8 +418,7 @@ For example::
             return ''.join([''.join(l) for l in (value.north,
                     value.east, value.south, value.west)])
 
-``get_db_prep_save(self, value)``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.. method:: get_db_prep_save(self, value)
 
 Same as the above, but called when the Field value must be *saved* to the
 database. As the default implementation just calls ``get_db_prep_value``, you
@@ -412,28 +426,33 @@ shouldn't need to implement this method unless your custom field need a special
 conversion when being saved that is not the same as the used for normal query
 parameters (which is implemented by ``get_db_prep_value``).
 
+Preprocessing values before saving
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-``pre_save(self, model_instance, add)``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.. method:: pre_save(self, model_instance, add)
 
-This method is called just prior to ``get_db_prep_save()`` and should return
+This method is called just prior to :meth:`get_db_prep_save` and should return
 the value of the appropriate attribute from ``model_instance`` for this field.
-The attribute name is in ``self.attname`` (this is set up by ``Field``). If
-the model is being saved to the database for the first time, the ``add``
-parameter will be ``True``, otherwise it will be ``False``.
+The attribute name is in ``self.attname`` (this is set up by
+:class:`~django.db.models.Field`). If the model is being saved to the database
+for the first time, the ``add`` parameter will be ``True``, otherwise it will be
+``False``.
 
 You only need to override this method if you want to preprocess the value
-somehow, just before saving. For example, Django's ``DateTimeField`` uses this
-method to set the attribute correctly in the case of ``auto_now`` or
-``auto_now_add``.
+somehow, just before saving. For example, Django's
+`:class:`~django.db.models.DateTimeField` uses this method to set the attribute
+correctly in the case of :attr:`~django.db.models.Field.auto_now` or
+:attr:`~django.db.models.Field.auto_now_add`.
 
 If you do override this method, you must return the value of the attribute at
 the end. You should also update the model's attribute if you make any changes
 to the value so that code holding references to the model will always see the
 correct value.
 
-``get_db_prep_lookup(self, lookup_type, value)``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Preparing values for use in database lookups
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. method:: get_db_prep_lookup(self, lookup_type, value)
 
 Prepares the ``value`` for passing to the database when used in a lookup (a
 ``WHERE`` constraint in SQL). The ``lookup_type`` will be one of the valid
@@ -447,7 +466,7 @@ should raise either a ``ValueError`` if the ``value`` is of the wrong sort (a
 list when you were expecting an object, for example) or a ``TypeError`` if
 your field does not support that type of lookup. For many fields, you can get
 by with handling the lookup types that need special handling for your field
-and pass the rest of the ``get_db_prep_lookup()`` method of the parent class.
+and pass the rest of the :meth:`get_db_prep_lookup` method of the parent class.
 
 If you needed to implement ``get_db_prep_save()``, you will usually need to
 implement ``get_db_prep_lookup()``. If you don't, ``get_db_prep_value`` will be
@@ -478,22 +497,23 @@ accepted lookup types to ``exact`` and ``in``::
             else:
                 raise TypeError('Lookup type %r not supported.' % lookup_type)
 
+Specifying the form field for a model field
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-``formfield(self, form_class=forms.CharField, **kwargs)``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.. method:: formfield(self, form_class=forms.CharField, **kwargs)
 
-Returns the default form field to use when this field is displayed
-in a model.
+Returns the default form field to use when this field is displayed in a model.
+This method is called by the :class:`~django.forms.ModelForm` helper.
 
 All of the ``kwargs`` dictionary is passed directly to the form field's
-``__init__()`` method. Normally, all you need to do is set up a good default
-for the ``form_class`` argument and then delegate further handling to the
-parent class. This might require you to write a custom form field (and even a
-form widget). See the `forms documentation`_ for information about this, and
-take a look at the code in ``django.contrib.localflavor`` for some examples of
-custom widgets.
+:meth:`~django.forms.Field__init__` method. Normally, all you need to do is
+set up a good default for the ``form_class`` argument and then delegate further
+handling to the parent class. This might require you to write a custom form
+field (and even a form widget). See the :ref:`forms documentation
+<topics-forms-index>` for information about this, and take a look at the code in
+:mod:`django.contrib.localflavor` for some examples of custom widgets.
 
-Continuing our ongoing example, we can write the ``formfield()`` method as::
+Continuing our ongoing example, we can write the :meth:`formfield` method as::
 
     class HandField(models.Field):
         # ...
@@ -512,15 +532,17 @@ fields.
 .. _helper functions: ../forms/#generating-forms-for-models
 .. _forms documentation: ../forms/
 
-``get_internal_type(self)``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Emulating built-in field types
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. method:: get_internal_type(self)
 
-Returns a string giving the name of the ``Field`` subclass we are emulating at
-the database level. This is used to determine the type of database column for
-simple cases.
+Returns a string giving the name of the :class:`~django.db.models.Field`
+subclass we are emulating at the database level. This is used to determine the
+type of database column for simple cases.
 
-If you have created a ``db_type()`` method, you don't need to worry about
-``get_internal_type()`` -- it won't be used much. Sometimes, though, your
+If you have created a :meth:`db_type` method, you don't need to worry about
+:meth:`get_internal_type` -- it won't be used much. Sometimes, though, your
 database storage is similar in type to some other field, so you can use that
 other field's logic to create the right column.
 
@@ -535,35 +557,35 @@ For example::
 No matter which database backend we are using, this will mean that ``syncdb``
 and other SQL commands create the right column type for storing a string.
 
-If ``get_internal_type()`` returns a string that is not known to Django for
+If :meth:`get_internal_type` returns a string that is not known to Django for
 the database backend you are using -- that is, it doesn't appear in
-``django.db.backends.<db_name>.creation.DATA_TYPES`` -- the string will still
-be used by the serializer, but the default ``db_type()`` method will return
-``None``. See the documentation of ``db_type()`` above_ for reasons why this
-might be useful. Putting a descriptive string in as the type of the field for
-the serializer is a useful idea if you're ever going to be using the
-serializer output in some other place, outside of Django.
-
-.. _above: #db-type-self
+``django.db.backends.<db_name>.creation.DATA_TYPES`` -- the string will still be
+used by the serializer, but the default :meth:`db_type` method will return
+``None``. See the documentation of :meth:`db_type` for reasons why this might be
+useful. Putting a descriptive string in as the type of the field for the
+serializer is a useful idea if you're ever going to be using the serializer
+output in some other place, outside of Django.
+
+Converting field data for serialization
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-``flatten_data(self, follow, obj=None)``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.. method:: flatten_data(self, follow, obj=None)
 
 .. admonition:: Subject to change
 
     Although implementing this method is necessary to allow field
     serialization, the API might change in the future.
 
-Returns a dictionary, mapping the field's attribute name to a
-flattened string version of the data. This method has some internal
-uses that aren't of interest to use here (mostly having to do with
-forms). For our purposes, it's sufficient to return a one item
-dictionary that maps the attribute name to a string.
+Returns a dictionary, mapping the field's attribute name to a flattened string
+version of the data. This method has some internal uses that aren't of interest
+to use here (mostly having to do with forms). For our purposes, it's sufficient
+to return a one item dictionary that maps the attribute name to a string.
 
 This method is used by the serializers to convert the field into a string for
-output. You can ignore the input parameters for serialization purposes,
-although calling ``Field._get_val_from_obj(obj)`` is the best way to get the
-value to serialize.
+output. You can ignore the input parameters for serialization purposes, although
+calling :meth:`Field._get_val_from_obj(obj)
+<django.db.models.Field._get_val_from_obj>` is the best way to get the value to
+serialize.
 
 For example, since our ``HandField`` uses strings for its data storage anyway,
 we can reuse some existing conversion code::
@@ -584,17 +606,19 @@ serialization formats. Here are a couple of tips to make things go more
 smoothly:
 
     1. Look at the existing Django fields (in
-       ``django/db/models/fields/__init__.py``) for inspiration. Try to find a
-       field that's similar to what you want and extend it a little bit,
+       :file:`django/db/models/fields/__init__.py`) for inspiration. Try to find
+       a field that's similar to what you want and extend it a little bit,
        instead of creating an entirely new field from scratch.
 
-    2. Put a ``__str__()`` or ``__unicode__()`` method on the class you're
+    2. Put a :meth:`__str__` or :meth:`__unicode__` method on the class you're
        wrapping up as a field. There are a lot of places where the default
-       behavior of the field code is to call ``force_unicode()`` on the value.
-       (In our examples in this document, ``value`` would be a ``Hand``
-       instance, not a ``HandField``). So if your ``__unicode__()`` method
-       automatically converts to the string form of your Python object, you can
-       save yourself a lot of work.
+       behavior of the field code is to call
+       :func:`~django.utils.encoding.force_unicode` on the value. (In our
+       examples in this document, ``value`` would be a ``Hand`` instance, not a
+       ``HandField``). So if your :meth:`__unicode__` method automatically
+       converts to the string form of your Python object, you can save yourself
+       a lot of work.
+
 
 Writing a ``FileField`` subclass
 =================================
@@ -606,17 +630,15 @@ retrieval, can remain unchanged, leaving subclasses to deal with the challenge
 of supporting a particular type of file.
 
 Django provides a ``File`` class, which is used as a proxy to the file's
-contents and operations. This can be subclassed to customzie hwo the file is
+contents and operations. This can be subclassed to customize how the file is
 accessed, and what methods are available. It lives at
 ``django.db.models.fields.files``, and its default behavior is explained in the
-`file documentation`_.
+:ref:`file documentation <ref-files-file>`.
 
 Once a subclass of ``File`` is created, the new ``FileField`` subclass must be
 told to use it. To do so, simply assign the new ``File`` subclass to the special
 ``attr_class`` attribute of the ``FileField`` subclass.
 
-.. _file documentation: ../files/
-
 A few suggestions
 ------------------
 

+ 78 - 664
docs/templates_python.txt → docs/howto/custom-template-tags.txt

@@ -1,634 +1,61 @@
-====================================================
-The Django template language: For Python programmers
-====================================================
+.. _howto-custom-template-tags:
 
-This document explains the Django template system from a technical
-perspective -- how it works and how to extend it. If you're just looking for
-reference on the language syntax, see
-`The Django template language: For template authors`_.
+================================
+Custom template tags and filters
+================================
 
-If you're looking to use the Django template system as part of another
-application -- i.e., without the rest of the framework -- make sure to read
-the `configuration`_ section later in this document.
+Introduction
+============
 
-.. _`The Django template language: For template authors`: ../templates/
+Django's template system comes a wide variety of :ref:`built-in tags and filters
+<ref-templates-builtins>` designed to address the presentation logic needs of
+your application. Nevertheless, you may find yourself needing functionality that
+is not covered by the core set of template primitives. You can extend the
+template engine by defining custom tags and filters using Python, and then make
+them available to your templates using the ``{% load %}`` tag.
 
-Basics
-======
+Code layout
+-----------
 
-A **template** is a text document, or a normal Python string, that is marked-up
-using the Django template language. A template can contain **block tags** or
-**variables**.
+Custom template tags and filters must live inside a Django app. If they relate
+to an existing app it makes sense to bundle them there; otherwise, you should
+create a new app to hold them.
 
-A **block tag** is a symbol within a template that does something.
+The app should contain a ``templatetags`` directory, at the same level as
+``models.py``, ``views.py``, etc. If this doesn't already exist, create it -
+don't forget the ``__init__.py`` file to ensure the directory is treated as a
+Python package.
 
-This definition is deliberately vague. For example, a block tag can output
-content, serve as a control structure (an "if" statement or "for" loop), grab
-content from a database or enable access to other template tags.
+Your custom tags and filters will live in a module inside the ``templatetags``
+directory. The name of the module file is the name you'll use to load the tags
+later, so be careful to pick a name that won't clash with custom tags and
+filters in another app.
 
-Block tags are surrounded by ``"{%"`` and ``"%}"``.
-
-Example template with block tags::
-
-    {% if is_logged_in %}Thanks for logging in!{% else %}Please log in.{% endif %}
-
-A **variable** is a symbol within a template that outputs a value.
-
-Variable tags are surrounded by ``"{{"`` and ``"}}"``.
-
-Example template with variables::
-
-    My first name is {{ first_name }}. My last name is {{ last_name }}.
-
-A **context** is a "variable name" -> "variable value" mapping that is passed
-to a template.
-
-A template **renders** a context by replacing the variable "holes" with values
-from the context and executing all block tags.
-
-Using the template system
-=========================
-
-Using the template system in Python is a two-step process:
-
-    * First, you compile the raw template code into a ``Template`` object.
-    * Then, you call the ``render()`` method of the ``Template`` object with a
-      given context.
-
-Compiling a string
-------------------
-
-The easiest way to create a ``Template`` object is by instantiating it
-directly. The class lives at ``django.template.Template``. The constructor
-takes one argument -- the raw template code::
-
-    >>> from django.template import Template
-    >>> t = Template("My name is {{ my_name }}.")
-    >>> print t
-    <django.template.Template instance>
-
-.. admonition:: Behind the scenes
-
-    The system only parses your raw template code once -- when you create the
-    ``Template`` object. From then on, it's stored internally as a "node"
-    structure for performance.
-
-    Even the parsing itself is quite fast. Most of the parsing happens via a
-    single call to a single, short, regular expression.
-
-Rendering a context
--------------------
-
-Once you have a compiled ``Template`` object, you can render a context -- or
-multiple contexts -- with it. The ``Context`` class lives at
-``django.template.Context``, and the constructor takes one (optional)
-argument: a dictionary mapping variable names to variable values. Call the
-``Template`` object's ``render()`` method with the context to "fill" the
-template::
-
-    >>> from django.template import Context, Template
-    >>> t = Template("My name is {{ my_name }}.")
-
-    >>> c = Context({"my_name": "Adrian"})
-    >>> t.render(c)
-    "My name is Adrian."
-
-    >>> c = Context({"my_name": "Dolores"})
-    >>> t.render(c)
-    "My name is Dolores."
-
-Variable names must consist of any letter (A-Z), any digit (0-9), an underscore
-or a dot.
-
-Dots have a special meaning in template rendering. A dot in a variable name
-signifies **lookup**. Specifically, when the template system encounters a dot
-in a variable name, it tries the following lookups, in this order:
-
-    * Dictionary lookup. Example: ``foo["bar"]``
-    * Attribute lookup. Example: ``foo.bar``
-    * Method call. Example: ``foo.bar()``
-    * List-index lookup. Example: ``foo[bar]``
-
-The template system uses the first lookup type that works. It's short-circuit
-logic.
-
-Here are a few examples::
-
-    >>> from django.template import Context, Template
-    >>> t = Template("My name is {{ person.first_name }}.")
-    >>> d = {"person": {"first_name": "Joe", "last_name": "Johnson"}}
-    >>> t.render(Context(d))
-    "My name is Joe."
-
-    >>> class PersonClass: pass
-    >>> p = PersonClass()
-    >>> p.first_name = "Ron"
-    >>> p.last_name = "Nasty"
-    >>> t.render(Context({"person": p}))
-    "My name is Ron."
-
-    >>> class PersonClass2:
-    ...     def first_name(self):
-    ...         return "Samantha"
-    >>> p = PersonClass2()
-    >>> t.render(Context({"person": p}))
-    "My name is Samantha."
-
-    >>> t = Template("The first stooge in the list is {{ stooges.0 }}.")
-    >>> c = Context({"stooges": ["Larry", "Curly", "Moe"]})
-    >>> t.render(c)
-    "The first stooge in the list is Larry."
-
-Method lookups are slightly more complex than the other lookup types. Here are
-some things to keep in mind:
-
-    * If, during the method lookup, a method raises an exception, the exception
-      will be propagated, unless the exception has an attribute
-      ``silent_variable_failure`` whose value is ``True``. If the exception
-      *does* have a ``silent_variable_failure`` attribute, the variable will
-      render as an empty string. Example::
-
-        >>> t = Template("My name is {{ person.first_name }}.")
-        >>> class PersonClass3:
-        ...     def first_name(self):
-        ...         raise AssertionError, "foo"
-        >>> p = PersonClass3()
-        >>> t.render(Context({"person": p}))
-        Traceback (most recent call last):
-        ...
-        AssertionError: foo
-
-        >>> class SilentAssertionError(Exception):
-        ...     silent_variable_failure = True
-        >>> class PersonClass4:
-        ...     def first_name(self):
-        ...         raise SilentAssertionError
-        >>> p = PersonClass4()
-        >>> t.render(Context({"person": p}))
-        "My name is ."
-
-      Note that ``django.core.exceptions.ObjectDoesNotExist``, which is the
-      base class for all Django database API ``DoesNotExist`` exceptions, has
-      ``silent_variable_failure = True``. So if you're using Django templates
-      with Django model objects, any ``DoesNotExist`` exception will fail
-      silently.
-
-    * A method call will only work if the method has no required arguments.
-      Otherwise, the system will move to the next lookup type (list-index
-      lookup).
-
-    * Obviously, some methods have side effects, and it'd be either foolish or
-      a security hole to allow the template system to access them.
-
-      A good example is the ``delete()`` method on each Django model object.
-      The template system shouldn't be allowed to do something like this::
-
-        I will now delete this valuable data. {{ data.delete }}
-
-      To prevent this, set a function attribute ``alters_data`` on the method.
-      The template system won't execute a method if the method has
-      ``alters_data=True`` set. The dynamically-generated ``delete()`` and
-      ``save()`` methods on Django model objects get ``alters_data=True``
-      automatically. Example::
-
-        def sensitive_function(self):
-            self.database_record.delete()
-        sensitive_function.alters_data = True
-
-How invalid variables are handled
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Generally, if a variable doesn't exist, the template system inserts the
-value of the ``TEMPLATE_STRING_IF_INVALID`` setting, which is set to ``''``
-(the empty string) by default.
-
-Filters that are applied to an invalid variable will only be applied if
-``TEMPLATE_STRING_IF_INVALID`` is set to ``''`` (the empty string). If
-``TEMPLATE_STRING_IF_INVALID`` is set to any other value, variable
-filters will be ignored.
-
-This behavior is slightly different for the ``if``, ``for`` and ``regroup``
-template tags. If an invalid variable is provided to one of these template
-tags, the variable will be interpreted as ``None``. Filters are always
-applied to invalid variables within these template tags.
-
-If ``TEMPLATE_STRING_IF_INVALID`` contains a ``'%s'``, the format marker will
-be replaced with the name of the invalid variable.
-
-.. admonition:: For debug purposes only!
-
-    While ``TEMPLATE_STRING_IF_INVALID`` can be a useful debugging tool,
-    it is a bad idea to turn it on as a 'development default'.
-
-    Many templates, including those in the Admin site, rely upon the
-    silence of the template system when a non-existent variable is
-    encountered. If you assign a value other than ``''`` to
-    ``TEMPLATE_STRING_IF_INVALID``, you will experience rendering
-    problems with these templates and sites.
-
-    Generally, ``TEMPLATE_STRING_IF_INVALID`` should only be enabled
-    in order to debug a specific template problem, then cleared
-    once debugging is complete.
-
-Playing with Context objects
-----------------------------
-
-Most of the time, you'll instantiate ``Context`` objects by passing in a
-fully-populated dictionary to ``Context()``. But you can add and delete items
-from a ``Context`` object once it's been instantiated, too, using standard
-dictionary syntax::
-
-    >>> c = Context({"foo": "bar"})
-    >>> c['foo']
-    'bar'
-    >>> del c['foo']
-    >>> c['foo']
-    ''
-    >>> c['newvariable'] = 'hello'
-    >>> c['newvariable']
-    'hello'
-
-A ``Context`` object is a stack. That is, you can ``push()`` and ``pop()`` it.
-If you ``pop()`` too much, it'll raise
-``django.template.ContextPopException``::
-
-    >>> c = Context()
-    >>> c['foo'] = 'first level'
-    >>> c.push()
-    >>> c['foo'] = 'second level'
-    >>> c['foo']
-    'second level'
-    >>> c.pop()
-    >>> c['foo']
-    'first level'
-    >>> c['foo'] = 'overwritten'
-    >>> c['foo']
-    'overwritten'
-    >>> c.pop()
-    Traceback (most recent call last):
-    ...
-    django.template.ContextPopException
-
-Using a ``Context`` as a stack comes in handy in some custom template tags, as
-you'll see below.
-
-Subclassing Context: RequestContext
------------------------------------
-
-Django comes with a special ``Context`` class,
-``django.template.RequestContext``, that acts slightly differently than
-the normal ``django.template.Context``. The first difference is that it takes
-an `HttpRequest object`_ as its first argument. For example::
-
-    c = RequestContext(request, {
-        'foo': 'bar',
-    }
-
-The second difference is that it automatically populates the context with a few
-variables, according to your `TEMPLATE_CONTEXT_PROCESSORS setting`_.
-
-The ``TEMPLATE_CONTEXT_PROCESSORS`` setting is a tuple of callables -- called
-**context processors** -- that take a request object as their argument and
-return a dictionary of items to be merged into the context. By default,
-``TEMPLATE_CONTEXT_PROCESSORS`` is set to::
-
-    ("django.core.context_processors.auth",
-    "django.core.context_processors.debug",
-    "django.core.context_processors.i18n",
-    "django.core.context_processors.media")
-
-Each processor is applied in order. That means, if one processor adds a
-variable to the context and a second processor adds a variable with the same
-name, the second will override the first. The default processors are explained
-below.
-
-Also, you can give ``RequestContext`` a list of additional processors, using the
-optional, third positional argument, ``processors``. In this example, the
-``RequestContext`` instance gets a ``ip_address`` variable::
-
-    def ip_address_processor(request):
-        return {'ip_address': request.META['REMOTE_ADDR']}
-
-    def some_view(request):
-        # ...
-        c = RequestContext(request, {
-            'foo': 'bar',
-        }, [ip_address_processor])
-        return t.render(c)
-
-.. note::
-    If you're using Django's ``render_to_response()`` shortcut to populate a
-    template with the contents of a dictionary, your template will be passed a
-    ``Context`` instance by default (not a ``RequestContext``). To use a
-    ``RequestContext`` in your template rendering, pass an optional third
-    argument to ``render_to_response()``: a ``RequestContext``
-    instance. Your code might look like this::
-
-        def some_view(request):
-            # ...
-            return render_to_response('my_template.html',
-                                      my_data_dictionary,
-                                      context_instance=RequestContext(request))
-
-Here's what each of the default processors does:
-
-.. _HttpRequest object: ../request_response/#httprequest-objects
-.. _TEMPLATE_CONTEXT_PROCESSORS setting: ../settings/#template-context-processors
-
-django.core.context_processors.auth
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-If ``TEMPLATE_CONTEXT_PROCESSORS`` contains this processor, every
-``RequestContext`` will contain these three variables:
-
-    * ``user`` -- An ``auth.User`` instance representing the currently
-      logged-in user (or an ``AnonymousUser`` instance, if the client isn't
-      logged in). See the `user authentication docs`_.
-
-    * ``messages`` -- A list of messages (as strings) for the currently
-      logged-in user. Behind the scenes, this calls
-      ``request.user.get_and_delete_messages()`` for every request. That method
-      collects the user's messages and deletes them from the database.
-
-      Note that messages are set with ``user.message_set.create``. See the
-      `message docs`_ for more.
-
-    * ``perms`` -- An instance of
-      ``django.core.context_processors.PermWrapper``, representing the
-      permissions that the currently logged-in user has. See the `permissions
-      docs`_.
-
-.. _user authentication docs: ../authentication/#users
-.. _message docs: ../authentication/#messages
-.. _permissions docs: ../authentication/#permissions
-
-django.core.context_processors.debug
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-If ``TEMPLATE_CONTEXT_PROCESSORS`` contains this processor, every
-``RequestContext`` will contain these two variables -- but only if your
-``DEBUG`` setting is set to ``True`` and the request's IP address
-(``request.META['REMOTE_ADDR']``) is in the ``INTERNAL_IPS`` setting:
-
-    * ``debug`` -- ``True``. You can use this in templates to test whether
-      you're in ``DEBUG`` mode.
-    * ``sql_queries`` -- A list of ``{'sql': ..., 'time': ...}`` dictionaries,
-      representing every SQL query that has happened so far during the request
-      and how long it took. The list is in order by query.
-
-django.core.context_processors.i18n
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-If ``TEMPLATE_CONTEXT_PROCESSORS`` contains this processor, every
-``RequestContext`` will contain these two variables:
-
-    * ``LANGUAGES`` -- The value of the `LANGUAGES setting`_.
-    * ``LANGUAGE_CODE`` -- ``request.LANGUAGE_CODE``, if it exists. Otherwise,
-      the value of the `LANGUAGE_CODE setting`_.
-
-See the `internationalization docs`_ for more.
-
-.. _LANGUAGES setting: ../settings/#languages
-.. _LANGUAGE_CODE setting: ../settings/#language-code
-.. _internationalization docs: ../i18n/
-
-django.core.context_processors.media
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-**New in Django development version**
-
-If ``TEMPLATE_CONTEXT_PROCESSORS`` contains this processor, every
-``RequestContext`` will contain a variable ``MEDIA_URL``, providing the
-value of the `MEDIA_URL setting`_.
-
-.. _MEDIA_URL setting: ../settings/#media-url
-
-django.core.context_processors.request
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-If ``TEMPLATE_CONTEXT_PROCESSORS`` contains this processor, every
-``RequestContext`` will contain a variable ``request``, which is the current
-`HttpRequest object`_. Note that this processor is not enabled by default;
-you'll have to activate it.
-
-Writing your own context processors
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-A context processor has a very simple interface: It's just a Python function
-that takes one argument, an ``HttpRequest`` object, and returns a dictionary
-that gets added to the template context. Each context processor *must* return
-a dictionary.
-
-Custom context processors can live anywhere in your code base. All Django cares
-about is that your custom context processors are pointed-to by your
-``TEMPLATE_CONTEXT_PROCESSORS`` setting.
-
-Loading templates
------------------
-
-Generally, you'll store templates in files on your filesystem rather than using
-the low-level ``Template`` API yourself. Save templates in a directory
-specified as a **template directory**.
-
-Django searches for template directories in a number of places, depending on
-your template-loader settings (see "Loader types" below), but the most basic
-way of specifying template directories is by using the ``TEMPLATE_DIRS``
-setting.
-
-The TEMPLATE_DIRS setting
-~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Tell Django what your template directories are by using the ``TEMPLATE_DIRS``
-setting in your settings file. This should be set to a list or tuple of strings
-that contain full paths to your template directory(ies). Example::
-
-    TEMPLATE_DIRS = (
-        "/home/html/templates/lawrence.com",
-        "/home/html/templates/default",
-    )
-
-Your templates can go anywhere you want, as long as the directories and
-templates are readable by the Web server. They can have any extension you want,
-such as ``.html`` or ``.txt``, or they can have no extension at all.
-
-Note that these paths should use Unix-style forward slashes, even on Windows.
-
-The Python API
-~~~~~~~~~~~~~~
-
-Django has two ways to load templates from files:
-
-``django.template.loader.get_template(template_name)``
-    ``get_template`` returns the compiled template (a ``Template`` object) for
-    the template with the given name. If the template doesn't exist, it raises
-    ``django.template.TemplateDoesNotExist``.
-
-``django.template.loader.select_template(template_name_list)``
-    ``select_template`` is just like ``get_template``, except it takes a list
-    of template names. Of the list, it returns the first template that exists.
-
-For example, if you call ``get_template('story_detail.html')`` and have the
-above ``TEMPLATE_DIRS`` setting, here are the files Django will look for, in
-order:
-
-    * ``/home/html/templates/lawrence.com/story_detail.html``
-    * ``/home/html/templates/default/story_detail.html``
-
-If you call ``select_template(['story_253_detail.html', 'story_detail.html'])``,
-here's what Django will look for:
-
-    * ``/home/html/templates/lawrence.com/story_253_detail.html``
-    * ``/home/html/templates/default/story_253_detail.html``
-    * ``/home/html/templates/lawrence.com/story_detail.html``
-    * ``/home/html/templates/default/story_detail.html``
-
-When Django finds a template that exists, it stops looking.
-
-.. admonition:: Tip
-
-    You can use ``select_template()`` for super-flexible "templatability." For
-    example, if you've written a news story and want some stories to have
-    custom templates, use something like
-    ``select_template(['story_%s_detail.html' % story.id, 'story_detail.html'])``.
-    That'll allow you to use a custom template for an individual story, with a
-    fallback template for stories that don't have custom templates.
-
-Using subdirectories
-~~~~~~~~~~~~~~~~~~~~
-
-It's possible -- and preferable -- to organize templates in subdirectories of
-the template directory. The convention is to make a subdirectory for each
-Django app, with subdirectories within those subdirectories as needed.
-
-Do this for your own sanity. Storing all templates in the root level of a
-single directory gets messy.
-
-To load a template that's within a subdirectory, just use a slash, like so::
-
-    get_template('news/story_detail.html')
-
-Using the same ``TEMPLATE_DIRS`` setting from above, this example
-``get_template()`` call will attempt to load the following templates:
-
-    * ``/home/html/templates/lawrence.com/news/story_detail.html``
-    * ``/home/html/templates/default/news/story_detail.html``
-
-Loader types
-~~~~~~~~~~~~
-
-By default, Django uses a filesystem-based template loader, but Django comes
-with a few other template loaders, which know how to load templates from other
-sources.
-
-These other loaders are disabled by default, but you can activate them by
-editing your ``TEMPLATE_LOADERS`` setting. ``TEMPLATE_LOADERS`` should be a
-tuple of strings, where each string represents a template loader. Here are the
-template loaders that come with Django:
-
-``django.template.loaders.filesystem.load_template_source``
-    Loads templates from the filesystem, according to ``TEMPLATE_DIRS``.
-
-``django.template.loaders.app_directories.load_template_source``
-    Loads templates from Django apps on the filesystem. For each app in
-    ``INSTALLED_APPS``, the loader looks for a ``templates`` subdirectory. If
-    the directory exists, Django looks for templates in there.
-
-    This means you can store templates with your individual apps. This also
-    makes it easy to distribute Django apps with default templates.
-
-    For example, for this setting::
-
-        INSTALLED_APPS = ('myproject.polls', 'myproject.music')
-
-    ...then ``get_template('foo.html')`` will look for templates in these
-    directories, in this order:
-
-        * ``/path/to/myproject/polls/templates/foo.html``
-        * ``/path/to/myproject/music/templates/foo.html``
-
-    Note that the loader performs an optimization when it is first imported:
-    It caches a list of which ``INSTALLED_APPS`` packages have a ``templates``
-    subdirectory.
-
-``django.template.loaders.eggs.load_template_source``
-    Just like ``app_directories`` above, but it loads templates from Python
-    eggs rather than from the filesystem.
-
-Django uses the template loaders in order according to the ``TEMPLATE_LOADERS``
-setting. It uses each loader until a loader finds a match.
-
-The ``render_to_string()`` shortcut
-===================================
-
-To cut down on the repetitive nature of loading and rendering
-templates, Django provides a shortcut function which largely
-automates the process: ``render_to_string()`` in
-``django.template.loader``, which loads a template, renders it and
-returns the resulting string::
-
-    from django.template.loader import render_to_string
-    rendered = render_to_string('my_template.html', { 'foo': 'bar' })
-
-The ``render_to_string`` shortcut takes one required argument --
-``template_name``, which should be the name of the template to load
-and render -- and two optional arguments::
-
-    dictionary
-        A dictionary to be used as variables and values for the
-        template's context. This can also be passed as the second
-        positional argument.
-
-    context_instance
-        An instance of ``Context`` or a subclass (e.g., an instance of
-        ``RequestContext``) to use as the template's context. This can
-        also be passed as the third positional argument.
-
-See also the `render_to_response()`_ shortcut, which calls
-``render_to_string`` and feeds the result into an ``HttpResponse``
-suitable for returning directly from a view.
-
-.. _render_to_response(): ../shortcuts/#render-to-response
-
-Extending the template system
-=============================
-
-Although the Django template language comes with several default tags and
-filters, you might want to write your own. It's easy to do.
-
-First, create a ``templatetags`` package in the appropriate Django app's
-package. It should be on the same level as ``models.py``, ``views.py``, etc. For
-example::
+For example, if your custom tags/filters are in a file called
+``poll_extras.py``, your app layout might look like this::
 
     polls/
         models.py
         templatetags/
+            __init__.py
+            poll_extras.py
         views.py
 
-Add two files to the ``templatetags`` package: an ``__init__.py`` file and a
-file that will contain your custom tag/filter definitions. The name of the
-latter file is the name you'll use to load the tags later. For example, if your
-custom tags/filters are in a file called ``poll_extras.py``, you'd do the
-following in a template::
+And in your template you would use the following:
 
-    {% load poll_extras %}
+.. code-block:: html+django
 
-The ``{% load %}`` tag looks at your ``INSTALLED_APPS`` setting and only allows
-the loading of template libraries within installed Django apps. This is a
-security feature: It allows you to host Python code for many template libraries
-on a single computer without enabling access to all of them for every Django
-installation.
+    {% load poll_extras %}
 
-If you write a template library that isn't tied to any particular models/views,
-it's perfectly OK to have a Django app package that only contains a
-``templatetags`` package.
+The app that contains the custom tags must be in :setting:`INSTALLED_APPS` in
+order for the ``{% load %}`` tag to work. This is a security feature: It allows
+you to host Python code for many template libraries on a single host machine
+without enabling access to all of them for every Django installation.
 
 There's no limit on how many modules you put in the ``templatetags`` package.
 Just keep in mind that a ``{% load %}`` statement will load tags/filters for
 the given Python module name, not the name of the app.
 
-Once you've created that Python module, you'll just have to write a bit of
-Python code, depending on whether you're writing filters or tags.
-
 To be a valid tag library, the module must contain a module-level variable
 named ``register`` that is a ``template.Library`` instance, in which all the
 tags and filters are registered. So, near the top of your module, put the
@@ -666,7 +93,9 @@ Here's an example filter definition::
         "Removes all values of arg from the given string"
         return value.replace(arg, '')
 
-And here's an example of how that filter would be used::
+And here's an example of how that filter would be used:
+
+.. code-block:: html+django
 
     {{ somevariable|cut:"0" }}
 
@@ -790,10 +219,10 @@ Template filter code falls into one of two situations:
        the result (aside from any that were already present), you should mark
        your filter with ``is_safe``::
 
-        @register.filter
-        def add_xx(value):
-            return '%sxx' % value
-        add_xx.is_safe = True
+           @register.filter
+           def add_xx(value):
+               return '%sxx' % value
+           add_xx.is_safe = True
 
        When this filter is used in a template where auto-escaping is enabled,
        Django will escape the output whenever the input is not already marked as
@@ -818,7 +247,8 @@ Template filter code falls into one of two situations:
        escaping so that your HTML markup isn't escaped further, so you'll need
        to handle the input yourself.
 
-       To mark the output as a safe string, use ``django.utils.safestring.mark_safe()``.
+       To mark the output as a safe string, use
+       :func:`django.utils.safestring.mark_safe`.
 
        Be careful, though. You need to do more than just mark the output as
        safe. You need to ensure it really *is* safe, and what you do depends on
@@ -852,9 +282,9 @@ Template filter code falls into one of two situations:
        The ``needs_autoescape`` attribute on the filter function and the
        ``autoescape`` keyword argument mean that our function will know whether
        automatic escaping is in effect when the filter is called. We use
-       ``autoescape`` to decide whether the input data needs to be passed through
-       ``django.utils.html.conditional_escape`` or not. (In the latter case, we
-       just use the identity function as the "escape" function.) The
+       ``autoescape`` to decide whether the input data needs to be passed
+       through ``django.utils.html.conditional_escape`` or not. (In the latter
+       case, we just use the identity function as the "escape" function.) The
        ``conditional_escape()`` function is like ``escape()`` except it only
        escapes input that is **not** a ``SafeData`` instance. If a ``SafeData``
        instance is passed to ``conditional_escape()``, the data is returned
@@ -902,7 +332,9 @@ responsible for returning a ``Node`` instance based on the contents of the tag.
 For example, let's write a template tag, ``{% current_time %}``, that displays
 the current date/time, formatted according to a parameter given in the tag, in
 `strftime syntax`_. It's a good idea to decide the tag syntax before anything
-else. In our case, let's say the tag should be used like this::
+else. In our case, let's say the tag should be used like this:
+
+.. code-block:: html+django
 
     <p>The time is {% current_time "%Y-%m-%d %I:%M %p" %}.</p>
 
@@ -1064,7 +496,9 @@ content (a template variable) to a template tag as an argument.
 
 While the previous examples have formatted the current time into a string and
 returned the string, suppose you wanted to pass in a ``DateTimeField`` from an
-object and have the template tag format that date-time::
+object and have the template tag format that date-time:
+
+.. code-block:: html+django
 
     <p>This post was last updated at {% format_time blog_entry.date_updated "%Y-%m-%d %I:%M %p" %}.</p>
 
@@ -1174,7 +608,7 @@ In Python 2.4, the decorator syntax also works::
 
 A couple of things to note about the ``simple_tag`` helper function:
 
-    * Checking for the required number of arguments, etc, has already been
+    * Checking for the required number of arguments, etc., has already been
       done by the time our function is called, so we don't need to do that.
     * The quotes around the argument (if any) have already been stripped away,
       so we just receive a plain string.
@@ -1200,11 +634,15 @@ These sorts of tags are called "inclusion tags".
 
 Writing inclusion tags is probably best demonstrated by example. Let's write a
 tag that outputs a list of choices for a given ``Poll`` object, such as was
-created in the tutorials_. We'll use the tag like this::
+created in the :ref:`tutorials <creating-models>`. We'll use the tag like this:
+
+.. code-block:: html+django
 
     {% show_results poll %}
 
-...and the output will be something like this::
+...and the output will be something like this:
+
+.. code-block:: html
 
     <ul>
       <li>First choice</li>
@@ -1223,7 +661,9 @@ for the template fragment. Example::
 
 Next, create the template used to render the tag's output. This template is a
 fixed feature of the tag: the tag writer specifies it, not the template
-designer. Following our example, the template is very simple::
+designer. Following our example, the template is very simple:
+
+.. code-block:: html+django
 
     <ul>
     {% for choice in choices %}
@@ -1272,13 +712,17 @@ back to the main page. Here's what the Python function would look like::
 
 In that ``register.inclusion_tag()`` line, we specified ``takes_context=True``
 and the name of the template. Here's what the template ``link.html`` might look
-like::
+like:
+
+.. code-block:: html+django
 
     Jump directly to <a href="{{ link }}">{{ title }}</a>.
 
 Then, any time you want to use that custom tag, load its library and call it
 without any arguments, like so::
 
+.. code-block:: html+django
+
     {% jump_link %}
 
 Note that when you're using ``takes_context=True``, there's no need to pass
@@ -1288,8 +732,6 @@ The ``takes_context`` parameter defaults to ``False``. When it's set to *True*,
 the tag is passed the context object, as in this example. That's the only
 difference between this case and the previous ``inclusion_tag`` example.
 
-.. _tutorials: ../tutorial01/#creating-models
-
 Setting a variable in the context
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -1313,7 +755,9 @@ Note that ``render()`` returns the empty string. ``render()`` should always
 return string output. If all the template tag does is set a variable,
 ``render()`` should return the empty string.
 
-Here's how you'd use this new version of the tag::
+Here's how you'd use this new version of the tag:
+
+.. code-block:: html+django
 
     {% current_time "%Y-%M-%d %I:%M %p" %}<p>The time is {{ current_time }}.</p>
 
@@ -1322,7 +766,9 @@ But, there's a problem with ``CurrentTimeNode2``: The variable name
 template doesn't use ``{{ current_time }}`` anywhere else, because the
 ``{% current_time %}`` will blindly overwrite that variable's value. A cleaner
 solution is to make the template tag specify the name of the output variable,
-like so::
+like so:
+
+.. code-block:: html+django
 
     {% get_current_time "%Y-%M-%d %I:%M %p" as my_current_time %}
     <p>The current time is {{ my_current_time }}.</p>
@@ -1402,7 +848,9 @@ possible to do something with the code between block tags.
 For example, here's a custom template tag, ``{% upper %}``, that capitalizes
 everything between itself and ``{% endupper %}``.
 
-Usage::
+Usage:
+
+.. code-block:: html+django
 
     {% upper %}This will appear in uppercase, {{ your_name }}.{% endupper %}
 
@@ -1427,37 +875,3 @@ The only new concept here is the ``self.nodelist.render(context)`` in
 For more examples of complex rendering, see the source code for ``{% if %}``,
 ``{% for %}``, ``{% ifequal %}`` and ``{% ifchanged %}``. They live in
 ``django/template/defaulttags.py``.
-
-.. _configuration:
-
-Configuring the template system in standalone mode
-==================================================
-
-.. note::
-
-    This section is only of interest to people trying to use the template
-    system as an output component in another application. If you're using the
-    template system as part of a Django application, nothing here applies to
-    you.
-
-Normally, Django will load all the configuration information it needs from its
-own default configuration file, combined with the settings in the module given
-in the ``DJANGO_SETTINGS_MODULE`` environment variable. But if you're using the
-template system independently of the rest of Django, the environment variable
-approach isn't very convenient, because you probably want to configure the
-template system in line with the rest of your application rather than dealing
-with settings files and pointing to them via environment variables.
-
-To solve this problem, you need to use the manual configuration option
-described in the `settings file`_ documentation. Simply import the appropriate
-pieces of the templating system and then, *before* you call any of the
-templating functions, call ``django.conf.settings.configure()`` with any
-settings you wish to specify. You might want to consider setting at least
-``TEMPLATE_DIRS`` (if you're going to use template loaders),
-``DEFAULT_CHARSET`` (although the default of ``utf-8`` is probably fine) and
-``TEMPLATE_DEBUG``. All available settings are described in the
-`settings documentation`_, and any setting starting with *TEMPLATE_*
-is of obvious interest.
-
-.. _settings file: ../settings/#using-settings-without-the-django-settings-module-environment-variable
-.. _settings documentation: ../settings/

+ 49 - 34
docs/fastcgi.txt → docs/howto/deployment/fastcgi.txt

@@ -1,17 +1,22 @@
+.. _howto-deployment-fastcgi:
+
 ===========================================
 How to use Django with FastCGI, SCGI or AJP
 ===========================================
 
-Although the `current preferred setup`_ for running Django is Apache_ with
-`mod_python`_, many people use shared hosting, on which protocols such as
-FastCGI, SCGI or AJP are the only viable options. In some setups, these protocols
-also allow better security -- and, possibly, better performance -- than mod_python.
+.. highlight:: bash
+
+Although the current preferred setup for running Django is :ref:`Apache with
+mod_python <howto-deployment-modpython>`, many people use shared hosting, on
+which protocols such as FastCGI, SCGI or AJP are the only viable options. In
+some setups, these protocols also allow better security -- and, possibly, better
+performance -- than mod_python_.
 
 .. admonition:: Note
 
     This document primarily focuses on FastCGI. Other protocols, such as SCGI
     and AJP, are also supported, through the ``flup`` Python package. See the
-    "Protocols" section below for specifics about SCGI and AJP.
+    Protocols_ section below for specifics about SCGI and AJP.
 
 Essentially, FastCGI is an efficient way of letting an external application
 serve pages to a Web server. The Web server delegates the incoming Web requests
@@ -19,12 +24,10 @@ serve pages to a Web server. The Web server delegates the incoming Web requests
 to the Web server, which, in turn, passes it back to the client's Web browser.
 
 Like mod_python, FastCGI allows code to stay in memory, allowing requests to be
-served with no startup time. Unlike mod_python (or `mod_perl`_), a FastCGI
+served with no startup time. Unlike mod_python_ (or `mod_perl`_), a FastCGI
 process doesn't run inside the Web server process, but in a separate,
 persistent process.
 
-.. _current preferred setup: ../modpython/
-.. _Apache: http://httpd.apache.org/
 .. _mod_python: http://www.modpython.org/
 .. _mod_perl: http://perl.apache.org/
 
@@ -45,9 +48,8 @@ persistent process.
 Prerequisite: flup
 ==================
 
-Before you can start using FastCGI with Django, you'll need to install flup_,
-which is a Python library for dealing with FastCGI. Version 0.5 or newer should
-work fine.
+Before you can start using FastCGI with Django, you'll need to install flup_, a
+Python library for dealing with FastCGI. Version 0.5 or newer should work fine.
 
 .. _flup: http://www.saddi.com/software/flup/
 
@@ -72,25 +74,27 @@ TCP socket. What you choose is a manner of preference; a TCP socket is usually
 easier due to permissions issues.
 
 To start your server, first change into the directory of your project (wherever
-your ``manage.py`` is), and then run ``manage.py`` with the ``runfcgi`` option::
+your :ref:`manage.py <ref-django-admin>` is), and then run the
+:djadmin:`runfcgi` command::
 
     ./manage.py runfcgi [options]
 
-If you specify ``help`` as the only option after ``runfcgi``, it'll display a
-list of all the available options.
+If you specify ``help`` as the only option after :djadmin:`runfcgi`, it'll
+display a list of all the available options.
 
-You'll need to specify either a ``socket``, ``protocol`` or both ``host`` and
-``port``. Then, when you set up your Web server, you'll just need to point it
-at the host/port or socket you specified when starting the FastCGI server.
+You'll need to specify either a ``socket``, a ``protocol`` or both ``host`` and
+``port``. Then, when you set up your Web server, you'll just need to point it at
+the host/port or socket you specified when starting the FastCGI server. See the
+examples_, below.
 
 Protocols
 ---------
 
 Django supports all the protocols that flup_ does, namely fastcgi_, `SCGI`_ and
 `AJP1.3`_ (the Apache JServ Protocol, version 1.3). Select your preferred
-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::
+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
 
@@ -122,8 +126,8 @@ Simply hitting ``Ctrl-C`` will stop and quit the FastCGI server. However, when
 you're dealing with background processes, you'll need to resort to the Unix
 ``kill`` command.
 
-If you specify the ``pidfile`` option to your ``manage.py runfcgi``, you can
-kill the running FastCGI daemon like this::
+If you specify the ``pidfile`` option to :djadmin:`runfcgi`, you can kill the
+running FastCGI daemon like this::
 
     kill `cat $PIDFILE`
 
@@ -170,7 +174,9 @@ Specifying the location of the FastCGI server
 
 The ``FastCGIExternalServer`` directive tells Apache how to find your FastCGI
 server. As the `FastCGIExternalServer docs`_ explain, you can specify either a
-``socket`` or a ``host``. Here are examples of both::
+``socket`` or a ``host``. Here are examples of both:
+
+.. code-block:: apache
 
     # Connect to FastCGI via a socket / named pipe.
     FastCGIExternalServer /home/user/public_html/mysite.fcgi -socket /home/user/mysite.sock
@@ -195,7 +201,9 @@ directive, as explained in the previous section).
 
 In this example, we tell Apache to use FastCGI to handle any request that
 doesn't represent a file on the filesystem and doesn't start with ``/media/``.
-This is probably the most common case, if you're using Django's admin site::
+This is probably the most common case, if you're using Django's admin site:
+
+.. code-block:: apache
 
     <VirtualHost 12.34.56.78>
       ServerName example.com
@@ -215,15 +223,19 @@ constructing URLs with the ``{% url %}`` template tag (and similar methods).
 lighttpd setup
 ==============
 
-lighttpd is a lightweight Web server commonly used for serving static files. It
+lighttpd_ is a lightweight Web server commonly used for serving static files. It
 supports FastCGI natively and, thus, is a good choice for serving both static
 and dynamic pages, if your site doesn't have any Apache-specific needs.
 
+.. _lighttpd: http://www.lighttpd.net/
+
 Make sure ``mod_fastcgi`` is in your modules list, somewhere after
 ``mod_rewrite`` and ``mod_access``, but not after ``mod_accesslog``. You'll
 probably want ``mod_alias`` as well, for serving admin media.
 
-Add the following to your lighttpd config file::
+Add the following to your lighttpd config file:
+
+.. code-block:: lua
 
     server.document-root = "/home/user/public_html"
     fastcgi.server = (
@@ -289,7 +301,9 @@ using Web server-spawned processes.
     there's no need for you to start the FastCGI server on your own. Apache
     will spawn a number of processes, scaling as it needs to.
 
-In your Web root directory, add this to a file named ``.htaccess`` ::
+In your Web root directory, add this to a file named ``.htaccess``:
+
+.. code-block:: apache
 
     AddHandler fastcgi-script .fcgi
     RewriteEngine On
@@ -298,7 +312,9 @@ In your Web root directory, add this to a file named ``.htaccess`` ::
 
 Then, create a small script that tells Apache how to spawn your FastCGI
 program. Create a file ``mysite.fcgi`` and place it in your Web directory, and
-be sure to make it executable::
+be sure to make it executable:
+
+.. code-block:: python
 
     #!/usr/bin/python
     import sys, os
@@ -332,12 +348,10 @@ easily by using the ``touch`` command::
 Serving admin media files
 =========================
 
-Regardless of the server and configuration you eventually decide to use, you will
-also need to give some thought to how to serve the admin media files. The
-advice given in the modpython_ documentation is also applicable in the setups
-detailed above.
-
-.. _modpython: ../modpython/#serving-the-admin-files
+Regardless of the server and configuration you eventually decide to use, you
+will also need to give some thought to how to serve the admin media files. The
+advice given in the :ref:`modpython <serving-the-admin-files>` documentation
+is also applicable in the setups detailed above.
 
 Forcing the URL prefix to a particular value
 ============================================
@@ -366,3 +380,4 @@ As an example of how to use it, if your Django configuration is serving all of
 the URLs under ``'/'`` and you wanted to use this setting, you would set
 ``FORCE_SCRIPT_NAME = ''`` in your settings file.
 
+

+ 33 - 0
docs/howto/deployment/index.txt

@@ -0,0 +1,33 @@
+.. _howto-deployment-index:
+
+Deploying Django
+================
+
+Django's chock-full of shortcuts to make web developer's lives easier, but all
+those tools are of no use if you can't easily deploy your sites. Since Django's
+inception, ease of deployment has been a major goal. There's a number of good
+ways to easily deploy Django:
+
+.. toctree::
+   :maxdepth: 1
+   
+   modpython
+   fastcgi
+   
+:ref:`Deploying under mod_python <howto-deployment-modpython>` is the
+recommended deployment method; start there if you're not sure which path you'd
+like to go down.
+
+.. seealso::
+
+    * `Chapter 20 of The Django Book`_ discusses deployment and especially
+      scaling in more detail.
+      
+    * `mod_wsgi`_ is a newcomer to the Python deployment world, but it's rapidly
+      gaining traction. Currently there's a few hoops you have to jump through to
+      `use mod_wsgi with Django`_, but mod_wsgi tends to get rave reviews from
+      those who use it.
+
+.. _chapter 20 of the django book: http://djangobook.com/en/1.0/chapter20/
+.. _mod_wsgi: http://code.google.com/p/modwsgi/
+.. _use mod_wsgi with Django: http://code.google.com/p/modwsgi/wiki/IntegrationWithDjango

+ 52 - 40
docs/modpython.txt → docs/howto/deployment/modpython.txt

@@ -1,27 +1,30 @@
-=================================
-How to use Django with mod_python
-=================================
+.. _howto-deployment-modpython:
+
+============================================
+How to use Django with Apache and mod_python
+============================================
+
+.. highlight:: apache
 
 Apache_ with `mod_python`_ currently is the preferred setup for using Django
 on a production server.
 
-mod_python is similar to `mod_perl`_ : It embeds Python within Apache and loads
-Python code into memory when the server starts. Code stays in memory throughout
-the life of an Apache process, which leads to significant performance gains over
-other server arrangements.
+mod_python is similar to (and inspired by) `mod_perl`_ : It embeds Python within
+Apache and loads Python code into memory when the server starts. Code stays in
+memory throughout the life of an Apache process, which leads to significant
+performance gains over other server arrangements.
 
 Django requires Apache 2.x and mod_python 3.x, and you should use Apache's
 `prefork MPM`_, as opposed to the `worker MPM`_.
 
-You may also be interested in `How to use Django with FastCGI, SCGI or AJP`_
-(which also covers SCGI and AJP).
+You may also be interested in :ref:`How to use Django with FastCGI, SCGI or AJP
+<howto-deployment-fastcgi>` (which also covers SCGI and AJP).
 
 .. _Apache: http://httpd.apache.org/
 .. _mod_python: http://www.modpython.org/
 .. _mod_perl: http://perl.apache.org/
 .. _prefork MPM: http://httpd.apache.org/docs/2.2/mod/prefork.html
 .. _worker MPM: http://httpd.apache.org/docs/2.2/mod/worker.html
-.. _How to use Django with FastCGI, SCGI or AJP: ../fastcgi/
 
 Basic configuration
 ===================
@@ -35,7 +38,7 @@ Then edit your ``httpd.conf`` file and add the following::
         SetHandler python-program
         PythonHandler django.core.handlers.modpython
         SetEnv DJANGO_SETTINGS_MODULE mysite.settings
-        PythonOption django.root /mysite
+        PythonOption django.root /mysite        
         PythonDebug On
     </Location>
 
@@ -43,8 +46,8 @@ Then edit your ``httpd.conf`` file and add the following::
 project's settings file.
 
 This tells Apache: "Use mod_python for any URL at or under '/mysite/', using the
-Django mod_python handler." It passes the value of ``DJANGO_SETTINGS_MODULE``
-so mod_python knows which settings to use.
+Django mod_python handler." It passes the value of :ref:`DJANGO_SETTINGS_MODULE
+<django-settings-module>` so mod_python knows which settings to use.
 
 **New in Django development version:** Because mod_python does not know we are
 serving this site from underneath the ``/mysite/`` prefix, this value needs to
@@ -78,27 +81,27 @@ computer, you'll have to tell mod_python where your project can be found:
         SetHandler python-program
         PythonHandler django.core.handlers.modpython
         SetEnv DJANGO_SETTINGS_MODULE mysite.settings
-        PythonOption django.root /mysite
+        PythonOption django.root /mysite        
         PythonDebug On
         **PythonPath "['/path/to/project'] + sys.path"**
     </Location>
 
 The value you use for ``PythonPath`` should include the parent directories of
 all the modules you are going to import in your application. It should also
-include the parent directory of the ``DJANGO_SETTINGS_MODULE`` location. This
-is exactly the same situation as setting the Python path for interactive
-usage. Whenever you try to import something, Python will run through all the
-directories in ``sys.path`` in turn, from first to last, and try to import
-from each directory until one succeeds.
+include the parent directory of the :ref:`DJANGO_SETTINGS_MODULE
+<django-settings-module>` location. This is exactly the same situation as
+setting the Python path for interactive usage. Whenever you try to import
+something, Python will run through all the directories in ``sys.path`` in turn,
+from first to last, and try to import from each directory until one succeeds.
 
-An example might make this clearer. Suppose
-you have some applications under ``/usr/local/django-apps/`` (for example,
-``/usr/local/django-apps/weblog/`` and so forth), your settings file is at
-``/var/www/mysite/settings.py`` and you have specified
-``DJANGO_SETTINGS_MODULE`` as in the above example. In this case, you would
-need to write your ``PythonPath`` directive as::
+An example might make this clearer. Suppose you have some applications under
+``/usr/local/django-apps/`` (for example, ``/usr/local/django-apps/weblog/`` and
+so forth), your settings file is at ``/var/www/mysite/settings.py`` and you have
+specified :ref:`DJANGO_SETTINGS_MODULE <django-settings-module>` as in the above
+example. In this case, you would need to write your ``PythonPath`` directive
+as::
 
-	PythonPath "['/usr/local/django-apps/', '/var/www'] + sys.path"
+    PythonPath "['/usr/local/django-apps/', '/var/www'] + sys.path"
 
 With this path, ``import weblog`` and ``import mysite.settings`` will both
 work. If you had ``import blogroll`` in your code somewhere and ``blogroll``
@@ -127,9 +130,9 @@ Note that you should set ``PythonDebug Off`` on a production server. If you
 leave ``PythonDebug On``, your users would see ugly (and revealing) Python
 tracebacks if something goes wrong within mod_python.
 
-Restart Apache, and any request to /mysite/ or below will be served by Django.
-Note that Django's URLconfs won't trim the "/mysite/" -- they get passed the
-full URL.
+Restart Apache, and any request to ``/mysite/`` or below will be served by
+Django. Note that Django's URLconfs won't trim the "/mysite/" -- they get passed
+the full URL.
 
 When deploying Django sites on mod_python, you'll need to restart Apache each
 time you make changes to your Python code.
@@ -196,6 +199,8 @@ Or add the debugging information to the template of your page.
 
 .. _mod_python documentation: http://modpython.org/live/current/doc-html/directives.html
 
+.. _serving-media-files:
+
 Serving media files
 ===================
 
@@ -205,9 +210,9 @@ server you choose.
 We recommend using a separate Web server -- i.e., one that's not also running
 Django -- for serving media. Here are some good choices:
 
-* lighttpd_
-* TUX_
-* A stripped-down version of Apache_
+    * lighttpd_
+    * TUX_
+    * A stripped-down version of Apache_
 
 If, however, you have no option but to serve media files on the same Apache
 ``VirtualHost`` as Django, here's how you can turn off mod_python for a
@@ -243,6 +248,10 @@ the ``media`` subdirectory and any URL that ends with ``.jpg``, ``.gif`` or
 .. _TUX: http://en.wikipedia.org/wiki/TUX_web_server
 .. _Apache: http://httpd.apache.org/
 
+.. _howto-deployment-modpython-serving-the-admin-files:
+
+.. _serving-the-admin-files:
+
 Serving the admin files
 =======================
 
@@ -251,25 +260,27 @@ but this is not the case when you use any other server arrangement. You're
 responsible for setting up Apache, or whichever media server you're using, to
 serve the admin files.
 
-The admin files live in (``django/contrib/admin/media``) of the Django
+The admin files live in (:file:`django/contrib/admin/media`) of the Django
 distribution.
 
 Here are two recommended approaches:
 
     1. Create a symbolic link to the admin media files from within your
-       document root. This way, all of your Django-related files -- code
-       **and** templates -- stay in one place, and you'll still be able to
-       ``svn update`` your code to get the latest admin templates, if they
-       change.
+       document root. This way, all of your Django-related files -- code **and**
+       templates -- stay in one place, and you'll still be able to ``svn
+       update`` your code to get the latest admin templates, if they change.
+       
     2. Or, copy the admin media files so that they live within your Apache
        document root.
 
-Using eggs with mod_python
-==========================
+Using "eggs" with mod_python
+============================
 
 If you installed Django from a Python egg_ or are using eggs in your Django
 project, some extra configuration is required. Create an extra file in your
-project (or somewhere else) that contains something like the following::
+project (or somewhere else) that contains something like the following:
+
+.. code-block:: python
 
     import os
     os.environ['PYTHON_EGG_CACHE'] = '/some/directory'
@@ -322,6 +333,7 @@ of which has to do with Django itself.
     1. It may be because your Python code is importing the "pyexpat" module,
        which may conflict with the version embedded in Apache. For full
        information, see `Expat Causing Apache Crash`_.
+       
     2. It may be because you're running mod_python and mod_php in the same
        Apache instance, with MySQL as your database backend. In some cases,
        this causes a known mod_python issue due to version conflicts in PHP and

+ 65 - 0
docs/howto/error-reporting.txt

@@ -0,0 +1,65 @@
+.. _howto-error-reporting:
+
+Error reporting via e-mail
+==========================
+
+When you're running a public site you should always turn off the
+:setting:`DEBUG` setting. That will make your server run much faster, and will
+also prevent malicious users from seeing details of your application that can be
+revealed by the error pages.
+
+However, running with :setting:`DEBUG` set to ``False`` means you'll never see
+errors generated by your site -- everyone will just see your public error pages.
+You need to keep track of errors that occur in deployed sites, so Django can be
+configured to email you details of those errors.
+
+Server errors
+-------------
+
+When :setting:`DEBUG` is ``False``, Django will e-mail the users listed in the
+:setting:`ADMIN` setting whenever your code raises an unhandled exception and
+results in an internal server error (HTTP status code 500). This gives the
+administrators immediate notification of any errors. The :setting:`ADMINS` will
+get a description of the error, a complete Python traceback, and details about
+the HTTP request that caused the error.
+
+To disable this behavior, just remove all entries from the :setting:`ADMINS`
+setting.
+
+404 errors
+----------
+
+Django can also be configured to email errors about broken links (404 "page
+not found" errors). Django sends emails about 404 errors when:
+
+    * :setting:`DEBUG` is ``False``
+    
+    * :setting:`SEND_BROKEN_LINK_EMAILS` is ``True``
+    
+    * Your :setting:`MIDDLEWARE_CLASSES` setting includes ``CommonMiddleware``
+      (which it does by default).
+    
+If those conditions are met, Django will e-mail the users listed in the
+:setting:`MANAGERS` setting whenever your code raises a 404 and the request has
+a referer. (It doesn't bother to e-mail for 404s that don't have a referer --
+those are usually just people typing in broken URLs or broken web 'bots).
+
+You can tell Django to stop reporting particular 404s by tweaking the
+:setting:`IGNORABLE_404_ENDS` and :setting:`IGNORABLE_404_STARTS` settings. Both
+should be a tuple of strings. For example::
+
+    IGNORABLE_404_ENDS = ('.php', '.cgi')
+    IGNORABLE_404_STARTS = ('/phpmyadmin/',)
+
+In this example, a 404 to any URL ending with ``.php`` or ``.cgi`` will *not* be
+reported. Neither will any URL starting with ``/phpmyadmin/``.
+
+The best way to disable this behavior is to set
+:setting:`SEND_BROKEN_LINK_EMAILS` to ``False``.
+
+.. seealso::
+
+    You can also set up custom error reporting by writing a custom piece of
+    :ref:`exception middleware <exception-middleware>`. If you do write custom
+    error handling, it's a good idea to emulate Django's built-in error handling
+    and only report/log errors if :setting:`DEBUG` is ``False``.

+ 33 - 0
docs/howto/index.txt

@@ -0,0 +1,33 @@
+.. _howto-index:
+
+"How-to" guides
+===============
+
+Here you'll find short answers to "How do I....?" types of questions. These
+how-to guides don't cover topics in depth -- you'll find that material in the
+:ref:`topics-index` and the :ref:`ref-index`. However, these guides will help
+you quickly accomplish common tasks.
+
+.. toctree::
+   :maxdepth: 1
+   
+   apache-auth
+   custom-management-commands
+   custom-model-fields
+   custom-template-tags
+   custom-file-storage
+   deployment/index
+   error-reporting
+   initial-data
+   legacy-databases
+   outputting-csv
+   outputting-pdf
+   static-files
+
+.. seealso::
+
+    The `Django community aggregator`_, where we aggregate content from the
+    global Django community. Many writers in the aggregator write this sort of
+    how-to material.
+    
+    .. _django community aggregator: http://www.djangoproject.com/community/

+ 140 - 0
docs/howto/initial-data.txt

@@ -0,0 +1,140 @@
+.. _howto-initial-data:
+
+=================================
+Providing initial data for models
+=================================
+
+It's sometimes useful to pre-populate your database with hard-coded data when
+you're first setting up an app. There's a couple of ways you can have Django
+automatically create this data: you can provide `initial data via fixtures`_, or
+you can provide `initial data as SQL`_.
+
+In general, using a fixture is a cleaner method since it's database-agnostic,
+but initial SQL is also quite a bit more flexible.
+
+.. _initial data as sql: `providing initial sql data`_
+.. _initial data via fixtures: `providing initial data with fixtures`_
+
+Providing initial data with fixtures
+====================================
+
+A fixture is a collection of data that Django knows how to import into a
+database. The most straightforward way of creating a fixture if you've already
+got some data is to use the :djadmin:`manage.py dumpdata` command. Or, you can
+write fixtures by hand; fixtures can be written as XML, YAML, or JSON documents.
+The :ref:`serialization documentation <topics-serialization>` has more details
+about each of these supported :ref:`serialization formats
+<serialization-formats>`.
+
+As an example, though, here's what a fixture for a simple ``Person`` model might
+look like in JSON:
+
+.. code-block:: js
+
+    [
+      {
+        "model": "myapp.person",  
+        "pk": 1,
+        "fields": {
+          "first_name": "John",
+          "last_name": "Lennon",
+        }
+      },
+      {
+        "model": "myapp.person",  
+        "pk": 2,
+        "fields": {
+          "first_name": "Paul",
+          "last_name": "McCartney",
+        }
+      },
+    ]
+    
+And here's that same fixture as YAML:
+
+.. code-block:: none
+
+    - model: myapp.person
+      pk: 1
+      fields:
+        first_name: John
+        last_name: Lennon
+    - model: myapp.person
+      pk: 1
+      fields:
+        first_name: Paul
+        last_name: McCartney
+        
+You'll store this data in a ``fixtures`` directory inside you app.
+
+Loading data is easy: just call :djadmin:`manage.py loaddata fixturename
+<loaddata>`, where *fixturename* is the name of the fixture file you've created.
+Every time you run :djadmin:`loaddata` the data will be read from the fixture
+and re-loaded into the database. Note that this means that if you change one of
+the rows created by a fixture and the run :djadmin:`loaddata` again you'll wipe
+out any changes you've made.
+
+Automatically loading initial data fixtures
+-------------------------------------------
+
+If you create a fixture named ``initial_data.[xml/yml/json]``, that fixture will
+be loaded every time you run :djadmin:`syncdb`. This is extremely convenient,
+but be careful: remember that the data will be refreshed *every time* you run
+:djadmin:`syncdb`. So don't use ``initial_data`` for data you'll want to edit.
+
+.. seealso::
+
+    Fixtures are also used by the :ref:`testing framework
+    <topics-testing-fixtures>` to help set up a consistent test environment.
+
+.. _initial-sql:
+
+Providing initial SQL data
+==========================
+
+Django provides a hook for passing the database arbitrary SQL that's executed
+just after the CREATE TABLE statements when you run :djadmin:`syncdb`. You can
+use this hook to populate default records, or you could also create SQL
+functions, views, triggers, etc.
+
+The hook is simple: Django just looks for a file called ``sql/<modelname>.sql``,
+in your app directory, where ``<modelname>`` is the model's name in lowercase.
+
+So, if you had a ``Person`` model in an app called ``myapp``, you could add
+arbitrary SQL to the file ``sql/person.sql`` inside your ``myapp`` directory.
+Here's an example of what the file might contain:
+
+.. code-block:: sql
+
+    INSERT INTO myapp_person (first_name, last_name) VALUES ('John', 'Lennon');
+    INSERT INTO myapp_person (first_name, last_name) VALUES ('Paul', 'McCartney');
+
+Each SQL file, if given, is expected to contain valid SQL statements
+which will insert the desired data (e.g., properly-formatted
+``INSERT`` statements separated by semicolons).
+
+The SQL files are read by the :djadmin:`sqlcustom`, :djadmin:`sqlreset`,
+:djadmin:`sqlall` and :djadmin:`reset` commands in :ref:`manage.py
+<ref-django-admin>`. Refer to the :ref:`manage.py documentation
+<ref-django-admin>` for more information.
+
+Note that if you have multiple SQL data files, there's no guarantee of the order
+in which they're executed. The only thing you can assume is that, by the time
+your custom data files are executed, all the database tables already will have
+been created.
+
+Database-backend-specific SQL data
+----------------------------------
+
+There's also a hook for backend-specific SQL data. For example, you can have
+separate initial-data files for PostgreSQL and MySQL. For each app, Django
+looks for a file called ``<appname>/sql/<modelname>.<backend>.sql``, where
+``<appname>`` is your app directory, ``<modelname>`` is the model's name in
+lowercase and ``<backend>`` is the value of :setting:`DATABASE_ENGINE` in your
+settings file (e.g., ``postgresql``, ``mysql``).
+
+Backend-specific SQL data is executed before non-backend-specific SQL data. For
+example, if your app contains the files ``sql/person.sql`` and
+``sql/person.postgresql.sql`` and you're installing the app on PostgreSQL,
+Django will execute the contents of ``sql/person.postgresql.sql`` first, then
+``sql/person.sql``.

+ 67 - 0
docs/howto/legacy-databases.txt

@@ -0,0 +1,67 @@
+.. _howto-legacy-databases:
+
+=========================================
+Integrating Django with a legacy database
+=========================================
+
+While Django is best suited for developing new applications, it's quite
+possible to integrate it into legacy databases. Django includes a couple of
+utilities to automate as much of this process as possible.
+
+This document assumes you know the Django basics, as covered in the
+:ref:`tutorial <intro-tutorial01>`.
+
+Once you've got Django set up, you'll follow this general process to integrate
+with an existing database.
+
+Give Django your database parameters
+====================================
+
+You'll need to tell Django what your database connection parameters are, and
+what the name of the database is. Do that by editing these settings in your
+:ref:`settings file <topics-settings>`:
+
+    * :setting:`DATABASE_NAME`
+    * :setting:`DATABASE_ENGINE`
+    * :setting:`DATABASE_USER`
+    * :setting:`DATABASE_PASSWORD`
+    * :setting:`DATABASE_HOST`
+    * :setting:`DATABASE_PORT`
+
+Auto-generate the models
+========================
+
+.. highlight:: bash
+
+Django comes with a utility called :djadmin:`inspectdb` that can create models
+by introspecting an existing database. You can view the output by running this
+command::
+
+    python manage.py inspectdb
+
+Save this as a file by using standard Unix output redirection::
+
+    python manage.py inspectdb > models.py
+
+This feature is meant as a shortcut, not as definitive model generation. See the
+:djadmin:`documentation of inspectdb <inspectdb>` for more information.
+
+Once you've cleaned up your models, name the file ``models.py`` and put it in
+the Python package that holds your app. Then add the app to your
+:setting:`INSTALLED_APPS` setting.
+
+Install the core Django tables
+==============================
+
+Next, run the :djadmin:`syncdb` command to install any extra needed database
+records such as admin permissions and content types::
+
+    python manage.py syncdb
+
+Test and tweak
+==============
+
+Those are the basic steps -- from here you'll want to tweak the models Django
+generated until they work the way you'd like. Try accessing your data via the
+Django database API, and try editing objects via Django's admin site, and edit
+the models file accordingly.

+ 27 - 30
docs/outputting_csv.txt → docs/howto/outputting-csv.txt

@@ -1,12 +1,12 @@
+.. _howto-outputting-csv:
+
 ==========================
 Outputting CSV with Django
 ==========================
 
 This document explains how to output CSV (Comma Separated Values) dynamically
-using Django views.
-
-To do this, you can either use the `Python CSV library`_ or the Django template
-system.
+using Django views. To do this, you can either use the `Python CSV library`_ or
+the Django template system.
 
 .. _Python CSV library: http://www.python.org/doc/current/lib/module-csv.html
 
@@ -14,18 +14,8 @@ Using the Python CSV library
 ============================
 
 Python comes with a CSV library, ``csv``. The key to using it with Django is
-that the ``csv`` module's CSV-creation capability acts on file-like objects,
-and Django's ``HttpResponse`` objects are file-like objects.
-
-.. admonition:: Note
-
-    For more information on ``HttpResponse`` objects, see
-    `Request and response objects`_.
-
-    For more information on the CSV library, see the `CSV library docs`_.
-
-    .. _Request and response objects: ../request_response/
-    .. _CSV library docs: http://www.python.org/doc/current/lib/module-csv.html
+that the ``csv`` module's CSV-creation capability acts on file-like objects, and
+Django's :class:`~django.http.HttpResponse` objects are file-like objects.
 
 Here's an example::
 
@@ -46,7 +36,7 @@ Here's an example::
 The code and comments should be self-explanatory, but a few things deserve a
 mention:
 
-    * The response gets a special mimetype, ``text/csv``. This tells
+    * The response gets a special MIME type, ``text/csv``. This tells
       browsers that the document is a CSV file, rather than an HTML file. If
       you leave this off, browsers will probably interpret the output as HTML,
       which will result in ugly, scary gobbledygook in the browser window.
@@ -56,9 +46,10 @@ mention:
       whatever you want. It'll be used by browsers in the "Save as..."
       dialogue, etc.
 
-    * Hooking into the CSV-generation API is easy: Just pass ``response`` as
-      the first argument to ``csv.writer``. The ``csv.writer`` function expects
-      a file-like object, and ``HttpResponse`` objects fit the bill.
+    * Hooking into the CSV-generation API is easy: Just pass ``response`` as the
+      first argument to ``csv.writer``. The ``csv.writer`` function expects a
+      file-like object, and :class:`~django.http.HttpResponse` objects fit the
+      bill.
 
     * For each row in your CSV file, call ``writer.writerow``, passing it an
       iterable object such as a list or tuple.
@@ -70,12 +61,12 @@ mention:
 Using the template system
 =========================
 
-Alternatively, you can use the `Django template system`_ to generate CSV. This
-is lower-level than using the convenient CSV, but the solution is presented
-here for completeness.
+Alternatively, you can use the :ref:`Django template system <topics-templates>`
+to generate CSV. This is lower-level than using the convenient CSV, but the
+solution is presented here for completeness.
 
 The idea here is to pass a list of items to your template, and have the
-template output the commas in a ``{% for %}`` loop.
+template output the commas in a :ttag:`for` loop.
 
 Here's an example, which generates the same CSV file as above::
 
@@ -105,15 +96,21 @@ The only difference between this example and the previous example is that this
 one uses template loading instead of the CSV module. The rest of the code --
 such as the ``mimetype='text/csv'`` -- is the same.
 
-Then, create the template ``my_template_name.txt``, with this template code::
+Then, create the template ``my_template_name.txt``, with this template code:
+
+.. code-block:: html+django
 
     {% for row in data %}"{{ row.0|addslashes }}", "{{ row.1|addslashes }}", "{{ row.2|addslashes }}", "{{ row.3|addslashes }}", "{{ row.4|addslashes }}"
     {% endfor %}
 
 This template is quite basic. It just iterates over the given data and displays
-a line of CSV for each row. It uses the `addslashes template filter`_ to ensure
-there aren't any problems with quotes. If you can be certain your data doesn't
-have single or double quotes in it, you can remove the ``addslashes`` filters.
+a line of CSV for each row. It uses the :tfilter:`addslashes` template filter to
+ensure there aren't any problems with quotes.
+
+Other text-based formats
+========================
 
-.. _Django template system: ../templates/
-.. _addslashes template filter: ../templates/#addslashes
+Notice that there isn't very much specific to CSV here -- just the specific
+output format. You can use either of these techniques to output any text-based
+format you can dream of. You can also use a similar technique to generate
+arbitrary binary data; see :ref:`howto-outputting-pdf` for an example.

+ 20 - 16
docs/outputting_pdf.txt → docs/howto/outputting-pdf.txt

@@ -1,3 +1,5 @@
+.. _howto-outputting-pdf:
+
 ===========================
 Outputting PDFs with Django
 ===========================
@@ -35,15 +37,8 @@ Write your view
 ===============
 
 The key to generating PDFs dynamically with Django is that the ReportLab API
-acts on file-like objects, and Django's ``HttpResponse`` objects are file-like
-objects.
-
-.. admonition:: Note
-
-    For more information on ``HttpResponse`` objects, see
-    `Request and response objects`_.
-
-    .. _Request and response objects: ../request_response/
+acts on file-like objects, and Django's :class:`~django.http.HttpResponse`
+objects are file-like objects.
 
 Here's a "Hello World" example::
 
@@ -70,7 +65,7 @@ Here's a "Hello World" example::
 The code and comments should be self-explanatory, but a few things deserve a
 mention:
 
-    * The response gets a special mimetype, ``application/pdf``. This tells
+    * The response gets a special MIME type, ``application/pdf``. This tells
       browsers that the document is a PDF file, rather than an HTML file. If
       you leave this off, browsers will probably interpret the output as HTML,
       which would result in ugly, scary gobbledygook in the browser window.
@@ -91,7 +86,8 @@ mention:
 
     * Hooking into the ReportLab API is easy: Just pass ``response`` as the
       first argument to ``canvas.Canvas``. The ``Canvas`` class expects a
-      file-like object, and ``HttpResponse`` objects fit the bill.
+      file-like object, and :class:`~django.http.HttpResponse` objects fit the
+      bill.
 
     * Note that all subsequent PDF-generation methods are called on the PDF
       object (in this case, ``p``) -- not on ``response``.
@@ -103,10 +99,9 @@ Complex PDFs
 ============
 
 If you're creating a complex PDF document with ReportLab, consider using the
-cStringIO_ library as a temporary holding place for your PDF file. The
-cStringIO library provides a file-like object interface that is particularly
-efficient. Here's the above "Hello World" example rewritten to use
-``cStringIO``::
+cStringIO_ library as a temporary holding place for your PDF file. The cStringIO
+library provides a file-like object interface that is particularly efficient.
+Here's the above "Hello World" example rewritten to use ``cStringIO``::
 
     from cStringIO import StringIO
     from reportlab.pdfgen import canvas
@@ -144,7 +139,7 @@ Further resources
     * PDFlib_ is another PDF-generation library that has Python bindings. To
       use it with Django, just use the same concepts explained in this article.
     * `Pisa HTML2PDF`_ is yet another PDF-generation library. Pisa ships with
-      an example of how to integrate Pisa with Django.
+      an example of how to integrate Pisa with Django.      
     * HTMLdoc_ is a command-line script that can convert HTML to PDF. It
       doesn't have a Python interface, but you can escape out to the shell
       using ``system`` or ``popen`` and retrieve the output in Python.
@@ -154,3 +149,12 @@ Further resources
 .. _`Pisa HTML2PDF`: http://www.htmltopdf.org/
 .. _HTMLdoc: http://www.htmldoc.org/
 .. _forge_fdf in Python: http://www.accesspdf.com/article.php/20050421092951834
+
+Other formats
+=============
+
+Notice that there isn't a lot in these examples that's PDF-specific -- just the
+bits using ``reportlab``. You can use a similar technique to generate any
+arbitrary format that you can find a Python library for. Also see
+:ref:`howto-outputting-csv` for another example and some techniques you can use
+when generated text-based formats.

+ 29 - 23
docs/static_files.txt → docs/howto/static-files.txt

@@ -1,7 +1,12 @@
+.. _howto-static-files:
+
 =========================
 How to serve static files
 =========================
 
+.. module:: django.views.static
+   :synopsis: Serving of static files during development.
+ 
 Django itself doesn't serve static (media) files, such as images, style sheets,
 or video. It leaves that job to whichever Web server you choose.
 
@@ -9,8 +14,8 @@ The reasoning here is that standard Web servers, such as Apache_ and lighttpd_,
 are much more fine-tuned at serving static files than a Web application
 framework.
 
-With that said, Django does support static files **during development**. Use
-the view ``django.views.static.serve`` to serve media files.
+With that said, Django does support static files **during development**. You can
+use the :func:`django.views.static.serve` view to serve media files.
 
 .. _Apache: http://httpd.apache.org/
 .. _lighttpd: http://www.lighttpd.net/
@@ -22,23 +27,25 @@ Using this method is **inefficient** and **insecure**. Do not use this in a
 production setting. Use this only for development.
 
 For information on serving static files in an Apache production environment,
-see the `Django mod_python documentation`_.
-
-.. _Django mod_python documentation: ../modpython/#serving-media-files
+see the :ref:`Django mod_python documentation <serving-media-files>`.
 
 How to do it
 ============
 
-Just put this in your URLconf_::
+Here's the formal definition of the :func:`~django.views.static.serve` view:
+
+.. function:: def serve(request, path, document_root, show_indexes=False):
+
+To use it, just put this in your :ref:`URLconf <topics-http-urls>`::
 
     (r'^site_media/(?P<path>.*)$', 'django.views.static.serve', {'document_root': '/path/to/media'}),
 
 ...where ``site_media`` is the URL where your media will be rooted, and
-``/path/to/media`` is the filesystem root for your media.
+``/path/to/media`` is the filesystem root for your media. This will call the
+:func:`~django.views.static.serve` view, passing in the path from the URLconf
+and the (required) ``document_root`` parameter.
 
-You must pass a ``document_root`` parameter to indicate the filesystem root.
-
-Examples:
+Given the above URLconf:
 
     * The file ``/path/to/media/foo.jpg`` will be made available at the URL
       ``/site_media/foo.jpg``.
@@ -49,26 +56,27 @@ Examples:
     * The file ``/path/bar.jpg`` will not be accessible, because it doesn't
       fall under the document root.
 
-.. _URLconf: ../url_dispatch/
 
 Directory listings
 ==================
 
-Optionally, you can pass a ``show_indexes`` parameter to the ``static.serve``
-view. This is ``False`` by default. If it's ``True``, Django will display file
-listings for directories.
+Optionally, you can pass the ``show_indexes`` parameter to the
+:func:`~django.views.static.serve` view. This is ``False`` by default. If it's
+``True``, Django will display file listings for directories.
 
-Example::
+For example::
 
     (r'^site_media/(?P<path>.*)$', 'django.views.static.serve', {'document_root': '/path/to/media', 'show_indexes': True}),
 
 You can customize the index view by creating a template called
-``static/directory_index``. That template gets two objects in its context:
+``static/directory_index.html``. That template gets two objects in its context:
 
     * ``directory`` -- the directory name (a string)
     * ``file_list`` -- a list of file names (as strings) in the directory
 
-Here's the default ``static/directory_index`` template::
+Here's the default ``static/directory_index`` template:
+
+.. code-block:: html+django
 
     <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
     <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
@@ -97,7 +105,7 @@ trick to make sure the static-serving view doesn't slip into a production
 setting by mistake.
 
 Do this by wrapping an ``if DEBUG`` statement around the
-``django.views.static.serve`` inclusion. Here's a full example URLconf::
+:func:`django.views.static.serve` inclusion. Here's a full example URLconf::
 
     from django.conf.urls.defaults import *
     from django.conf import settings
@@ -115,11 +123,9 @@ Do this by wrapping an ``if DEBUG`` statement around the
         )
 
 This code is straightforward. It imports the settings and checks the value of
-the ``DEBUG`` setting. If it evaluates to ``True``, then ``site_media`` will be
-associated with the ``django.views.static.serve`` view. If not
-(``DEBUG == False``), then the view won't be made available.
+the :setting:`DEBUG` setting. If it evaluates to ``True``, then ``site_media``
+will be associated with the ``django.views.static.serve`` view. If not, then the
+view won't be made available.
 
 Of course, the catch here is that you'll have to remember to set ``DEBUG=False``
 in your production settings file. But you should be doing that anyway.
-
-.. _DEBUG setting: ../settings/#debug

+ 143 - 115
docs/index.txt

@@ -1,134 +1,162 @@
+.. _index:
+
 ====================
-Django Documentation
+Django documentation
 ====================
 
-The essential documentation
-===========================
-
-If you're new to Django, make sure to read the following documentation in
-order.. The rest (in the "reference" section below) can be ready in any order as
-you need various functionality.
-
-.. toctree::
-   :maxdepth: 1
-   
-   overview
-   install
-   tutorial01
-   tutorial02
-   tutorial03
-   tutorial04
-   faq
-   documentation
-   
-Reference
-=========
+.. rubric:: Everything you need to know about Django (and then some).
+
+Getting help
+============
+
+Having trouble? We'd like to help!
+
+* Try the :ref:`FAQ <faq-index>` -- it's got answers to many common questions.
+
+* Looking for specific information? Try the :ref:`genindex`, :ref:`modindex` or
+  the :ref:`detailed table of contents <contents>`.
+
+* Search for information in the `archives of the django-users mailing list`_, or
+  `post a question`_
+  
+* Ask a question in the `#django IRC channel`_, or search the `IRC logs`_ to see
+  if its been asked before
+
+* Report bugs with Django in our `ticket tracker`_.
+
+.. _archives of the django-users mailing list: http://groups.google.com/group/django-users/
+.. _post a question: http://groups.google.com/group/django-users/
+.. _#django IRC channel: irc://irc.freenode.net/django
+.. _IRC logs: http://oebfare.com/logger/django/
+.. _ticket tracker: http://code.djangoproject.com/
 
-.. toctree::
-   :maxdepth: 1
-   
-   django-admin
-   model-api
-   db-api
-   transactions
-   templates
-   templates_python
-   forms
-   modelforms
-   files
-   upload_handling
-   testing
-   sessions
-   cache
-   settings
-   url_dispatch
-   request_response
-   generic_views
-   authentication
-   shortcuts
-   unicode
-   pagination
-   serialization
-   i18n
-   middleware
-   custom_model_fields
-   databases
-   
-``django.contrib`` add-ons
---------------------------
-
-.. toctree::
-   :maxdepth: 1
-   
-   admin
-   add_ons
-   contenttypes
-   csrf
-   databrowse
-   flatpages
-   form_preview
-   form_wizard
-   localflavor
-   redirects
-   sites
-   sitemaps
-   syndication_feeds
-   webdesign
-   
-Deployment
-----------
-
-.. toctree::
-   :maxdepth: 1
-
-   modpython
-   fastcgi
+First steps
+===========
+
+:ref:`Overview <intro-overview>`
+    See what writing a database-driven application with Django looks like.
     
-Solving specific problems
--------------------------
+:ref:`Installation <intro-install>`
+    Get Django installed on your computer.
+    
+Tutorial: Writing your first Django application
+===============================================
+
+:ref:`Part 1 <intro-tutorial01>`
+    Get set up, create models, and play with the database API.
+    
+:ref:`Part 2 <intro-tutorial02>`
+    Explore the automatically-generated admin site.
+    
+:ref:`Part 3 <intro-tutorial03>`
+    Write the public interface views.
+    
+:ref:`Part 4 <intro-tutorial04>`
+    Learn how to process forms.
+        
+Using Django
+============
+
+:ref:`Models <topics-db-index>`
+    Design a single, definitive source of data about your data.
+    
+:ref:`Handling web requests <topics-http-index>`
+    Handle web requests, map them to views, and return pages.
+    
+:ref:`Forms <topics-forms-index>`
+    Build and handle HTML forms.
+    
+:ref:`Templates <topics-templates>`
+    Develop the visual design of your site.
+    
+And more:
+---------
 
-.. toctree::
-   :maxdepth: 1
+:ref:`topics-auth` ... :ref:`topics-cache` ... :ref:`topics-email` ...
+:ref:`topics-files` ... :ref:`topics-i18n` ... :ref:`topics-install` ...
+:ref:`topics-pagination` ... :ref:`topics-serialization` ...
+:ref:`topics-settings` ... :ref:`topics-testing`
+    
+Add-on ("contrib") applications
+===============================
 
-   apache_auth
-   static_files
-   email
-   legacy_databases
-   outputting_pdf
-   outputting_csv
+:ref:`Django's automatic admin site <ref-contrib-admin>`
+    Get a clean interface to your data with no effort at all.
+    
+:ref:`Form tools <ref-contrib-formtools-index>`
+    Easily handle complex form workflows.
     
-Et cetera
+:ref:`Syndication feeds <ref-contrib-syndication>`
+    Generate RSS and Atom feeds of your data.
+    
+:ref:`"Local flavor" <ref-contrib-localflavor>`
+    Give your site that special local touch.
+    
+And more:
 ---------
 
-.. toctree::
-   :maxdepth: 1
+:ref:`ref-contrib-contenttypes` ... :ref:`ref-contrib-csrf` ...
+:ref:`ref-contrib-databrowse` ... :ref:`ref-contrib-flatpages` ...
+:ref:`ref-contrib-humanize` ... :ref:`ref-contrib-redirects` ...
+:ref:`ref-contrib-sitemaps` ... :ref:`ref-contrib-sites` ...
+:ref:`ref-contrib-webdesign`
 
-   design_philosophies
-   contributing
-   admin_css
-   api_stability
-   distributions
+Solving specific problems
+=========================
 
-Release notes
--------------
+:ref:`Deployment <howto-deployment-index>`
+    Release your project to the world.
+    
+:ref:`Importing data from legacy databases <howto-legacy-databases>`
+    Use Django with an existing database or alongside other web development
+    toolkits.
 
-.. toctree::
-   :maxdepth: 1
+:ref:`Custom template tags <howto-custom-template-tags>`
+    Add your own extensions to Django's template language.
+    
+:ref:`Generating CSV <howto-outputting-csv>` & :ref:`PDF <howto-outputting-PDF>`
+    Produce non-HTML content with Django.
+    
+And more:
+---------
 
-   release_notes_0.96
-   release_notes_0.95
-   release_notes_1.0_alpha
-   release_notes_1.0_alpha_2
+:ref:`Authenticating in Apache <howto-apache-auth>` ...
+:ref:`howto-custom-file-storage` ... :ref:`howto-custom-management-commands` ...
+:ref:`howto-custom-model-fields` ... :ref:`howto-error-reporting` ...
+:ref:`howto-initial-data` ... :ref:`howto-static-files`
+    
+Reference
+=========
 
-Also see the list of `backwards-incompatible changes`__ for changes made between
-releases.
+:ref:`Settings <ref-settings>`
+    See all of Django's settings and what they do.
+    
+:ref:`Request & response objects <ref-request-response>`
+    Understand the classes Django uses to represent HTTP requests and responses.
+
+:ref:`Model API reference <ref-models-index>`
+    Revel in the gory details of Django's model system.
+        
+:ref:`Form API reference <ref-forms-index>`
+    Learn the details of forms, fields, and widgets.
+    
+And more:
+---------
 
-__ http://code.djangoproject.com/wiki/BackwardsIncompatibleChanges
+:ref:`ref-databases` ... :ref:`ref-django-admin` ... :ref:`ref-files-index` ...
+:ref:`ref-generic-views` ... :ref:`ref-middleware` ...
+:ref:`ref-templates-index` ... :ref:`ref-unicode`
+    
+And all the rest
+================
 
-Indices and tables
-==================
+:ref:`Internals <internals-index>`
+    Learn how Django works under the hood, and how you can contribute to the
+    project.
 
-* :ref:`genindex`
-* :ref:`modindex`
-* :ref:`search`
+:ref:`Release notes <releases-index>`
+    See what is and was new in each release of Django.
 
+:ref:`Miscellany <misc-index>`
+    Stuff we can't find a more organized place for. Like that drawer in your
+    kitchen with the scissors, batteries, and duct tape.

BIN
docs/internals/_images/djangotickets.png


+ 39 - 23
docs/contributing.txt → docs/internals/contributing.txt

@@ -1,3 +1,5 @@
+.. _internals-contributing:
+
 ======================
 Contributing to Django
 ======================
@@ -30,6 +32,8 @@ community. The rest of this document describes the details of how our community
 works and how it handles bugs, mailing lists, and all the other minutiae of
 Django development.
 
+.. _reporting-bugs:
+
 Reporting bugs
 ==============
 
@@ -38,7 +42,7 @@ amount of overhead involved in working with any bug tracking system, so your
 help in keeping our ticket tracker as useful as possible is appreciated.  In
 particular:
 
-    * **Do** read the FAQ_ to see if your issue might be a well-known question.
+    * **Do** read the :ref:`FAQ <faq-index>` to see if your issue might be a well-known question.
 
     * **Do** `search the tracker`_ to see if your issue has already been filed.
 
@@ -74,6 +78,8 @@ particular:
 
 .. _django-updates: http://groups.google.com/group/django-updates
 
+.. _reporting-security-issues:
+
 Reporting security issues
 =========================
 
@@ -231,7 +237,7 @@ ticket is waiting on.
 
 Since a picture is worth a thousand words, let's start there:
 
-.. image:: http://media.djangoproject.com/img/doc/djangotickets.png
+.. image:: _images/djangotickets.png
    :height: 451
    :width: 590
    :alt: Django's ticket workflow
@@ -377,6 +383,8 @@ the ticket database:
       be making a change, don't make the change -- leave a comment with your
       concerns on the ticket, or post a message to `django-developers`_.
 
+.. _contributing-translations:
+
 Submitting and maintaining translations
 =======================================
 
@@ -390,23 +398,22 @@ translated, here's what to do:
 
     * Join the `Django i18n mailing list`_ and introduce yourself.
     * Create translations using the methods described in the
-      `i18n documentation`_.
+      :ref:`i18n documentation <topics-i18n>`.
     * Create a diff of the ``.po`` file against the current Subversion trunk.
     * Make sure that `` django-admin.py compilemessages -l <lang>`` runs without
       producing any warnings.
     * Attach the patch to a ticket in Django's ticket system.
 
 .. _Django i18n mailing list: http://groups.google.com/group/django-i18n/
-.. _i18n documentation: ../i18n/
 
 Coding style
 ============
 
 Please follow these coding standards when writing code for inclusion in Django:
 
-    * Unless otherwise specified, follow `PEP 8`_.
+    * Unless otherwise specified, follow :pep:8.
 
-      You could use  a tool like `pep8.py`_ to check for some problems in this
+      You could use a tool like `pep8.py`_ to check for some problems in this
       area, but remember that PEP 8 is only a guide, so respect the style of
       the surrounding code as a primary goal.
 
@@ -418,8 +425,8 @@ Please follow these coding standards when writing code for inclusion in Django:
     * Use ``InitialCaps`` for class names (or for factory functions that
       return classes).
 
-    * Mark all strings for internationalization; see the `i18n documentation`_
-      for details.
+    * Mark all strings for internationalization; see the :ref:`i18n
+      documentation <topics-i18n>` for details.
 
     * In docstrings, use "action words" such as::
 
@@ -449,11 +456,15 @@ Template style
     * In Django template code, put one (and only one) space between the curly
       brackets and the tag contents.
 
-      Do this::
+      Do this:
+      
+      .. code-block:: html+django
 
           {{ foo }}
 
-      Don't do this::
+      Don't do this:
+      
+      .. code-block:: html+django
 
           {{foo}}
 
@@ -706,15 +717,15 @@ The tests cover:
 We appreciate any and all contributions to the test suite!
 
 The Django tests all use the testing infrastructure that ships with Django for
-testing applications. See `Testing Django applications`_ for an explanation of
-how to write new tests.
-
-.. _Testing Django applications: ../testing/
+testing applications. See :ref:`Testing Django applications <topics-testing>`
+for an explanation of how to write new tests.
 
 Running the unit tests
 ----------------------
 
-To run the tests, ``cd`` to the ``tests/`` directory and type::
+To run the tests, ``cd`` to the ``tests/`` directory and type:
+
+.. code-block:: bash
 
     ./runtests.py --settings=path.to.django.settings
 
@@ -727,13 +738,13 @@ needed. A temporary database will be created in memory when running the tests.
 
 If you're using another backend:
 
-    * Your ``DATABASE_USER`` setting needs to specify an existing user account
+    * Your :setting:`DATABASE_USER` setting needs to specify an existing user account
       for the database engine.
 
-    * The ``DATABASE_NAME`` setting must be the name of an existing database to
+    * The :setting:`DATABASE_NAME` setting must be the name of an existing database to
       which the given user has permission to connect. The unit tests will not
       touch this database; the test runner creates a new database whose name is
-      ``DATABASE_NAME`` prefixed with ``test_``, and this test database is
+      :setting:`DATABASE_NAME` prefixed with ``test_``, and this test database is
       deleted when the tests are finished. This means your user account needs
       permission to execute ``CREATE DATABASE``.
 
@@ -766,7 +777,9 @@ To run a subset of the unit tests, append the names of the test modules to the
 
 As an example, if Django is not in your ``PYTHONPATH``, you placed
 ``settings.py`` in the ``tests/`` directory, and you'd like to only run tests
-for generic relations and internationalization, type::
+for generic relations and internationalization, type:
+
+.. code-block:: bash
 
     PYTHONPATH=..
     ./runtests.py --settings=settings generic_relations i18n
@@ -787,6 +800,7 @@ method as above::
 
     ./runtests.py --settings=settings markup
 
+
 Requesting features
 ===================
 
@@ -854,7 +868,9 @@ To use a branch, you'll need to do two things:
 Getting the code from Subversion
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-To get the latest version of a branch's code, check it out using Subversion::
+To get the latest version of a branch's code, check it out using Subversion:
+
+.. code-block:: bash
 
     svn co http://code.djangoproject.com/svn/django/branches/<branch>/
 
@@ -862,7 +878,9 @@ To get the latest version of a branch's code, check it out using Subversion::
 
 Alternatively, you can automatically convert an existing directory of the
 Django source code as long as you've checked it out via Subversion. To do the
-conversion, execute this command from within your ``django`` directory::
+conversion, execute this command from within your ``django`` directory:
+
+.. code-block:: bash
 
     svn switch http://code.djangoproject.com/svn/django/branches/<branch>/
 
@@ -1025,12 +1043,10 @@ requests for commit access are potential flame-war starters, and will be ignored
 .. _community page: http://www.djangoproject.com/community/
 .. _ticket tracker: http://code.djangoproject.com/newticket
 .. _django-developers: http://groups.google.com/group/django-developers
-.. _FAQ: http://www.djangoproject.com/documentation/faq/
 .. _search the tracker: http://code.djangoproject.com/search
 .. _django-users: http://groups.google.com/group/django-users
 .. _`#django`: irc://irc.freenode.net/django
 .. _list of tickets with patches: http://code.djangoproject.com/query?status=new&status=assigned&status=reopened&has_patch=1&order=priority
-.. _PEP 8: http://www.python.org/peps/pep-0008.html
 .. _pep8.py: http://svn.browsershots.org/trunk/devtools/pep8/pep8.py
 .. _i18n branch: http://code.djangoproject.com/browser/django/branches/i18n
 .. _`tags/releases`: http://code.djangoproject.com/browser/django/tags/releases

+ 204 - 0
docs/internals/documentation.txt

@@ -0,0 +1,204 @@
+.. _internals-documentation:
+
+How the Django documentation works
+==================================
+
+\... and how to contribute.
+
+Django's documentation uses the Sphinx__ documentation system, which in turn is
+based on docutils__. The basic idea is that lightly-formatted plain-text
+documentation is transformed into HTML, PDF, and any other output format.
+
+__ http://sphinx.pocoo.org/
+__ http://docutils.sf.net/
+
+To actually build the documentation locally, you'll currently need to install
+Sphinx -- ``easy_install Sphinx`` should do the trick.
+
+Then, building the html is easy; just ``make html`` from the ``docs`` directory.
+
+To get started contributing, you'll want to read the `ReStructuredText
+Primer`__. After that, you'll want to read about the `Sphinx-specific markup`__
+that's used to manage metadata, indexing, and cross-references.
+
+__ http://sphinx.pocoo.org/rest.html
+__ http://sphinx.pocoo.org/markup/
+
+The main thing to keep in mind as you write and edit docs is that the more
+semantic markup you can add the better. So::
+
+    Add ``django.contrib.auth`` to your ``INSTALLED_APPS``...
+    
+Isn't nearly as helpful as::
+
+    Add :mod:`django.contrib.auth` to your :setting:`INSTALLED_APPS`...
+    
+This is because Sphinx will generate proper links for the later, which greatly
+helps readers. There's basically no limit to the amount of useful markup you can
+add.
+
+Django-specific markup
+----------------------
+
+Besides the `Sphinx built-in markup`__, Django's docs defines some extra description units:
+
+__ http://sphinx.pocoo.org/markup/desc.html
+
+    * Settings::
+    
+            .. setting:: INSTALLED_APPS
+                
+      To link to a setting, use ``:setting:`INSTALLED_APPS```.
+      
+    * Template tags::
+   
+            .. templatetag:: regroup
+    
+      To link, use ``:ttag:`regroup```.
+     
+    * Template filters::
+   
+            .. templatefilter:: linebreaksbr
+       
+      To link, use ``:tfilter:`linebreaksbr```.
+      
+    * Field lookups (i.e. ``Foo.objects.filter(bar__exact=whatever)``)::
+    
+            .. fieldlookup:: exact
+            
+      To link, use ``:lookup:`exact```.
+      
+    * ``django-admin`` commands::
+    
+            .. django-admin:: syncdb
+            
+      To link, use ``:djadmin:`syncdb```.
+      
+    * ``django-admin`` command-line options::
+    
+            .. django-admin-option:: --traceback
+            
+      To link, use ``:djadminopt:`--traceback```.
+
+An example
+----------
+
+For a quick example of how it all fits together, check this out:
+
+    * First, the ``ref/settings.txt`` document starts out like this::
+    
+        .. _ref-settings:
+
+        Available settings
+        ==================
+        
+        ...
+        
+    * Next, if you look at the ``topics/settings.txt`` document, you can see how
+      a link to ``ref/settings`` works::
+     
+        Available settings
+        ==================
+
+        For a full list of available settings, see the :ref:`settings reference
+        <ref-settings>`.
+        
+    * Next, notice how the settings (right now just the top few) are annotated::
+   
+        .. setting:: ADMIN_FOR
+
+        ADMIN_FOR
+        ---------
+
+        Default: ``()`` (Empty tuple)
+
+        Used for admin-site settings modules, this should be a tuple of settings
+        modules (in the format ``'foo.bar.baz'``) for which this site is an
+        admin.
+        
+        The admin site uses this in its automatically-introspected
+        documentation of models, views and template tags.
+        
+      This marks up the following header as the "canonical" target for the
+      setting ``ADMIN_FOR`` This means any time I talk about ``ADMIN_FOR``, I
+      can reference it using ``:setting:`ADMIN_FOR```.
+     
+That's basically how everything fits together.
+
+TODO
+----
+
+The work is mostly done, but here's what's left, in rough order of priority.
+
+    * Fix up generic view docs: adapt Chapter 9 of the Django Book (consider
+      this TODO item my permission and license) into
+      ``topics/generic-views.txt``; remove the intro material from
+      ``ref/generic-views.txt`` and just leave the function reference.
+    
+    * Change the "Added/changed in development version" callouts to proper
+      Sphinx ``.. versionadded::`` or ``.. versionchanged::`` directives.
+    
+    * Check for and fix malformed links. Do this by running ``make linkcheck``
+      and fix all of the 300+ errors/warnings.
+      
+      In particular, look at all the relative links; these need to be 
+      changed to proper references.
+      
+    * Most of the various ``index.txt`` documents have *very* short or even
+      non-existent intro text. Each of those documents needs a good short intro
+      the content below that point.
+
+    * The glossary is very perfunctory. It needs to be filled out.
+    
+    * Add more metadata targets: there's lots of places that look like::
+    
+            ``File.close()``
+            ~~~~~~~~~~~~~~~~
+        
+      \... these should be::
+      
+            .. method:: File.close()
+            
+      That is, use metadata instead of titles.
+      
+    * Add more links -- nearly everything that's an inline code literal
+      right now can probably be turned into a xref. 
+      
+      See the ``literals_to_xrefs.py`` file in ``_ext`` -- it's a shell script
+      to help do this work.
+
+      This will probably be a continuing, never-ending project.
+
+    * Add `info field lists`__ where appropriate.
+    
+      __ http://sphinx.pocoo.org/markup/desc.html#info-field-lists
+      
+    * Add ``.. code-block:: <lang>`` to literal blocks so that they get
+      highlighted.
+
+Hints
+-----
+
+Some hints for making things look/read better:
+
+    * Whenever possible, use links. So, use ``:setting:`ADMIN_FOR``` instead of
+      ````ADMIN_FOR````.
+
+    * Some directives (``.. setting::``, for one) are prefix-style directives;
+      they go *before* the unit they're describing. These are known as
+      "crossref" directives. Others (``.. class::``, e.g.) generate their own
+      markup; these should go inside the section they're describing. These are
+      called "description units".
+      
+      You can tell which are which by looking at in :file:`_ext/djangodocs.py`;
+      it registers roles as one of the other.
+      
+    * When referring to classes/functions/modules, etc., you'll want to use the
+      fully-qualified name of the target
+      (``:class:`django.contrib.contenttypes.models.ContentType```). 
+      
+      Since this doesn't look all that awesome in the output -- it shows the
+      entire path to the object -- you can prefix the target with a ``~``
+      (that's a tilde) to get just the "last bit" of that path. So
+      ``:class:`~django.contrib.contenttypes.models.ContentType``` will just
+      display a link with the title "ContentType".

+ 22 - 0
docs/internals/index.txt

@@ -0,0 +1,22 @@
+.. _internals-index:
+
+Django internals
+================
+
+Documentation for people hacking on Django itself. This is the place to go if
+you'd like to help improve Django, learn or learn about how Django works "under
+the hood".
+
+.. warning::
+
+    Elsewhere in the Django documentation, coverage of a feature is a sort of a
+    contract: once an API is in the official documentation, we consider it
+    "stable" and don't change it without a good reason. APIs covered here,
+    however, are considered "internal-only": we reserve the right to change
+    these internals if we must.
+
+.. toctree::
+   :maxdepth: 1
+   
+   contributing
+   documentation

BIN
docs/intro/_images/admin01.png


BIN
docs/intro/_images/admin02.png


BIN
docs/intro/_images/admin02t.png


BIN
docs/intro/_images/admin03.png


BIN
docs/intro/_images/admin03t.png


BIN
docs/intro/_images/admin04.png


BIN
docs/intro/_images/admin04t.png


BIN
docs/intro/_images/admin05.png


BIN
docs/intro/_images/admin05t.png


BIN
docs/intro/_images/admin06.png


BIN
docs/intro/_images/admin06t.png


BIN
docs/intro/_images/admin07.png


BIN
docs/intro/_images/admin08.png


BIN
docs/intro/_images/admin08t.png


BIN
docs/intro/_images/admin09.png


BIN
docs/intro/_images/admin10.png


BIN
docs/intro/_images/admin11.png


BIN
docs/intro/_images/admin11t.png


BIN
docs/intro/_images/admin12.png


BIN
docs/intro/_images/admin13.png


BIN
docs/intro/_images/admin13t.png


BIN
docs/intro/_images/admin14.png


BIN
docs/intro/_images/admin14t.png


+ 38 - 0
docs/intro/index.txt

@@ -0,0 +1,38 @@
+.. _intro-index:
+
+Getting started
+===============
+
+New to Django? Or to web development in general? Well, you came to the right
+place: read this material to quickly get up and running.
+
+.. toctree::
+   :maxdepth: 1
+    
+   overview
+   install
+   tutorial01
+   tutorial02
+   tutorial03
+   tutorial04
+   whatsnext
+   
+.. seealso::
+
+    If you're new to Python_, you might want to start by getting an idea of what
+    the language is like. Django is 100% Python, so if you've got minimal
+    comfort with Python you'll probably get a lot more out of Django.
+    
+    If you're new to programming entirely, you might want to start with this
+    `list of Python resources for non-programmers`_
+    
+    If you already know a few other languages and want to get up to speed with
+    Python quickly, we recommend `Dive Into Python`_ (also available in a
+    `dead-tree version`_). If that's not quite your style, there are quite
+    a few other `books about Python`_.
+    
+    .. _python: http://python.org/
+    .. _list of Python resources for non-programmers: http://wiki.python.org/moin/BeginnersGuide/NonProgrammers
+    .. _dive into python: http://diveintopython.org/
+    .. _dead-tree version: http://www.amazon.com/exec/obidos/ASIN/1590593561/ref=nosim/jacobian20
+    .. _books about Python: http://wiki.python.org/moin/PythonBooks

+ 75 - 0
docs/intro/install.txt

@@ -0,0 +1,75 @@
+.. _intro-install:
+
+Quick install guide
+===================
+
+Before you can use Django, you'll need to get it installed. We have a
+:ref:`complete installation guide <topics-install>` that covers all the
+possibilities; this guide will guide you to a simple, minimal installation
+that'll work while you walk through the introduction.
+
+Install Python
+--------------
+
+Being a Python Web framework, Django requires Python. It works with any Python
+version 2.3 and higher, but we recommend installing Python 2.5 or later. If you do so, you won't need to set up a database just yet: Python 2.5 or later includes a lightweight database called SQLite_.
+
+.. _sqlite: http://sqlite.org/
+
+Get Python at http://www.python.org. If you're running Linux or Mac OS X, you
+probably already have it installed.
+
+You can verify that Python's installed py typing ``python`` from your shell; you should see something like::
+
+    Python 2.5.1 (r251:54863, Jan 17 2008, 19:35:17) 
+    [GCC 4.0.1 (Apple Inc. build 5465)] on darwin
+    Type "help", "copyright", "credits" or "license" for more information.
+    >>>
+    
+Set up a database
+-----------------
+
+If you installed Python 2.5 or later, you can skip this step for now.
+
+If not, or if you'd like to work with a "large" database engine like PostgreSQL,
+MySQL, or Oracle, consult the :ref:`database installation information
+<database-installation>`.
+
+Remove any old versions of Django
+---------------------------------
+
+If you are upgrading your installation of Django from a previous version, you
+will need to :ref:`uninstall the old Django version before installing the new
+version <removing-old-versions-of-django>`.
+
+Install Django
+--------------
+
+You've got three easy options to install Django:
+
+    * Install a version of Django :ref:`provided by your operating system
+      distribution <misc-distributions>`. This is the quickest option for those
+      who have operating systems that distribute Django.
+
+    * :ref:`Install an official release <installing-official-release>`. This
+      is the best approach for users who want a stable version number and aren't
+      concerned about running a slightly older version of Django.
+      
+    * :ref:`Install the latest development version
+      <installing-development-version>`. This is best for users who want the
+      latest-and-greatest features and aren't afraid of running brand-new code.
+      
+.. warning::
+
+    If do either of the first two steps, keep an eye out for parts of the
+    documentation marked **new in development version**. That phrase flags
+    features that are only available in development versions of Django; if you
+    try to use them with an official release they won't work.
+    
+That's it!
+----------
+
+That's it -- you can now :ref:`move onto the tutorial <intro-tutorial01>`.
+
+
+

+ 44 - 33
docs/overview.txt → docs/intro/overview.txt

@@ -1,3 +1,5 @@
+.. _intro-overview:
+
 ==================
 Django at a glance
 ==================
@@ -8,10 +10,9 @@ overview of how to write a database-driven Web app with Django.
 
 The goal of this document is to give you enough technical specifics to
 understand how Django works, but this isn't intended to be a tutorial or
-reference. Please see our more-detailed Django documentation_ when you're ready
-to start a project.
-
-.. _documentation: ../
+reference -- but we've got both! When you're ready to start a project, you can
+:ref:`start with the tutorial <intro-tutorial01>` or :ref:`dive right into more
+detailed documentation <topics-index>`.
 
 Design your model
 =================
@@ -20,9 +21,9 @@ Although you can use Django without a database, it comes with an
 object-relational mapper in which you describe your database layout in Python
 code.
 
-The data-model syntax offers many rich ways of representing your models -- so
-far, it's been solving two years' worth of database-schema problems. Here's a
-quick example::
+The :ref:`data-model syntax <topics-db-models>` offers many rich ways of
+representing your models -- so 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(max_length=70)
@@ -43,18 +44,20 @@ Install it
 ==========
 
 Next, run the Django command-line utility to create the database tables
-automatically::
+automatically:
+
+.. code-block:: bash
 
     manage.py syncdb
 
-The ``syncdb`` command looks at all your available models and creates tables
-in your database for whichever tables don't already exist.
+The :djadmin:`syncdb` command looks at all your available models and creates
+tables in your database for whichever tables don't already exist.
 
 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::
+With that, you've got a free, and rich, :ref:`Python API <topics-db-queries>` to
+access your data. The API is created on the fly, no code generation necessary::
 
     >>> from mysite.models import Reporter, Article
 
@@ -128,15 +131,16 @@ 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,
-production ready administrative interface -- a Web site that lets authenticated
-users add, change and delete objects. It's as easy as adding a line of code to
-your model classes::
+production ready :ref:`administrative interface <ref-contrib-admin>` -- a Web
+site that lets authenticated users add, change and delete objects. It's as easy
+as adding a line of code to your model classes::
 
     class Article(models.Model):
         pub_date = models.DateTimeField()
         headline = models.CharField(max_length=200)
         content = models.TextField()
         reporter = models.ForeignKey(Reporter)
+        
         class Admin: pass
 
 The philosophy here is that your site is edited by a staff, or a client, or
@@ -154,10 +158,10 @@ A clean, elegant URL scheme is an important detail in a high-quality Web
 application. Django encourages beautiful URL design and doesn't put any cruft
 in URLs, like ``.php`` or ``.asp``.
 
-To design URLs for an app, you create a Python module called a URLconf. A table
-of contents for your app, it contains a simple mapping between URL patterns and
-Python callback functions. URLconfs also serve to decouple URLs from Python
-code.
+To design URLs for an app, you create a Python module called a :ref:`URLconf
+<topics-http-urls>`. A table of contents for your app, it contains a simple mapping
+between URL patterns and Python callback functions. URLconfs also serve to
+decouple URLs from Python code.
 
 Here's what a URLconf might look like for the ``Reporter``/``Article``
 example above::
@@ -190,8 +194,9 @@ Write your views
 ================
 
 Each view is responsible for doing one of two things: Returning an
-``HttpResponse`` object containing the content for the requested page, or
-raising an exception such as ``Http404``. The rest is up to you.
+:class:`~django.http.HttpResponse` object containing the content for the
+requested page, or raising an exception such as :class:`~django.http.Http404`.
+The rest is up to you.
 
 Generally, a view retrieves data according to the parameters, loads a template
 and renders the template with the retrieved data. Here's an example view for
@@ -201,8 +206,9 @@ and renders the template with the retrieved data. Here's an example view for
         a_list = Article.objects.filter(pub_date__year=year)
         return render_to_response('news/year_archive.html', {'year': year, 'article_list': a_list})
 
-This example uses Django's template system, which has several powerful
-features but strives to stay simple enough for non-programmers to use.
+This example uses Django's :ref:`template system <topics-templates>`, which has
+several powerful features but strives to stay simple enough for non-programmers
+to use.
 
 Design your templates
 =====================
@@ -215,7 +221,9 @@ for templates. If a template doesn't exist in the first directory, it checks the
 second, and so on.
 
 Let's say the ``news/article_detail.html`` template was found. Here's what that
-might look like::
+might look like:
+
+.. code-block:: html+django
 
     {% extends "base.html" %}
 
@@ -252,7 +260,9 @@ Finally, Django uses the concept of "template inheritance": That's what 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.
 
-Here's what the "base.html" template might look like::
+Here's what the "base.html" template might look like:
+
+.. code-block:: html+django
 
     <html>
     <head>
@@ -287,17 +297,18 @@ This is just the surface
 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
-      writing a small Python class.
+    * A :ref:`caching framework <topics-cache>` that integrates with memcached
+      or other backends.
+
+    * A :ref:`syndication framework <ref-contrib-syndication>` 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!
+The next obvious steps are for you to `download Django`_, read :ref:`the
+tutorial <intro-tutorial01>` and join `the community`_. Thanks for your
+interest!
 
 .. _download Django: http://www.djangoproject.com/download/
-.. _the tutorial: ../tutorial01/
 .. _the community: http://www.djangoproject.com/community/

+ 252 - 210
docs/tutorial01.txt → docs/intro/tutorial01.txt

@@ -1,3 +1,5 @@
+.. _intro-tutorial01:
+
 =====================================
 Writing your first Django app, part 1
 =====================================
@@ -12,71 +14,70 @@ It'll consist of two parts:
     * A public site that lets people view polls and vote in them.
     * An admin site that lets you add, change and delete polls.
 
-We'll assume you have `Django installed`_ already. You can tell Django is
-installed by running the Python interactive interpreter and typing
-``import django``. If that command runs successfully, with no errors, Django is
-installed.
-
-.. _`Django installed`: ../install/
+We'll assume you have :ref:`Django installed <intro-install>` already. You can
+tell Django is installed by running the Python interactive interpreter and
+typing ``import django``. If that command runs successfully, with no errors,
+Django is 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`` to chat
+    to `django-users`__ or drop by `#django on irc.freenode.net`__ to chat
     with other Django users who might be able to help.
 
-.. _django-users: http://groups.google.com/group/django-users
-.. _#django: irc://irc.freenode.net/django
+__ http://groups.google.com/group/django-users
+__ irc://irc.freenode.net/django
 
 Creating a project
 ==================
 
 If this is your first time using Django, you'll have to take care of some
-initial setup. Namely, you'll need to auto-generate some code that establishes
-a Django *project* -- a collection of settings for an instance of Django,
+initial setup. Namely, you'll need to auto-generate some code that establishes a
+Django :term:`project` -- a collection of settings for an instance of Django,
 including database configuration, Django-specific options and
 application-specific settings.
 
 From the command line, ``cd`` into a directory where you'd like to store your
-code, then run the command ``django-admin.py startproject mysite``. This
-will create a ``mysite`` directory in your current directory.
+code, then run the command ``django-admin.py startproject mysite``. This will
+create a ``mysite`` directory in your current directory.
 
 .. admonition:: Mac OS X permissions
    
-   If you're using Mac OS X, you may see the message "permission
-   denied" when you try to run ``django-admin.py startproject``. This
-   is because, on Unix-based systems like OS X, a file must be marked
-   as "executable" before it can be run as a program. To do this, open
-   Terminal.app and navigate (using the ``cd`` command) to the directory
-   where ``django-admin.py`` is installed, then run the command
+   If you're using Mac OS X, you may see the message "permission denied" when
+   you try to run ``django-admin.py startproject``. This is because, on
+   Unix-based systems like OS X, a file must be marked as "executable" before it
+   can be run as a program. To do this, open Terminal.app and navigate (using
+   the ``cd`` command) to the directory where :ref:`django-admin.py
+   <ref-django-admin>` is installed, then run the command 
    ``chmod +x django-admin.py``.
 
 .. 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
+    ``django`` (which will conflict with Django itself) or ``test`` (which
     conflicts with a built-in Python package).
 
-(``django-admin.py`` should be on your system path if you installed Django via
-``python setup.py``. If it's not on your path, you can find it in
-``site-packages/django/bin``, where ``site-packages`` is a directory within
-your Python installation. Consider symlinking to ``django-admin.py`` from some
-place on your path, such as ``/usr/local/bin``.)
+:ref:`django-admin.py <ref-django-admin>` should be on your system path if you
+installed Django via ``python setup.py``. If it's not on your path, you can find
+it in ``site-packages/django/bin``, where ```site-packages``` is a directory
+within your Python installation. Consider symlinking to :ref:`django-admin.py
+<ref-django-admin>` from some place on your path, such as
+:file:`/usr/local/bin`.
 
 .. admonition:: Where should this code live?
 
     If your background is in PHP, you're probably used to putting code under the
     Web server's document root (in a place such as ``/var/www``). With Django,
-    you don't do that. It's not a good idea to put any of this Python code within
-    your Web server's document root, because it risks the possibility that
-    people may be able to view your code over the Web. That's not good for
+    you don't do that. It's not a good idea to put any of this Python code
+    within your Web server's document root, because it risks the possibility
+    that people may be able to view your code over the Web. That's not good for
     security.
 
     Put your code in some directory **outside** of the document root, such as
-    ``/home/mycode``.
+    :file:`/home/mycode`.
 
-Let's look at what ``startproject`` created::
+Let's look at what :djadmin:`startproject` created::
 
     mysite/
         __init__.py
@@ -86,28 +87,34 @@ Let's look at what ``startproject`` created::
 
 These files are:
 
-    * ``__init__.py``: An empty file that tells Python that this directory
+    * :file:`__init__.py`: An empty file that tells Python that this directory
       should be considered a Python package. (Read `more about packages`_ in the
       official Python docs if you're a Python beginner.)
-    * ``manage.py``: A command-line utility that lets you interact with this
-      Django project in various ways.
-    * ``settings.py``: Settings/configuration for this Django project.
-    * ``urls.py``: The URL declarations for this Django project; a "table of
-      contents" of your Django-powered site.
+      
+    * :file:`manage.py`: A command-line utility that lets you interact with this
+      Django project in various ways. You can read all the details about
+      :file:`manage.py` in :ref:`ref-django-admin`.
+      
+    * :file:`settings.py`: Settings/configuration for this Django project.
+      :ref:`topics-settings` will tell you all about how settings work.
+    
+    * :file:`urls.py`: The URL declarations for this Django project; a "table of
+      contents" of your Django-powered site. You can read more about URLs in
+      :ref:`topics-http-urls`.
 
 .. _more about packages: http://docs.python.org/tut/node8.html#packages
 
 The development server
 ----------------------
 
-Let's verify this worked. Change into the ``mysite`` directory, if you
+Let's verify this worked. Change into the :file:`mysite` directory, if you
 haven't already, and run the command ``python manage.py runserver``. You'll see
 the following output on the command line::
 
     Validating models...
     0 errors found.
 
-    Django version 0.95, using settings 'mysite.settings'
+    Django version 0.96, using settings 'mysite.settings'
     Development server is running at http://127.0.0.1:8000/
     Quit the server with CONTROL-C (Unix) or CTRL-BREAK (Windows).
 
@@ -126,40 +133,49 @@ It worked!
 
 .. admonition:: Changing the port
 
-    By default, the ``runserver`` command starts the development server on port
-    8000. If you want to change the server's port, pass it as a command-line
-    argument. For instance, this command starts the server on port 8080::
+    By default, the :djadmin:`runserver` command starts the development server
+    on port 8000. If you want to change the server's port, pass it as a
+    command-line argument. For instance, this command starts the server on port
+    8080:
+    
+    .. code-block:: bash
 
         python manage.py runserver 8080
 
-    Full docs for the development server are at `django-admin documentation`_.
+    Full docs for the development server can be found in the
+    :djadmin:`runserver` reference.
 
-.. _django-admin documentation: ../django-admin/
 
 Database setup
 --------------
 
-Now, edit ``settings.py``. It's a normal Python module with module-level
+Now, edit :file:`settings.py`. It's a normal Python module with module-level
 variables representing Django settings. Change these settings to match your
 database's connection parameters:
 
-    * ``DATABASE_ENGINE`` -- Either 'postgresql_psycopg2', 'mysql' or 'sqlite3'.
-      Other backends are `also available`_.
-    * ``DATABASE_NAME`` -- The name of your database. If you're using
-      SQLite, the database will be a file on your computer; in that
-      case, ``DATABASE_NAME`` should be the full absolute path,
-      including filename, of that file. If the file doesn't exist, it
-      will automatically be created when you synchronize the database
-      for the first time (see below).
-    * ``DATABASE_USER`` -- Your database username (not used for SQLite).
-    * ``DATABASE_PASSWORD`` -- Your database password (not used for SQLite).
-    * ``DATABASE_HOST`` -- The host your database is on. Leave this as an
-      empty string if your database server is on the same physical machine
-      (not used for SQLite).
-
-.. _also available: ../settings/
+    * :setting:`DATABASE_ENGINE` -- Either 'postgresql_psycopg2', 'mysql' or
+      'sqlite3'. Other backends are :setting:`also available <DATABASE_ENGINE>`.
+      
+    * :setting:`DATABASE_NAME` -- The name of your database. If you're using
+      SQLite, the database will be a file on your computer; in that case,
+      ``DATABASE_NAME`` should be the full absolute path, including filename, of
+      that file. If the file doesn't exist, it will automatically be created
+      when you synchronize the database for the first time (see below).
+      
+    * :setting:`DATABASE_USER` -- Your database username (not used for SQLite).
+    
+    * :setting:`DATABASE_PASSWORD` -- Your database password (not used for
+      SQLite).
+    
+    * :setting:`DATABASE_HOST` -- The host your database is on. Leave this as an
+      empty string if your database server is on the same physical machine (not
+      used for SQLite).
+
+If you're new to databases, we recommend simply using SQLite (by setting
+:setting:`DATABASE_ENGINE` to ``'sqlite3'``). SQLite is included as part of
+Python 2.5 and later, so you won't need to install anything else.
 
-.. admonition:: Note
+.. note::
 
     If you're using PostgreSQL or MySQL, make sure you've created a database by
     this point. Do that with "``CREATE DATABASE database_name;``" within your
@@ -168,35 +184,39 @@ database's connection parameters:
     If you're using SQLite, you don't need to create anything beforehand - the
     database file will be created automatically when it is needed.
 
-While you're editing ``settings.py``, take note of the ``INSTALLED_APPS``
-setting towards the bottom of the file. That variable holds the names of all
-Django applications that are activated in this Django instance. Apps can be
-used in multiple projects, and you can package and distribute them for use
-by others in their projects.
+While you're editing :file:`settings.py`, take note of the
+:setting:`INSTALLED_APPS` setting towards the bottom of the file. That variable
+holds the names of all Django applications that are activated in this Django
+instance. Apps can be used in multiple projects, and you can package and
+distribute them for use by others in their projects.
+
+By default, :setting:`INSTALLED_APPS` contains the following apps, all of which
+come with Django:
+
+    * :mod:`django.contrib.auth` -- An authentication system.
 
-By default, ``INSTALLED_APPS`` contains the following apps, all of which come
-with Django:
+    * :mod:`django.contrib.contenttypes` -- A framework for content types.
 
-    * ``django.contrib.auth`` -- An authentication system.
-    * ``django.contrib.contenttypes`` -- A framework for content types.
-    * ``django.contrib.sessions`` -- A session framework.
-    * ``django.contrib.sites`` -- A framework for managing multiple sites
+    * :mod:`django.contrib.sessions` -- A session framework.
+
+    * :mod:`django.contrib.sites` -- A framework for managing multiple sites
       with one Django installation.
 
-These applications are included by default as a convenience for the common
-case.
+These applications are included by default as a convenience for the common case.
 
 Each of these applications makes use of at least one database table, though,
 so we need to create the tables in the database before we can use them. To do
-that, run the following command::
+that, run the following command:
+
+.. code-block:: bash
 
     python manage.py syncdb
 
-The ``syncdb`` command looks at the ``INSTALLED_APPS`` setting and creates any
-necessary database tables according to the database settings in your
-``settings.py`` file. You'll see a message for each database table it creates,
-and you'll get a prompt asking you if you'd like to create a superuser account
-for the authentication system. Go ahead and do that.
+The :djadmin:`syncdb` command looks at the :setting:`INSTALLED_APPS` setting and
+creates any necessary database tables according to the database settings in your
+:file:`settings.py` file. You'll see a message for each database table it
+creates, and you'll get a prompt asking you if you'd like to create a superuser
+account for the authentication system. Go ahead and do that.
 
 If you're interested, run the command-line client for your database and type
 ``\dt`` (PostgreSQL), ``SHOW TABLES;`` (MySQL), or ``.schema`` (SQLite) to
@@ -207,8 +227,11 @@ display the tables Django created.
     Like we said above, the default applications are included for the common
     case, but not everybody needs them. If you don't need any or all of them,
     feel free to comment-out or delete the appropriate line(s) from
-    ``INSTALLED_APPS`` before running ``syncdb``. The ``syncdb`` command will
-    only create tables for apps in ``INSTALLED_APPS``.
+    :setting:`INSTALLED_APPS` before running :djadmin:`syncdb`. The
+    :djadmin:`syncdb` command will only create tables for apps in
+    :setting:`INSTALLED_APPS`.
+
+.. _creating-models:
 
 Creating models
 ===============
@@ -229,17 +252,19 @@ so you can focus on writing code rather than creating directories.
     configuration and apps for a particular Web site. A project can contain
     multiple apps. An app can be in multiple projects.
 
-In this tutorial, we'll create our poll app in the ``mysite`` directory,
+In this tutorial, we'll create our poll app in the :file:`mysite` directory,
 for simplicity. As a consequence, the app will be coupled to the project --
 that is, Python code within the poll app will refer to ``mysite.polls``.
 Later in this tutorial, we'll discuss decoupling your apps for distribution.
 
-To create your app, make sure you're in the ``mysite`` directory and type
-this command::
+To create your app, make sure you're in the :file:`mysite` directory and type
+this command:
+
+.. code-block:: bash
 
     python manage.py startapp polls
 
-That'll create a directory ``polls``, which is laid out like this::
+That'll create a directory :file:`polls`, which is laid out like this::
 
     polls/
         __init__.py
@@ -253,17 +278,17 @@ The first step in writing a database Web app in Django is to define your models
 
 .. admonition:: Philosophy
 
-   A model is the single, definitive source of data about your
-   data. It contains the essential fields and behaviors of the data you're
-   storing. Django follows the `DRY Principle`_. The goal is to define your
-   data model in one place and automatically derive things from it.
+   A model is the single, definitive source of data about your data. It contains
+   the essential fields and behaviors of the data you're storing. Django follows
+   the :ref:`DRY Principle <dry>`. The goal is to define your data model in one
+   place and automatically derive things from it.
 
 In our simple poll app, we'll create two models: polls and choices. A poll has
 a question and a publication date. A choice has two fields: the text of the
 choice and a vote tally. Each choice is associated with a poll.
 
 These concepts are represented by simple Python classes. Edit the
-``polls/models.py`` file so it looks like this::
+:file:`polls/models.py` file so it looks like this::
 
     from django.db import models
 
@@ -276,51 +301,54 @@ These concepts are represented by simple Python classes. Edit the
         choice = models.CharField(max_length=200)
         votes = models.IntegerField()
 
-.. admonition:: Errors about ``max_length``
+.. admonition:: Errors about :attr:`~django.db.models.Field.max_length`
 
-   If Django gives you an error message saying that ``max_length`` is
-   not a valid argument, you're most likely using an old version of
-   Django. (This version of the tutorial is written for the latest
-   development version of Django.) If you're using a Subversion checkout
-   of Django's development version (see `the installation docs`_ for
-   more information), you shouldn't have any problems.
+   If Django gives you an error message saying that
+   :attr:`~django.db.models.Field.max_length` is not a valid argument, you're
+   most likely using an old version of Django. (This version of the tutorial is
+   written for the latest development version of Django.) If you're using a
+   Subversion checkout of Django's development version (see :ref:`the
+   installation docs <topics-install>` for more information), you shouldn't have
+   any problems.
 
-   If you want to stick with an older version of Django, you'll want to
-   switch to `the Django 0.96 tutorial`_, because this tutorial covers
-   several features that only exist in the Django development version.
+   If you want to stick with an older version of Django, you'll want to switch
+   to `the Django 0.96 tutorial`_, because this tutorial covers several features
+   that only exist in the Django development version.
 
-.. _the installation docs: ../install/
-.. _the Django 0.96 tutorial: ../0.96/tutorial01/
+.. _the Django 0.96 tutorial: http://www.djangoproject.com/documentation/0.96/tutorial01/
 
 The code is straightforward. Each model is represented by a class that
-subclasses ``django.db.models.Model``. Each model has a number of class
+subclasses :class:`django.db.models.Model`. Each model has a number of class
 variables, each of which represents a database field in the model.
 
-Each field is represented by an instance of a ``models.*Field`` class -- e.g.,
-``models.CharField`` for character fields and ``models.DateTimeField`` for
-datetimes. This tells Django what type of data each field holds.
-
-The name of each ``models.*Field`` instance (e.g. ``question`` or ``pub_date`` )
-is the field's name, in machine-friendly format. You'll use this value in your
-Python code, and your database will use it as the column name.
-
-You can use an optional first positional argument to a ``Field`` to designate a
-human-readable name. That's used in a couple of introspective parts of Django,
-and it doubles as documentation. If this field isn't provided, Django will use
-the machine-readable name. In this example, we've only defined a human-readable
-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 ``max_length``. That's used not only in the database
+Each field is represented by an instance of a :class:`~django.db.models.Field`
+class -- e.g., :class:`~django.db.models.CharField` for character fields and
+:class:`~django.db.models.DateTimeField` for datetimes. This tells Django what
+type of data each field holds.
+
+The name of each :class:`~django.db.models.Field` instance (e.g. ``question`` or
+``pub_date`` ) is the field's name, in machine-friendly format. You'll use this
+value in your Python code, and your database will use it as the column name.
+
+You can use an optional first positional argument to a
+:class:`~django.db.models.Field` to designate a human-readable name. That's used
+in a couple of introspective parts of Django, and it doubles as documentation.
+If this field isn't provided, Django will use the machine-readable name. In this
+example, we've only defined a human-readable 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 :class:`~django.db.models.Field` classes have required elements.
+:class:`~django.db.models.CharField`, for example, requires that you give it a
+:attr:`~django.db.models.Field.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
-Django each Choice is related to a single Poll. Django supports all the common
-database relationships: many-to-ones, many-to-manys and one-to-ones.
+Finally, note a relationship is defined, using
+:class:`~django.db.models.ForeignKey`. That tells Django each Choice is related
+to a single Poll. Django supports all the common database relationships:
+many-to-ones, many-to-manys and one-to-ones.
 
 .. _`Python path`: http://docs.python.org/tut/node8.html#SECTION008110000000000000000
-.. _DRY Principle: http://c2.com/cgi/wiki?DontRepeatYourself
 
 Activating models
 =================
@@ -339,8 +367,9 @@ But first we need to tell our project that the ``polls`` app is installed.
     you can distribute apps, because they don't have to be tied to a given
     Django installation.
 
-Edit the ``settings.py`` file again, and change the ``INSTALLED_APPS`` setting
-to include the string ``'mysite.polls'``. So it'll look like this::
+Edit the :file:`settings.py` file again, and change the
+:setting:`INSTALLED_APPS` setting to include the string ``'mysite.polls'``. So
+it'll look like this::
 
     INSTALLED_APPS = (
         'django.contrib.auth',
@@ -350,12 +379,17 @@ to include the string ``'mysite.polls'``. So it'll look like this::
         'mysite.polls'
     )
 
-Now Django knows ``mysite`` includes the ``polls`` app. Let's run another command::
+Now Django knows ``mysite`` includes the ``polls`` app. Let's run another
+command:
+
+.. code-block:: bash
 
     python manage.py sql polls
 
-You should see something similar to the following (the CREATE TABLE SQL statements
-for the polls app)::
+You should see something similar to the following (the ``CREATE TABLE`` SQL
+statements for the polls app):
+
+.. code-block:: sql
 
     BEGIN;
     CREATE TABLE "polls_poll" (
@@ -384,7 +418,8 @@ Note the following:
     * By convention, Django appends ``"_id"`` to the foreign key field name.
       Yes, you can override this, as well.
 
-    * The foreign key relationship is made explicit by a ``REFERENCES`` statement.
+    * The foreign key relationship is made explicit by a ``REFERENCES``
+      statement.
 
     * It's tailored to the database you're using, so database-specific field
       types such as ``auto_increment`` (MySQL), ``serial`` (PostgreSQL), or
@@ -393,53 +428,58 @@ Note the following:
       quotes. The author of this tutorial runs PostgreSQL, so the example
       output is in PostgreSQL syntax.
 
-    * The ``sql`` command doesn't actually run the SQL in your database - it just
-      prints it to the screen so that you can see what SQL Django thinks is required.
-      If you wanted to, you could copy and paste this SQL into your database prompt.
-      However, as we will see shortly, Django provides an easier way of committing
-      the SQL to the database.
+    * The :djadmin:`sql` command doesn't actually run the SQL in your database -
+      it just prints it to the screen so that you can see what SQL Django thinks
+      is required. If you wanted to, you could copy and paste this SQL into your
+      database prompt. However, as we will see shortly, Django provides an
+      easier way of committing the SQL to the database.
 
 If you're interested, also run the following commands:
-    * ``python manage.py validate`` -- Checks for any errors in the
-      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.
+    * :djadmin:`python manage.py validate <validate>` -- Checks for any errors
+      in the construction of your models.
 
-    * ``python manage.py sqlclear polls`` -- Outputs the necessary ``DROP
-      TABLE`` statements for this app, according to which tables already exist
-      in your database (if any).
+    * :djadmin:`python manage.py sqlcustom polls <sqlcustom>` -- Outputs any
+      :ref:`custom SQL statements <initial-sql>` (such as table modifications or
+      constraints) that are defined for the application.
 
-    * ``python manage.py sqlindexes polls`` -- Outputs the ``CREATE INDEX``
-      statements for this app.
+    * :djadmin:`python manage.py sqlclear polls <sqlclear>` -- Outputs the
+      necessary ``DROP TABLE`` statements for this app, according to which
+      tables already exist in your database (if any).
 
-    * ``python manage.py sqlall polls`` -- A combination of all the SQL from
-      the 'sql', 'sqlcustom', and 'sqlindexes' commands.
+    * :djadmin:`python manage.py sqlindexes polls <sqlindexes>` -- Outputs the
+      ``CREATE INDEX`` statements for this app.
+
+    * :djadmin:`python manage.py sqlall polls <sqlall>` -- A combination of all
+      the SQL from the :djadmin:`sql`, :djadmin:`sqlcustom`, and
+      :djadmin:`sqlindexes` commands.
 
 Looking at the output of those commands can help you understand what's actually
 happening under the hood.
 
-Now, run ``syncdb`` again to create those model tables in your database::
+Now, run :djadmin:`syncdb` again to create those model tables in your database:
 
-    python manage.py syncdb
+.. code-block:: bash
 
-The ``syncdb`` command runs the sql from 'sqlall' on your database for all apps
-in ``INSTALLED_APPS`` that don't already exist in your database. This creates
-all the tables, initial data and indexes for any apps you have added to your
-project since the last time you ran syncdb. ``syncdb`` can be called as often
-as you like, and it will only ever create the tables that don't exist.
+    python manage.py syncdb
 
-Read the `django-admin.py documentation`_ for full information on what the
-``manage.py`` utility can do.
+The :djadmin:`syncdb` command runs the sql from 'sqlall' on your database for
+all apps in :setting:`INSTALLED_APPS` that don't already exist in your database.
+This creates all the tables, initial data and indexes for any apps you have
+added to your project since the last time you ran syncdb. :djadmin:`syncdb` can
+be called as often as you like, and it will only ever create the tables that
+don't exist.
 
-.. _django-admin.py documentation: ../django-admin/
+Read the :ref:`django-admin.py documentation <ref-django-admin>` for full
+information on what the ``manage.py`` utility can do.
 
 Playing with the API
 ====================
 
 Now, let's hop into the interactive Python shell and play around with the free
-API Django gives you. To invoke the Python shell, use this command::
+API Django gives you. To invoke the Python shell, use this command:
+
+.. code-block:: bash
 
     python manage.py shell
 
@@ -449,28 +489,28 @@ things:
 
     * Putting ``mysite`` on ``sys.path``. For flexibility, several pieces of
       Django refer to projects in Python dotted-path notation (e.g.
-      ``'mysite.polls.models'``). In order for this to work, the
-      ``mysite`` package has to be on ``sys.path``.
+      ``'mysite.polls.models'``). In order for this to work, the ``mysite``
+      package has to be on ``sys.path``.
 
-      We've already seen one example of this: the ``INSTALLED_APPS`` setting is
-      a list of packages in dotted-path notation.
+      We've already seen one example of this: the :setting:`INSTALLED_APPS`
+      setting is a list of packages in dotted-path notation.
 
     * Setting the ``DJANGO_SETTINGS_MODULE`` environment variable, which gives
       Django the path to your ``settings.py`` file.
 
 .. admonition:: Bypassing manage.py
 
-    If you'd rather not use ``manage.py``, no problem. Just make sure
-    ``mysite`` is at the root level on the Python path (i.e.,
-    ``import mysite`` works) and set the ``DJANGO_SETTINGS_MODULE``
-    environment variable to ``mysite.settings``.
+    If you'd rather not use ``manage.py``, no problem. Just make sure ``mysite``
+    is at the root level on the Python path (i.e., ``import mysite`` works) and
+    set the ``DJANGO_SETTINGS_MODULE`` environment variable to
+    ``mysite.settings``.
 
-    For more information on all of this, see the `django-admin.py documentation`_.
+    For more information on all of this, see the :ref:`django-admin.py
+    documentation <ref-django-admin>`.
 
-Once you're in the shell, explore the database API::
+Once you're in the shell, explore the :ref:`database API <topics-db-queries>`::
 
-    # Import the model classes we just wrote.
-    >>> from mysite.polls.models import Poll, Choice
+    >>> from mysite.polls.models import Poll, Choice # Import the model classes we just wrote.
 
     # No polls are in the system yet.
     >>> Poll.objects.all()
@@ -505,10 +545,11 @@ Once you're in the shell, explore the database API::
     [<Poll: Poll object>]
 
 
-Wait a minute. ``<Poll: Poll object>`` is, utterly, an unhelpful
-representation of this object. Let's fix that by editing the polls model (in
-the ``polls/models.py`` file) and adding a ``__unicode__()`` method to both
-``Poll`` and ``Choice``::
+Wait a minute. ``<Poll: Poll object>`` is, utterly, an unhelpful representation
+of this object. Let's fix that by editing the polls model (in the
+``polls/models.py`` file) and adding a
+:meth:`~django.db.models.Model.__unicode__` method to both ``Poll`` and
+``Choice``::
 
     class Poll(models.Model):
         # ...
@@ -520,43 +561,46 @@ the ``polls/models.py`` file) and adding a ``__unicode__()`` method to both
         def __unicode__(self):
             return self.choice
 
-.. admonition:: If ``__unicode__()`` doesn't seem to work
+.. admonition:: If :meth:`~django.db.models.Model.__unicode__` doesn't seem to work
 
-   If you add the ``__unicode__()`` method to your models and don't
-   see any change in how they're represented, you're most likely using
-   an old version of Django. (This version of the tutorial is written
-   for the latest development version of Django.) If you're using a
-   Subversion checkout of of Django's development version (see `the
-   installation docs`_ for more information), you shouldn't have any
-   problems.
+   If you add the :meth:`~django.db.models.Model.__unicode__` method to your
+   models and don't see any change in how they're represented, you're most
+   likely using an old version of Django. (This version of the tutorial is
+   written for the latest development version of Django.) If you're using a
+   Subversion checkout of of Django's development version (see :ref:`the
+   installation docs <topics-install>` for more information), you shouldn't have
+   any problems.
 
-   If you want to stick with an older version of Django, you'll want to
-   switch to `the Django 0.96 tutorial`_, because this tutorial covers
-   several features that only exist in the Django development version.
+   If you want to stick with an older version of Django, you'll want to switch
+   to `the Django 0.96 tutorial`_, because this tutorial covers several features
+   that only exist in the Django development version.
 
-.. _the installation docs: ../install/
-.. _the Django 0.96 tutorial: ../0.96/tutorial01/
+.. _the Django 0.96 tutorial: http://www.djangoproject.com/documentation/0.96/tutorial01/
 
-It's important to add ``__unicode__()`` methods to your models, not only for
-your own sanity when dealing with the interactive prompt, but also because
-objects' representations are used throughout Django's automatically-generated
-admin.
+It's important to add :meth:`~django.db.models.Model.__unicode__` methods to
+your models, not only for your own sanity when dealing with the interactive
+prompt, but also because objects' representations are used throughout Django's
+automatically-generated admin.
 
-.. admonition:: Why ``__unicode__()`` and not ``__str__()``?
+.. admonition:: Why :meth:`~django.db.models.Model.__unicode__` and not 
+                :meth:`django.db.models.Model.__str__`?
 
     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.
-
-    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.
+    :meth:`django.db.models.Model.__str__` methods to your classes, not
+    :meth:`~django.db.models.Model.__unicode__` methods. We use
+    :meth:`~django.db.models.Model.__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 :meth:`django.db.models.Model.__str__` method
+    that calls :meth:`~django.db.models.Model.__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
+    :meth:`~django.db.models.Model.__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::
@@ -639,10 +683,8 @@ Let's jump back into the Python interactive shell by running
     >>> c = p.choice_set.filter(choice__startswith='Just hacking')
     >>> c.delete()
 
-For full details on the database API, see our `Database API reference`_.
-
-When you're comfortable with the API, read `part 2 of this tutorial`_ to get
-Django's automatic admin working.
+For full details on the database API, see our :ref:`Database API reference
+<topics-db-queries>`.
 
-.. _Database API reference: ../db-api/
-.. _part 2 of this tutorial: ../tutorial02/
+When you're comfortable with the API, read :ref:`part 2 of this tutorial
+<intro-tutorial02>` to get Django's automatic admin working.

+ 86 - 90
docs/tutorial02.txt → docs/intro/tutorial02.txt

@@ -1,26 +1,27 @@
+.. _intro-tutorial02:
+
 =====================================
 Writing your first Django app, part 2
 =====================================
 
-This tutorial begins where `Tutorial 1`_ left off. We're continuing the Web-poll
-application and will focus on Django's automatically-generated admin site.
-
-.. _Tutorial 1: ../tutorial01/
+This tutorial begins where :ref:`Tutorial 1 <intro-tutorial01>` left off. We're
+continuing the Web-poll application and will focus on Django's
+automatically-generated admin site.
 
 .. admonition:: Philosophy
 
     Generating admin sites for your staff or clients to add, change and delete
-    content is tedious work that doesn't require much creativity. For that reason,
-    Django entirely automates creation of admin interfaces for models.
-
+    content is tedious work that doesn't require much creativity. For that
+    reason, Django entirely automates creation of admin interfaces for models.
+    
     Django was written in a newsroom environment, with a very clear separation
     between "content publishers" and the "public" site. Site managers use the
     system to add news stories, events, sports scores, etc., and that content is
-    displayed on the public site. Django solves the problem of creating a unified
-    interface for site administrators to edit content.
-
-    The admin isn't necessarily intended to be used by site visitors; it's for site
-    managers.
+    displayed on the public site. Django solves the problem of creating a
+    unified interface for site administrators to edit content.
+    
+    The admin isn't necessarily intended to be used by site visitors; it's for
+    site managers.
 
 Activate the admin site
 =======================
@@ -28,10 +29,10 @@ Activate the admin site
 The Django admin site is not activated by default -- it's an opt-in thing. To
 activate the admin site for your installation, do these three things:
 
-    * Add ``"django.contrib.admin"`` to your ``INSTALLED_APPS`` setting.
+    * Add ``"django.contrib.admin"`` to your :setting:`INSTALLED_APPS` setting.
     
     * Run ``python manage.py syncdb``. Since you have added a new application
-      to ``INSTALLED_APPS``, the database tables need to be updated.
+      to :setting:`INSTALLED_APPS`, the database tables need to be updated.
       
     * Edit your ``mysite/urls.py`` file and uncomment the lines below the
       "Uncomment this for admin:" comments. This file is a URLconf; we'll dig
@@ -65,14 +66,16 @@ Start the development server
 
 Let's start the development server and explore the admin site.
 
-Recall from Tutorial 1 that you start the development server like so::
+Recall from Tutorial 1 that you start the development server like so:
+
+.. code-block:: bash
 
     python manage.py runserver
 
 Now, open a Web browser and go to "/admin/" on your local domain -- e.g.,
 http://127.0.0.1:8000/admin/. You should see the admin's login screen:
 
-.. image:: http://media.djangoproject.com/img/doc/tutorial-trunk/admin01.png
+.. image:: _images/admin01.png
    :alt: Django admin login screen
 
 Enter the admin site
@@ -81,24 +84,22 @@ Enter the admin site
 Now, try logging in. (You created a superuser account in the first part of this
 tutorial, remember?) You should see the Django admin index page:
 
-.. image:: http://media.djangoproject.com/img/doc/tutorial-trunk/admin02t.png
+.. image:: _images/admin02t.png
    :alt: Django admin index page
-   :target: http://media.djangoproject.com/img/doc/tutorial-trunk/admin02.png
 
 You should see a few other types of editable content, including groups, users
 and sites. These are core features Django ships with by default.
 
-.. _"I can't log in" questions: ../faq/#the-admin-site
-
 Make the poll app modifiable in the admin
 =========================================
 
 But where's our poll app? It's not displayed on the admin index page.
 
 Just one thing to do: We need to tell the admin that ``Poll``
-objects have an admin interface. Edit the ``mysite/polls/models.py`` file and
+objects have an admin interface. Edit the ``mysite/polls/admin.py`` file and
 add the following to the bottom of the file::
 
+    from mysite.polls.models import Poll
     from django.contrib import admin
     
     admin.site.register(Poll)
@@ -113,52 +114,54 @@ Explore the free admin functionality
 Now that we've registered ``Poll``, Django knows that it should be displayed on
 the admin index page:
 
-.. image:: http://media.djangoproject.com/img/doc/tutorial-trunk/admin03t.png
+.. image:: _images/admin03t.png
    :alt: Django admin index page, now with polls displayed
-   :target: http://media.djangoproject.com/img/doc/tutorial-trunk/admin03.png
 
 Click "Polls." Now you're at the "change list" page for polls. This page
 displays all the polls in the database and lets you choose one to change it.
 There's the "What's up?" poll we created in the first tutorial:
 
-.. image:: http://media.djangoproject.com/img/doc/tutorial-trunk/admin04t.png
+.. image:: _images/admin04t.png
    :alt: Polls change list page
-   :target: http://media.djangoproject.com/img/doc/tutorial-trunk/admin04.png
 
 Click the "What's up?" poll to edit it:
 
-.. image:: http://media.djangoproject.com/img/doc/tutorial-trunk/admin05t.png
+.. image:: _images/admin05t.png
    :alt: Editing form for poll object
-   :target: http://media.djangoproject.com/img/doc/tutorial-trunk/admin05.png
 
 Things to note here:
 
-* The form is automatically generated from the Poll model.
-* The different model field types (``models.DateTimeField``, ``models.CharField``)
-  correspond to the appropriate HTML input widget. Each type of field knows
-  how to display itself in the Django admin.
-* Each ``DateTimeField`` gets free JavaScript shortcuts. Dates get a "Today"
-  shortcut and calendar popup, and times get a "Now" shortcut and a convenient
-  popup that lists commonly entered times.
+    * The form is automatically generated from the Poll model.
+    
+    * The different model field types (:class:`~django.db.models.DateTimeField`,
+      :class:`~django.db.models.CharField`) correspond to the appropriate HTML
+      input widget. Each type of field knows how to display itself in the Django
+      admin.
+    
+    * Each :class:`~django.db.models.DateTimeField` gets free JavaScript
+      shortcuts. Dates get a "Today" shortcut and calendar popup, and times get
+      a "Now" shortcut and a convenient popup that lists commonly entered times.
 
 The bottom part of the page gives you a couple of options:
 
-* Save -- Saves changes and returns to the change-list page for this type of
-  object.
-* Save and continue editing -- Saves changes and reloads the admin page for
-  this object.
-* Save and add another -- Saves changes and loads a new, blank form for this
-  type of object.
-* Delete -- Displays a delete confirmation page.
+    * Save -- Saves changes and returns to the change-list page for this type of
+      object.
+      
+    * Save and continue editing -- Saves changes and reloads the admin page for
+      this object.
+      
+    * Save and add another -- Saves changes and loads a new, blank form for this
+      type of object.
+      
+    * Delete -- Displays a delete confirmation page.
 
 Change the "Date published" by clicking the "Today" and "Now" shortcuts. Then
 click "Save and continue editing." Then click "History" in the upper right.
 You'll see a page listing all changes made to this object via the Django admin,
 with the timestamp and username of the person who made the change:
 
-.. image:: http://media.djangoproject.com/img/doc/tutorial-trunk/admin06t.png
+.. image:: _images/admin06t.png
    :alt: History page for poll object
-   :target: http://media.djangoproject.com/img/doc/tutorial-trunk/admin06.png
 
 Customize the admin form
 ========================
@@ -184,7 +187,7 @@ admin options for an object.
 This particular change above makes the "Publication date" come before the
 "Question" field:
 
-.. image:: http://media.djangoproject.com/img/doc/tutorial-trunk/admin07.png
+.. image:: _images/admin07.png
    :alt: Fields have been reordered
 
 This isn't impressive with only two fields, but for admin forms with dozens
@@ -204,9 +207,8 @@ up into fieldsets::
 The first element of each tuple in ``fieldsets`` is the title of the fieldset.
 Here's what our form looks like now:
 
-.. image:: http://media.djangoproject.com/img/doc/tutorial-trunk/admin08t.png
+.. image:: _images/admin08t.png
    :alt: Form has fieldsets now
-   :target: http://media.djangoproject.com/img/doc/tutorial-trunk/admin08.png
 
 You can assign arbitrary HTML classes to each fieldset. Django provides a
 ``"collapse"`` class that displays a particular fieldset initially collapsed.
@@ -219,7 +221,7 @@ aren't commonly used::
                 ('Date information', {'fields': ['pub_date'], 'classes': ['collapse']}),
             ]
 
-.. image:: http://media.djangoproject.com/img/doc/tutorial-trunk/admin09.png
+.. image:: _images/admin09.png
    :alt: Fieldset is initially collapsed
 
 Adding related objects
@@ -232,18 +234,21 @@ Yet.
 
 There are two ways to solve this problem. The first register ``Choice`` with the
 admin just as we did with ``Poll``. That's easy::
-
+    
+    from mysite.polls.models import Choice
+    
     admin.site.register(Choice)
 
 Now "Choices" is an available option in the Django admin. The "Add choice" form
 looks like this:
 
-.. image:: http://media.djangoproject.com/img/doc/tutorial-trunk/admin10.png
+.. image:: _images/admin10.png
    :alt: Choice admin page
 
 In that form, the "Poll" field is a select box containing every poll in the
-database. Django knows that a ``ForeignKey`` should be represented in the admin
-as a ``<select>`` box. In our case, only one poll exists at this point.
+database. Django knows that a :class:`~django.db.models.ForeignKey` should be
+represented in the admin as a ``<select>`` box. In our case, only one poll
+exists at this point.
 
 Also note the "Add Another" link next to "Poll." Every object with a
 ``ForeignKey`` relationship to another gets this for free. When you click "Add
@@ -259,6 +264,7 @@ Poll object. Let's make that happen.
 Remove the ``register()`` call for the Choice model. Then, edit the ``Poll``
 registration code to read::
 
+    poll = models.ForeignKey(Poll, edit_inline=models.STACKED, num_in_admin=3)
     class ChoiceInline(admin.StackedInline):
         model = Choice
         extra = 3
@@ -277,16 +283,15 @@ default, provide enough fields for 3 choices."
 
 Load the "Add poll" page to see how that looks:
 
-.. image:: http://media.djangoproject.com/img/doc/tutorial-trunk/admin11t.png
+.. image:: _images/admin11t.png
    :alt: Add poll page now has choices on it
-   :target: http://media.djangoproject.com/img/doc/tutorial-trunk/admin11.png
 
 It works like this: There are three slots for related Choices -- as specified
 by ``extra`` -- and each time you come back to the "Change" page for an
 already-created object, you get another three extra slots.
 
 One small problem, though. It takes a lot of screen space to display all the
-fields for entering related Choice objects. For that reason, Django offers an
+fields for entering related Choice objects. For that reason, Django offers a
 tabular way of displaying inline related objects; you just need to change
 the ``ChoiceInline`` declaration to read::
 
@@ -296,7 +301,7 @@ the ``ChoiceInline`` declaration to read::
 With that ``TabularInline`` (instead of ``StackedInline``), the
 related objects are displayed in a more compact, table-based format:
 
-.. image:: http://media.djangoproject.com/img/doc/tutorial-trunk/admin12.png
+.. image:: _images/admin12.png
    :alt: Add poll page now has more compact choices
 
 Customize the admin change list
@@ -307,9 +312,8 @@ Now that the Poll admin page is looking good, let's make some tweaks to the
 
 Here's what it looks like at this point:
 
-.. image:: http://media.djangoproject.com/img/doc/tutorial-trunk/admin04t.png
+.. image:: _images/admin04t.png
    :alt: Polls change list page
-   :target: http://media.djangoproject.com/img/doc/tutorial-trunk/admin04.png
 
 By default, Django displays the ``str()`` of each object. But sometimes it'd be
 more helpful if we could display individual fields. To do that, use the
@@ -329,9 +333,8 @@ method from Tutorial 1::
 
 Now the poll change list page looks like this:
 
-.. image:: http://media.djangoproject.com/img/doc/tutorial-trunk/admin13t.png
+.. image:: _images/admin13t.png
    :alt: Polls change list page, updated
-   :target: http://media.djangoproject.com/img/doc/tutorial-trunk/admin13.png
 
 You can click on the column headers to sort by those values -- except in the
 case of the ``was_published_today`` header, because sorting by the output of
@@ -352,9 +355,8 @@ following line to ``PollAdmin``::
 That adds a "Filter" sidebar that lets people filter the change list by the
 ``pub_date`` field:
 
-.. image:: http://media.djangoproject.com/img/doc/tutorial-trunk/admin14t.png
+.. image:: _images/admin14t.png
    :alt: Polls change list page, updated
-   :target: http://media.djangoproject.com/img/doc/tutorial-trunk/admin14.png
 
 The type of filter displayed depends on the type of field you're filtering on.
 Because ``pub_date`` is a DateTimeField, Django knows to give the default
@@ -395,11 +397,12 @@ is powered by Django itself, and its interfaces use Django's own template
 system. (How meta!)
 
 Open your settings file (``mysite/settings.py``, remember) and look at the
-``TEMPLATE_DIRS`` setting. ``TEMPLATE_DIRS`` is a tuple of filesystem
-directories to check when loading Django templates. It's a search path.
+:setting:`TEMPLATE_DIRS` setting. :setting:`TEMPLATE_DIRS` is a tuple of
+filesystem directories to check when loading Django templates. It's a search
+path.
 
-By default, ``TEMPLATE_DIRS`` is empty. So, let's add a line to it, to tell
-Django where our templates live::
+By default, :setting:`TEMPLATE_DIRS` is empty. So, let's add a line to it, to
+tell Django where our templates live::
 
     TEMPLATE_DIRS = (
         "/home/my_username/mytemplates", # Change this to your own directory.
@@ -407,9 +410,10 @@ Django where our templates live::
 
 Now copy the template ``admin/base_site.html`` from within the default Django
 admin template directory (``django/contrib/admin/templates``) into an ``admin``
-subdirectory of whichever directory you're using in ``TEMPLATE_DIRS``. For
-example, if your ``TEMPLATE_DIRS`` includes ``"/home/my_username/mytemplates"``,
-as above, then copy ``django/contrib/admin/templates/admin/base_site.html`` to
+subdirectory of whichever directory you're using in :setting:`TEMPLATE_DIRS`.
+For example, if your :setting:`TEMPLATE_DIRS` includes
+``"/home/my_username/mytemplates"``, as above, then copy
+``django/contrib/admin/templates/admin/base_site.html`` to
 ``/home/my_username/mytemplates/admin/base_site.html``. Don't forget that
 ``admin`` subdirectory.
 
@@ -421,13 +425,11 @@ override a template, just do the same thing you did with ``base_site.html`` --
 copy it from the default directory into your custom directory, and make
 changes.
 
-Astute readers will ask: But if ``TEMPLATE_DIRS`` was empty by default, how was
-Django finding the default admin templates? The answer is that, by default,
-Django automatically looks for a ``templates/`` subdirectory within each app
-package, for use as a fallback. See the `loader types documentation`_ for full
-information.
-
-.. _loader types documentation: ../templates_python/#loader-types
+Astute readers will ask: But if :setting:`TEMPLATE_DIRS` was empty by default,
+how was Django finding the default admin templates? The answer is that, by
+default, Django automatically looks for a ``templates/`` subdirectory within
+each app package, for use as a fallback. See the :ref:`template loader
+documentation <template-loaders>` for full information.
 
 Customize the admin index page
 ==============================
@@ -435,10 +437,10 @@ Customize the admin index page
 On a similar note, you might want to customize the look and feel of the Django
 admin index page.
 
-By default, it displays all the apps in your ``INSTALLED_APPS`` setting that
-have been registered with the admin application, in alphabetical order. You
-may want to make significant changes to the layout. After all, the index is
-probably the most important page of the admin, and it should be easy to use.
+By default, it displays all the apps in :setting:`INSTALLED_APPS` that have been
+registered with the admin application, in alphabetical order. You may want to
+make significant changes to the layout. After all, the index is probably the
+most important page of the admin, and it should be easy to use.
 
 The template to customize is ``admin/index.html``. (Do the same as with
 ``admin/base_site.html`` in the previous section -- copy it from the default
@@ -447,15 +449,9 @@ uses a template variable called ``app_list``. That variable contains every
 installed Django app. Instead of using that, you can hard-code links to
 object-specific admin pages in whatever way you think is best.
 
-Django offers another shortcut in this department. Run the command
-``python manage.py adminindex polls`` to get a chunk of template code for
-inclusion in the admin index template. It's a useful starting point.
-
-For full details on customizing the look and feel of the Django admin site in
-general, see the `Django admin CSS guide`_.
-
-When you're comfortable with the admin site, read `part 3 of this tutorial`_ to
-start working on public poll views.
+Django offers another shortcut in this department. Run the command ``python
+manage.py adminindex polls`` to get a chunk of template code for inclusion in
+the admin index template. It's a useful starting point.
 
-.. _Django admin CSS guide: ../admin_css/
-.. _part 3 of this tutorial: ../tutorial03/
+When you're comfortable with the admin site, read :ref:`part 3 of this tutorial
+<intro-tutorial03>` to start working on public poll views.

+ 133 - 111
docs/tutorial03.txt → docs/intro/tutorial03.txt

@@ -1,11 +1,12 @@
+.. _intro-tutorial03:
+
 =====================================
 Writing your first Django app, part 3
 =====================================
 
-This tutorial begins where `Tutorial 2`_ left off. We're continuing the Web-poll
-application and will focus on creating the public interface -- "views."
-
-.. _Tutorial 2: ../tutorial02/
+This tutorial begins where :ref:`Tutorial 2 <intro-tutorial02>` left off. We're
+continuing the Web-poll application and will focus on creating the public
+interface -- "views."
 
 Philosophy
 ==========
@@ -15,20 +16,28 @@ a specific function and has a specific template. For example, in a weblog
 application, you might have the following views:
 
     * Blog homepage -- displays the latest few entries.
+    
     * Entry "detail" page -- permalink page for a single entry.
+    
     * Year-based archive page -- displays all months with entries in the
       given year.
+      
     * Month-based archive page -- displays all days with entries in the
       given month.
+      
     * Day-based archive page -- displays all entries in the given day.
+    
     * Comment action -- handles posting comments to a given entry.
 
 In our poll application, we'll have the following four views:
 
     * Poll "archive" page -- displays the latest few polls.
+    
     * Poll "detail" page -- displays a poll question, with no results but
       with a form to vote.
+    
     * Poll "results" page -- displays results for a particular poll.
+    
     * Vote action -- handles voting for a particular choice in a particular
       poll.
 
@@ -42,8 +51,8 @@ creating a Python module, called a URLconf. URLconfs are how Django associates
 a given URL with given Python code.
 
 When a user requests a Django-powered page, the system looks at the
-``ROOT_URLCONF`` setting, which contains a string in Python dotted syntax.
-Django loads that module and looks for a module-level variable called
+:setting:`ROOT_URLCONF` setting, which contains a string in Python dotted
+syntax. Django loads that module and looks for a module-level variable called
 ``urlpatterns``, which is a sequence of tuples in the following format::
 
     (regular expression, Python callback function [, optional dictionary])
@@ -53,17 +62,19 @@ comparing the requested URL against each regular expression until it finds one
 that matches.
 
 When it finds a match, Django calls the Python callback function, with an
-``HTTPRequest`` object as the first argument, any "captured" values from the
-regular expression as keyword arguments, and, optionally, arbitrary keyword
-arguments from the dictionary (an optional third item in the tuple).
+:class:`~django.http.HttpRequest` object as the first argument, any "captured"
+values from the regular expression as keyword arguments, and, optionally,
+arbitrary keyword arguments from the dictionary (an optional third item in the
+tuple).
 
-For more on ``HTTPRequest`` objects, see the `request and response documentation`_.
-For more details on URLconfs, see the `URLconf documentation`_.
+For more on :class:`~django.http.HttpRequest` objects, see the
+:ref:`ref-request-response`. For more details on URLconfs, see the
+:ref:`topics-http-urls`.
 
 When you ran ``python django-admin.py startproject mysite`` at the beginning of
 Tutorial 1, it created a default URLconf in ``mysite/urls.py``. It also
-automatically set your ``ROOT_URLCONF`` setting (in ``settings.py``) to point
-at that file::
+automatically set your :setting:`ROOT_URLCONF` setting (in ``settings.py``) to
+point at that file::
 
     ROOT_URLCONF = 'mysite.urls'
 
@@ -78,27 +89,27 @@ Time for an example. Edit ``mysite/urls.py`` so it looks like this::
         (r'^polls/(?P<poll_id>\d+)/vote/$', 'mysite.polls.views.vote'),
     )
 
-This is worth a review. When somebody requests a page from your Web site --
-say, "/polls/23/", Django will load this Python module, because it's pointed to
-by the ``ROOT_URLCONF`` setting. It finds the variable named ``urlpatterns``
+This is worth a review. When somebody requests a page from your Web site -- say,
+"/polls/23/", Django will load this Python module, because it's pointed to by
+the :setting:`ROOT_URLCONF` setting. It finds the variable named ``urlpatterns``
 and traverses the regular expressions in order. When it finds a regular
 expression that matches -- ``r'^polls/(?P<poll_id>\d+)/$'`` -- it loads the
 associated Python package/module: ``mysite.polls.views.detail``. That
-corresponds to the function ``detail()`` in ``mysite/polls/views.py``.
-Finally, it calls that ``detail()`` function like so::
+corresponds to the function ``detail()`` in ``mysite/polls/views.py``. Finally,
+it calls that ``detail()`` function like so::
 
     detail(request=<HttpRequest object>, poll_id='23')
 
-The ``poll_id='23'`` part comes from ``(?P<poll_id>\d+)``. Using parenthesis around a
-pattern "captures" the text matched by that pattern and sends it as an argument
-to the view function; the ``?P<poll_id>`` defines the name that will be used to
-identify the matched pattern; and ``\d+`` is a regular expression to match a sequence of
-digits (i.e., a number).
+The ``poll_id='23'`` part comes from ``(?P<poll_id>\d+)``. Using parenthesis
+around a pattern "captures" the text matched by that pattern and sends it as an
+argument to the view function; the ``?P<poll_id>`` defines the name that will be
+used to identify the matched pattern; and ``\d+`` is a regular expression to
+match a sequence of digits (i.e., a number).
 
 Because the URL patterns are regular expressions, there really is no limit on
-what you can do with them. And there's no need to add URL cruft such as
-``.php`` -- unless you have a sick sense of humor, in which case you can do
-something like this::
+what you can do with them. And there's no need to add URL cruft such as ``.php``
+-- unless you have a sick sense of humor, in which case you can do something
+like this::
 
     (r'^polls/latest\.php$', 'mysite.polls.views.index'),
 
@@ -110,16 +121,14 @@ the URLconf will look for ``/myapp/``. In a request to
 ``http://www.example.com/myapp/?page=3``, the URLconf will look for ``/myapp/``.
 
 If you need help with regular expressions, see `Wikipedia's entry`_ and the
-`Python documentation`_. Also, the O'Reilly book "Mastering Regular
-Expressions" by Jeffrey Friedl is fantastic.
+`Python documentation`_. Also, the O'Reilly book "Mastering Regular Expressions"
+by Jeffrey Friedl is fantastic.
 
 Finally, a performance note: these regular expressions are compiled the first
 time the URLconf module is loaded. They're super fast.
 
 .. _Wikipedia's entry: http://en.wikipedia.org/wiki/Regular_expression
 .. _Python documentation: http://www.python.org/doc/current/lib/module-re.html
-.. _request and response documentation: ../request_response/
-.. _URLconf documentation: ../url_dispatch/
 
 Write your first view
 =====================
@@ -127,7 +136,9 @@ Write your first view
 Well, we haven't created any views yet -- we just have the URLconf. But let's
 make sure Django is following the URLconf properly.
 
-Fire up the Django development Web server::
+Fire up the Django development Web server:
+
+.. code-block:: bash
 
     python manage.py runserver
 
@@ -170,21 +181,22 @@ provide in the URL.
 Write views that actually do something
 ======================================
 
-Each view is responsible for doing one of two things: Returning an ``HttpResponse``
-object containing the content for the requested page, or raising an exception
-such as ``Http404``. The rest is up to you.
+Each view is responsible for doing one of two things: Returning an
+:class:`~django.http.HttpResponse` object containing the content for the
+requested page, or raising an exception such as :exc:`~django.http.Http404`. The
+rest is up to you.
 
 Your view can read records from a database, or not. It can use a template
 system such as Django's -- or a third-party Python template system -- or not.
 It can generate a PDF file, output XML, create a ZIP file on the fly, anything
 you want, using whatever Python libraries you want.
 
-All Django wants is that ``HttpResponse``. Or an exception.
+All Django wants is that :class:`~django.http.HttpResponse`. Or an exception.
 
 Because it's convenient, let's use Django's own database API, which we covered
-in Tutorial 1. Here's one stab at the ``index()`` view, which displays the
-latest 5 poll questions in the system, separated by commas, according to
-publication date::
+in :ref:`Tutorial 1 <intro-tutorial01>`. Here's one stab at the ``index()``
+view, which displays the latest 5 poll questions in the system, separated by
+commas, according to publication date::
 
     from mysite.polls.models import Poll
     from django.http import HttpResponse
@@ -210,8 +222,8 @@ So let's use Django's template system to separate the design from Python::
         })
         return HttpResponse(t.render(c))
 
-That code loads the template called "polls/index.html" and passes it a context. The
-context is a dictionary mapping template variable names to Python objects.
+That code loads the template called "polls/index.html" and passes it a context.
+The context is a dictionary mapping template variable names to Python objects.
 
 Reload the page. Now you'll see an error::
 
@@ -219,20 +231,21 @@ Reload the page. Now you'll see an error::
     polls/index.html
 
 Ah. There's no template yet. First, create a directory, somewhere on your
-filesystem, whose contents Django can access. (Django runs as whatever user
-your server runs.) Don't put them under your document root, though. You
-probably shouldn't make them public, just for security's sake.
-
-Then edit ``TEMPLATE_DIRS`` in your ``settings.py`` to tell Django where it can
-find templates -- just as you did in the "Customize the admin look and feel"
-section of Tutorial 2.
+filesystem, whose contents Django can access. (Django runs as whatever user your
+server runs.) Don't put them under your document root, though. You probably
+shouldn't make them public, just for security's sake.
+Then edit :setting:`TEMPLATE_DIRS` in your ``settings.py`` to tell Django where
+it can find templates -- just as you did in the "Customize the admin look and
+feel" section of Tutorial 2.
 
 When you've done that, create a directory ``polls`` in your template directory.
 Within that, create a file called ``index.html``. Note that our
 ``loader.get_template('polls/index.html')`` code from above maps to
 "[template_directory]/polls/index.html" on the filesystem.
 
-Put the following code in that template::
+Put the following code in that template:
+
+.. code-block:: html+django
 
     {% if latest_poll_list %}
         <ul>
@@ -251,8 +264,9 @@ A shortcut: render_to_response()
 --------------------------------
 
 It's a very common idiom to load a template, fill a context and return an
-``HttpResponse`` object with the result of the rendered template. Django
-provides a shortcut. Here's the full ``index()`` view, rewritten::
+:class:`~django.http.HttpResponse` object with the result of the rendered
+template. Django provides a shortcut. Here's the full ``index()`` view,
+rewritten::
 
     from django.shortcuts import render_to_response
     from mysite.polls.models import Poll
@@ -261,11 +275,14 @@ provides a shortcut. Here's the full ``index()`` view, rewritten::
         latest_poll_list = Poll.objects.all().order_by('-pub_date')[:5]
         return render_to_response('polls/index.html', {'latest_poll_list': latest_poll_list})
 
-Note that once we've done this in all these views, we no longer need to import ``loader``, ``Context`` and ``HttpResponse``.
+Note that once we've done this in all these views, we no longer need to import
+:mod:`~django.template.loader`, :class:`~django.template.Context` and
+:class:`~django.http.HttpResponse`.
 
-The ``render_to_response()`` function takes a template name as its first
-argument and a dictionary as its optional second argument. It returns an
-``HttpResponse`` object of the given template rendered with the given context.
+The :func:`~django.shortcuts.render_to_response` function takes a template name
+as its first argument and a dictionary as its optional second argument. It
+returns an :class:`~django.http.HttpResponse` object of the given template
+rendered with the given context.
 
 Raising 404
 ===========
@@ -282,15 +299,15 @@ for a given poll. Here's the view::
             raise Http404
         return render_to_response('polls/detail.html', {'poll': p})
 
-The new concept here: The view raises the ``django.http.Http404``
-exception if a poll with the requested ID doesn't exist.
+The new concept here: The view raises the :exc:`~django.http.Http404` exception
+if a poll with the requested ID doesn't exist.
 
 A shortcut: get_object_or_404()
 -------------------------------
 
-It's a very common idiom to use ``get()`` and raise ``Http404`` if the
-object doesn't exist. Django provides a shortcut. Here's the ``detail()`` view,
-rewritten::
+It's a very common idiom to use :meth:`~django.db.models.QuerySet.get` and raise
+:exc:`~django.http.Http404` if the object doesn't exist. Django provides a
+shortcut. Here's the ``detail()`` view, rewritten::
 
     from django.shortcuts import render_to_response, get_object_or_404
     # ...
@@ -298,32 +315,36 @@ rewritten::
         p = get_object_or_404(Poll, pk=poll_id)
         return render_to_response('polls/detail.html', {'poll': p})
 
-The ``get_object_or_404()`` function takes a Django model module as its first
-argument and an arbitrary number of keyword arguments, which it passes to the
-module's ``get()`` function. It raises ``Http404`` if the object doesn't
-exist.
+The :func:`~django.shortcuts.get_object_or_404` function takes a Django model
+module as its first argument and an arbitrary number of keyword arguments, which
+it passes to the module's :meth:`~django.db.models.QuerySet.get` function. It
+raises :exc:`~django.http.Http404` if the object doesn't exist.
 
 .. admonition:: Philosophy
 
-    Why do we use a helper function ``get_object_or_404()`` instead of
-    automatically catching the ``DoesNotExist`` exceptions at a higher level,
-    or having the model API raise ``Http404`` instead of ``DoesNotExist``?
+    Why do we use a helper function :func:`~django.shortcuts.get_object_or_404`
+    instead of automatically catching the
+    :exc:`~django.core.exceptions.ObjectDoesNotExist` exceptions at a higher
+    level, or having the model API raise :exc:`~django.http.Http404` instead of
+    :exc:`~django.core.exceptions.ObjectDoesNotExist`?
 
     Because that would couple the model layer to the view layer. One of the
     foremost design goals of Django is to maintain loose coupling.
 
-There's also a ``get_list_or_404()`` function, which works just as
-``get_object_or_404()`` -- except using ``filter()`` instead of
-``get()``. It raises ``Http404`` if the list is empty.
+There's also a :func:`~django.shortcuts.get_list_or_404` function, which works
+just as :func:`~django.shortcuts.get_object_or_404` -- except using
+:meth:`~django.db.models.QuerySet.filter` instead of
+:meth:`~django.db.models.QuerySet.get`. It raises :exc:`~django.http.Http404` if
+the list is empty.
 
 Write a 404 (page not found) view
 =================================
 
-When you raise ``Http404`` from within a view, Django will load a special view
-devoted to handling 404 errors. It finds it by looking for the variable
-``handler404``, which is a string in Python dotted syntax -- the same format
-the normal URLconf callbacks use. A 404 view itself has nothing special: It's
-just a normal view.
+When you raise :exc:`~django.http.Http404` from within a view, Django will load
+a special view devoted to handling 404 errors. It finds it by looking for the
+variable ``handler404``, which is a string in Python dotted syntax -- the same
+format the normal URLconf callbacks use. A 404 view itself has nothing special:
+It's just a normal view.
 
 You normally won't have to bother with writing 404 views. By default, URLconfs
 have the following line up top::
@@ -332,18 +353,20 @@ have the following line up top::
 
 That takes care of setting ``handler404`` in the current module. As you can see
 in ``django/conf/urls/defaults.py``, ``handler404`` is set to
-``'django.views.defaults.page_not_found'`` by default.
+:func:`django.views.defaults.page_not_found` by default.
 
 Three more things to note about 404 views:
 
     * The 404 view is also called if Django doesn't find a match after checking
       every regular expression in the URLconf.
-    * If you don't define your own 404 view -- and simply use the default,
-      which is recommended -- you still have one obligation: To create a
-      ``404.html`` template in the root of your template directory. The default
-      404 view will use that template for all 404 errors.
-    * If ``DEBUG`` is set to ``True`` (in your settings module) then your 404
-      view will never be used, and the traceback will be displayed instead.
+      
+    * If you don't define your own 404 view -- and simply use the default, which
+      is recommended -- you still have one obligation: To create a ``404.html``
+      template in the root of your template directory. The default 404 view will
+      use that template for all 404 errors.
+      
+    * If :setting:`DEBUG` is set to ``True`` (in your settings module) then your
+      404 view will never be used, and the traceback will be displayed instead.
 
 Write a 500 (server error) view
 ===============================
@@ -355,9 +378,11 @@ view code.
 Use the template system
 =======================
 
-Back to the ``detail()`` view for our poll application. Given the context 
+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::
+like:
+
+.. code-block:: html+django
 
     <h1>{{ poll.question }}</h1>
     <ul>
@@ -376,9 +401,7 @@ Method-calling happens in the ``{% for %}`` loop: ``poll.choice_set.all`` is
 interpreted as the Python code ``poll.choice_set.all()``, which returns an
 iterable of Choice objects and is suitable for use in the ``{% for %}`` tag.
 
-See the `template guide`_ for full details on how templates work.
-
-.. _template guide: ../templates/
+See the :ref:`template guide <topics-templates>` for more about templates.
 
 Simplifying the URLconfs
 ========================
@@ -397,7 +420,7 @@ Namely, ``mysite.polls.views`` is in every callback.
 
 Because this is a common case, the URLconf framework provides a shortcut for
 common prefixes. You can factor out the common prefixes and add them as the
-first argument to ``patterns()``, like so::
+first argument to :func:`~django.conf.urls.defaults.patterns`, like so::
 
     urlpatterns = patterns('mysite.polls.views',
         (r'^polls/$', 'index'),
@@ -414,7 +437,7 @@ Decoupling the URLconfs
 
 While we're at it, we should take the time to decouple our poll-app URLs from
 our Django project configuration. Django apps are meant to be pluggable -- that
-is, each particular app should be transferrable to another Django installation
+is, each particular app should be transferable to another Django installation
 with minimal fuss.
 
 Our poll app is pretty decoupled at this point, thanks to the strict directory
@@ -425,28 +448,29 @@ We've been editing the URLs in ``mysite/urls.py``, but the URL design of an
 app is specific to the app, not to the Django installation -- so let's move the
 URLs within the app directory.
 
-Copy the file ``mysite/urls.py`` to ``mysite/polls/urls.py``. Then,
-change ``mysite/urls.py`` to remove the poll-specific URLs and insert an
-``include()``::
+Copy the file ``mysite/urls.py`` to ``mysite/polls/urls.py``. Then, change
+``mysite/urls.py`` to remove the poll-specific URLs and insert an
+:func:`~django.conf.urls.defaults.include`::
 
     (r'^polls/', include('mysite.polls.urls')),
 
-``include()``, simply, references another URLconf. Note that the regular
-expression doesn't have a ``$`` (end-of-string match character) but has the
-trailing slash. Whenever Django encounters ``include()``, it chops off whatever
-part of the URL matched up to that point and sends the remaining string to the
-included URLconf for further processing.
+:func:`~django.conf.urls.defaults.include`, simply, references another URLconf.
+Note that the regular expression doesn't have a ``$`` (end-of-string match
+character) but has the trailing slash. Whenever Django encounters
+:func:`~django.conf.urls.defaults.include`, it chops off whatever part of the
+URL matched up to that point and sends the remaining string to the included
+URLconf for further processing.
 
 Here's what happens if a user goes to "/polls/34/" in this system:
 
-* Django will find the match at ``'^polls/'``
-* It will strip off the matching text (``"polls/"``) and send the remaining
-  text -- ``"34/"`` -- to the 'mysite.polls.urls' URLconf for
-  further processing.
+    * Django will find the match at ``'^polls/'``
 
-Now that we've decoupled that, we need to decouple the
-'mysite.polls.urls' URLconf by removing the leading "polls/" from each
-line::
+    * Then, Django will strip off the matching text (``"polls/"``) and send the
+      remaining text -- ``"34/"`` -- to the 'mysite.polls.urls' URLconf for
+      further processing.
+
+Now that we've decoupled that, we need to decouple the 'mysite.polls.urls'
+URLconf by removing the leading "polls/" from each line::
 
     urlpatterns = patterns('mysite.polls.views',
         (r'^$', 'index'),
@@ -455,14 +479,12 @@ line::
         (r'^(?P<poll_id>\d+)/vote/$', 'vote'),
     )
 
-The idea behind ``include()`` and URLconf decoupling is to make it easy to
-plug-and-play URLs. Now that polls are in their own URLconf, they can be placed
-under "/polls/", or under "/fun_polls/", or under "/content/polls/", or any
-other URL root, and the app will still work.
+The idea behind :func:`~django.conf.urls.defaults.include` and URLconf
+decoupling is to make it easy to plug-and-play URLs. Now that polls are in their
+own URLconf, they can be placed under "/polls/", or under "/fun_polls/", or
+under "/content/polls/", or any other URL root, and the app will still work.
 
 All the poll app cares about is its relative URLs, not its absolute URLs.
 
-When you're comfortable with writing views, read `part 4 of this tutorial`_ to
-learn about simple form processing and generic views.
-
-.. _part 4 of this tutorial: ../tutorial04/
+When you're comfortable with writing views, read :ref:`part 4 of this tutorial
+<intro-tutorial04>` to learn about simple form processing and generic views.

+ 117 - 110
docs/tutorial04.txt → docs/intro/tutorial04.txt

@@ -1,15 +1,20 @@
+.. _intro-tutorial04:
+
 =====================================
 Writing your first Django app, part 4
 =====================================
 
-This tutorial begins where `Tutorial 3`_ left off. We're continuing the Web-poll
-application and will focus on simple form processing and cutting down our code.
+This tutorial begins where :ref:`Tutorial 3 <intro-tutorial03>` left off. We're
+continuing the Web-poll application and will focus on simple form processing and
+cutting down our code.
 
 Write a simple form
 ===================
 
 Let's update our poll detail template ("polls/detail.html") from the last
-tutorial, so that the template contains an HTML ``<form>`` element::
+tutorial, so that the template contains an HTML ``<form>`` element:
+
+.. code-block:: html+django
 
     <h1>{{ poll.question }}</h1>
 
@@ -38,15 +43,12 @@ A quick rundown:
       data server-side, use ``method="post"``. This tip isn't specific to
       Django; it's just good Web development practice.
 
-    * ``forloop.counter`` indicates how many times the ``for`` tag has
-      gone through its loop. For more information, see `the
-      documentation for the "for" tag`_.
-
-.. _the documentation for the "for" tag: ../templates/#for
+    * ``forloop.counter`` indicates how many times the ;ttag:`for` tag has gone
+      through its loop
 
 Now, let's create a Django view that handles the submitted data and does
-something with it. Remember, in `Tutorial 3`_, we created a URLconf for the
-polls application that includes this line::
+something with it. Remember, in :ref:`Tutorial 3 <intro-tutorial03>`, we created
+a URLconf for the polls application that includes this line::
 
     (r'^(?P<poll_id>\d+)/vote/$', 'mysite.polls.views.vote'),
 
@@ -77,47 +79,52 @@ So let's create a ``vote()`` function in ``mysite/polls/views.py``::
 
 This code includes a few things we haven't covered yet in this tutorial:
 
-    * ``request.POST`` is a dictionary-like object that lets you access
-      submitted data by key name. In this case, ``request.POST['choice']``
-      returns the ID of the selected choice, as a string. ``request.POST``
-      values are always strings.
+    * :attr:`request.POST <django.http.HttpRequest.POST>` is a dictionary-like
+      object that lets you access submitted data by key name. In this case,
+      ``request.POST['choice']`` returns the ID of the selected choice, as a
+      string. :attr:`request.POST <django.http.HttpRequest.POST>` values are
+      always strings.
 
-      Note that Django also provides ``request.GET`` for accessing GET data
-      in the same way -- but we're explicitly using ``request.POST`` in our
-      code, to ensure that data is only altered via a POST call.
+      Note that Django also provides :attr:`request.GET
+      <django.http.HttpRequest.GET>` for accessing GET data in the same way --
+      but we're explicitly using :attr:`request.POST
+      <django.http.HttpRequest.POST>` in our code, to ensure that data is only
+      altered via a POST call.
 
-    * ``request.POST['choice']`` will raise ``KeyError`` if ``choice`` wasn't
-      provided in POST data. The above code checks for ``KeyError`` and
+    * ``request.POST['choice']`` will raise :exc:`KeyError` if ``choice`` wasn't
+      provided in POST data. The above code checks for :exc:`KeyError` and
       redisplays the poll form with an error message if ``choice`` isn't given.
 
     * After incrementing the choice count, the code returns an
-      ``HttpResponseRedirect`` rather than a normal ``HttpResponse``.
-      ``HttpResponseRedirect`` takes a single argument: the URL to which the
-      user will be redirected (see the following point for how we construct
-      the URL in this case).
+      :class:`~django.http.HttpResponseRedirect` rather than a normal
+      :class:`~django.http.HttpResponse`.
+      :class:`~django.http.HttpResponseRedirect` takes a single argument: the
+      URL to which the user will be redirected (see the following point for how
+      we construct the URL in this case).
 
       As the Python comment above points out, you should always return an
-      ``HttpResponseRedirect`` after successfully dealing with POST data. This
-      tip isn't specific to Django; it's just good Web development practice.
-
-    * We are using the ``reverse()`` function in the ``HttpResponseRedirect``
-      constructor in this example. This function helps avoid having to
-      hardcode a URL in the view function. It is given the name of the view
-      that we want to pass control to and the variable portion of the URL
-      pattern that points to that view. In this case, using the URLConf we set
-      up in Tutorial 3, this ``reverse()`` call will return a string like ::
+      :class:`~django.http.HttpResponseRedirect` after successfully dealing with
+      POST data. This tip isn't specific to Django; it's just good Web
+      development practice.
+
+    * We are using the :func:`~django.core.urlresolvers.reverse` function in the
+      :class:`~django.http.HttpResponseRedirect` constructor in this example.
+      This function helps avoid having to hardcode a URL in the view function.
+      It is given the name of the view that we want to pass control to and the
+      variable portion of the URL pattern that points to that view. In this
+      case, using the URLConf we set up in Tutorial 3, this
+      :func:`~django.core.urlresolvers.reverse` call will return a string like
+      ::
 
         '/polls/3/results/'
 
       ... where the ``3`` is the value of ``p.id``. This redirected URL will
-      then call the ``'results'`` view to display the final page. Note that
-      you need to use the full name of the view here (including the prefix).
+      then call the ``'results'`` view to display the final page. Note that you
+      need to use the full name of the view here (including the prefix).
 
-      For more information about ``reverse()``, see the `URL dispatcher`_
-      documentation.
-
-As mentioned in Tutorial 3, ``request`` is a ``HTTPRequest`` object. For more
-on ``HTTPRequest`` objects, see the `request and response documentation`_.
+As mentioned in Tutorial 3, ``request`` is a :class:`~django.http.HttpRequest`
+object. For more on :class:`~django.http.HttpRequest` objects, see the
+:ref:`request and response documentation <ref-request-response>`.
 
 After somebody votes in a poll, the ``vote()`` view redirects to the results
 page for the poll. Let's write that view::
@@ -126,10 +133,13 @@ page for the poll. Let's write that view::
         p = get_object_or_404(Poll, pk=poll_id)
         return render_to_response('polls/results.html', {'poll': p})
 
-This is almost exactly the same as the ``detail()`` view from `Tutorial 3`_.
-The only difference is the template name. We'll fix this redundancy later.
+This is almost exactly the same as the ``detail()`` view from :ref:`Tutorial 3
+<intro-tutorial03>`. The only difference is the template name. We'll fix this
+redundancy later.
+
+Now, create a ``results.html`` template:
 
-Now, create a ``results.html`` template::
+.. code-block:: html+django
 
     <h1>{{ poll.question }}</h1>
 
@@ -143,15 +153,12 @@ Now, go to ``/polls/1/`` in your browser and vote in the poll. You should see a
 results page that gets updated each time you vote. If you submit the form
 without having chosen a choice, you should see the error message.
 
-.. _request and response documentation: ../request_response/
-.. _URL dispatcher: ../url_dispatch#reverse
-
 Use generic views: Less code is better
 ======================================
 
-The ``detail()`` (from `Tutorial 3`_) and ``results()`` views are stupidly
-simple -- and, as mentioned above, redundant. The ``index()`` view (also from
-Tutorial 3), which displays a list of polls, is similar.
+The ``detail()`` (from :ref:`Tutorial 3 <intro-tutorial03>`) and ``results()``
+views are stupidly simple -- and, as mentioned above, redundant. The ``index()``
+view (also from Tutorial 3), which displays a list of polls, is similar.
 
 These views represent a common case of basic Web development: getting data from
 the database according to a parameter passed in the URL, loading a template and
@@ -175,7 +182,7 @@ conversion.
 
     You should know basic math before you start using a calculator.
 
-First, open the polls/urls.py URLconf. It looks like this, according to the
+First, open the ``polls/urls.py`` URLconf. It looks like this, according to the
 tutorial so far::
 
     from django.conf.urls.defaults import *
@@ -203,92 +210,95 @@ Change it like so::
         (r'^(?P<poll_id>\d+)/vote/$', 'mysite.polls.views.vote'),
     )
 
-We're using two generic views here: ``object_list`` and ``object_detail``.
-Respectively, those two views abstract the concepts of "display a list of
-objects" and "display a detail page for a particular type of object."
+We're using two generic views here:
+:func:`~django.views.generic.list_detail.object_list` and
+:func:`~django.views.generic.list_detail.object_detail`. Respectively, those two
+views abstract the concepts of "display a list of objects" and "display a detail
+page for a particular type of object."
 
     * Each generic view needs to know what data it will be acting upon. This
       data is provided in a dictionary. The ``queryset`` key in this dictionary
       points to the list of objects to be manipulated by the generic view.
 
-    * The ``object_detail`` generic view expects the ID value captured
-      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 the documentation about
-      `naming URL patterns`_ for information). We're also using the `url()`_
-      function from ``django.conf.urls.defaults`` here. It's a good habit to
-      use ``url()`` when you are providing a pattern name like this.
-
-.. _naming URL patterns: ../url_dispatch/#naming-url-patterns
-.. _url(): ../url_dispatch/#url
-
-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
-``polls/poll_detail.html``, and change the ``render_to_response()`` line in
-``vote()``.
-
-Similarly, the ``object_list`` generic view uses a template called
-``<app name>/<model name>_list.html``. Thus, rename ``polls/index.html`` to
-``polls/poll_list.html``.
-
-Because we have more than one entry in the URLconf that uses ``object_detail``
-for the polls app, we manually specify a template name for the results view:
+    * The :func:`~django.views.generic.list_detail.object_detail` generic view
+      expects the ID value captured 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 the documentation about
+      :ref:`naming URL patterns <naming-url-patterns>` for information). We're
+      also using the :func:`~django.conf.urls.default.url` function from
+      :mod:`django.conf.urls.defaults` here. It's a good habit to use
+      :func:`~django.conf.urls.defaults.url` when you are providing a pattern
+      name like this.
+
+By default, the :func:`~django.views.generic.list_detail.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 ``polls/poll_detail.html``, and change the
+:func:`~django.shortcuts.render_to_response` line in ``vote()``.
+
+Similarly, the :func:`~django.views.generic.list_detail.object_list` generic
+view uses a template called ``<app name>/<model name>_list.html``. Thus, rename
+``polls/index.html`` to ``polls/poll_list.html``.
+
+Because we have more than one entry in the URLconf that uses
+:func:`~django.views.generic.list_detail.object_detail` for the polls app, we
+manually specify a template name for the results view:
 ``template_name='polls/results.html'``. Otherwise, both views would use the same
 template. Note that we use ``dict()`` to return an altered dictionary in place.
 
-.. note:: ``all()`` is lazy
+.. note:: :meth:`django.db.models.QuerySet.all` is lazy
 
     It might look a little frightening to see ``Poll.objects.all()`` being used
     in a detail view which only needs one ``Poll`` object, but don't worry;
-    ``Poll.objects.all()`` is actually a special object called a ``QuerySet``,
-    which is "lazy" and doesn't hit your database until it absolutely has to. By
-    the time the database query happens, the ``object_detail`` generic view will
-    have narrowed its scope down to a single object, so the eventual query will
-    only select one row from the database.
+    ``Poll.objects.all()`` is actually a special object called a
+    :class:`~django.db.models.QuerySet`, which is "lazy" and doesn't hit your
+    database until it absolutely has to. By the time the database query happens,
+    the :func:`~django.views.generic.list_detail.object_detail` generic view
+    will have narrowed its scope down to a single object, so the eventual query
+    will only select one row from the database.
 
     If you'd like to know more about how that works, The Django database API
-    documentation `explains the lazy nature of QuerySet objects`_.
+    documentation :ref:`explains the lazy nature of QuerySet objects
+    <querysets-are-lazy>`.
 
-.. _explains the lazy nature of QuerySet objects: ../db-api/#querysets-are-lazy
-
-In previous parts of the tutorial, the templates have been provided with a context
-that contains the ``poll`` and ``latest_poll_list`` context variables. However,
-the generic views provide the variables ``object`` and ``object_list`` as context.
-Therefore, you need to change your templates to match the new context variables.
-Go through your templates, and modify any reference to ``latest_poll_list`` to
-``object_list``, and change any reference to ``poll`` to ``object``.
+In previous parts of the tutorial, the templates have been provided with a
+context that contains the ``poll`` and ``latest_poll_list`` context variables.
+However, the generic views provide the variables ``object`` and ``object_list``
+as context. Therefore, you need to change your templates to match the new
+context variables. Go through your templates, and modify any reference to
+``latest_poll_list`` to :func:`~django.views.generic.list_detail.object_list`,
+and change any reference to ``poll`` to ``object``.
 
 You can now delete the ``index()``, ``detail()`` and ``results()`` views
 from ``polls/views.py``. We don't need them anymore -- they have been replaced
 by generic views.
 
-The ``vote()`` view is still required. However, it must be modified to match
-the new context variables. In the ``render_to_response()`` call, rename the
-``poll`` context variable to ``object``.
+The ``vote()`` view is still required. However, it must be modified to match the
+new context variables. In the :func:`~django.shortcuts.render_to_response` call,
+rename the ``poll`` context variable to ``object``.
 
 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::
+views. In the vote view above, we used the
+:func:`~django.core.urlresolvers.reverse` function to avoid hard-coding our
+URLs. Now that we've switched to a generic view, we'll need to change the
+:func:`~django.core.urlresolvers.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`_.
-
-.. _generic views documentation: ../generic_views/
+For full details on generic views, see the :ref:`generic views documentation
+<topics-http-generic-views>`.
 
 Coming soon
 ===========
 
-The tutorial ends here for the time being. But check back soon for the next
-installments:
+The tutorial ends here for the time being. Future installments of the tutorial
+will cover:
 
     * Advanced form processing
     * Using the RSS framework
@@ -297,8 +307,5 @@ installments:
     * Advanced admin features: Permissions
     * Advanced admin features: Custom JavaScript
 
-In the meantime, you can read through the rest of the `Django documentation`_
-and start writing your own applications.
-
-.. _Tutorial 3: ../tutorial03/
-.. _Django documentation: http://www.djangoproject.com/documentation/
+In the meantime, you might want to check out some pointers on :ref:`where to go
+from here <intro-whatsnext>`

+ 235 - 0
docs/intro/whatsnext.txt

@@ -0,0 +1,235 @@
+.. _intro-whatsnext:
+
+=================
+What to read next
+=================
+
+So you've read all the :ref:`introductory material <intro-index>` and have
+decided you'd like to keep using Django. We've only just scratched the surface
+with this intro (in fact, if you've read every single word you've still read
+less than 10% of the overall documentation).
+
+So what's next?
+
+Well, we've always been big fans of learning by doing. At this point you should
+know enough to start a project of your own and start fooling around. As you need
+to learn new tricks, come back to the documentation.
+
+We've put a lot of effort into making Django's documentation useful, easy to
+read and as complete as possible. The rest of this document explains more about
+how the documentation works so that you can get the most out of it.
+
+(Yes, this is documentation about documentation. Rest assured we have no plans
+to write a document about how to read the document about documentation.)
+
+Finding documentation
+=====================
+
+Django's got a *lot* of documentation -- almost 200,000 words -- so finding what
+you need can sometimes be tricky. A few good places to start the :ref:`search`
+and the :ref:`genindex`.
+
+Or you can just browse around!
+
+How the documentation is organized
+==================================
+
+Django's main documentation is broken up into "chunks" designed to fill
+different needs:
+
+    * The :ref:`introductory material <intro-index>` is designed for people new
+      to Django -- or to web development in general. It doesn't cover anything
+      in depth, but instead gives a high-level overview of how developing in
+      Django "feels".
+      
+    * The :ref:`topic guides <topics-index>`, on the other hand, dive deep into
+      individual parts of Django. There are complete guides to Django's
+      :ref:`model system <topics-db-index>`, :ref:`template engine
+      <topics-templates>`, :ref:`forms framework <topics-forms-index>`, and much
+      more.`
+      
+      This is probably where you'll want to spent most of your time; if you work
+      your way through these guides you should come out knowing pretty much
+      everything there is to know about Django.
+
+    * Web development is often broad, not deep -- problems span many domains.
+      We've written a set of :ref:`how-to guides <howto-index>` that answer
+      common "How do I ...?" questions. Here you'll find information about
+      :ref:`generating PDFs with Django <howto-outputting-pdf>`, :ref:`writing
+      custom template tags <howto-custom-template-tags>`, and more.
+
+      Answers to really common questions can also be found in the :ref:`FAQ
+      <faq-index>`.
+
+    * The guides and how-to's don't cover every single class, function, and
+      method available in Django -- that would be overwhelming when you're
+      trying to learn. Instead, details about individual classes, functions,
+      methods, and modules are kept in the :ref:`reference <ref-index>`. This is
+      where you'll turn to find the details of a particular function or
+      whathaveyou.
+    
+    * Finally, there's some "specialized" documentation not usually relevant to
+      most developers. This includes the :ref:`release notes <releases-index>`,
+      :ref:`documentation of obsolete features <obsolete-index>`,
+      :ref:`internals documentation <internals-index>` for those who want to add
+      code to Django itself, and a :ref:`few other things that simply don't fit
+      elsewhere <misc-index>`.
+      
+
+How documentation is updated
+============================
+
+Just as the Django code base is developed and improved on a daily basis, our
+documentation is consistently improving. We improve documentation for several
+reasons:
+
+    * To make content fixes, such as grammar/typo corrections.
+
+    * To add information and/or examples to existing sections that need to be
+      expanded.
+
+    * To document Django features that aren't yet documented. (The list of
+      such features is shrinking but exists nonetheless.)
+
+    * To add documentation for new features as new features get added, or as
+      Django APIs or behaviors change.
+
+Django's documentation is kept in the same source control system as its code. It
+lives in the `django/trunk/docs`_ directory of our Subversion repository. Each
+document online is a separate text file in the repository.
+
+.. _django/trunk/docs: http://code.djangoproject.com/browser/django/trunk/docs
+
+Where to get it
+===============
+
+You can read Django documentation in several ways. They are, in order of
+preference:
+
+On the Web
+----------
+
+The most recent version of the Django documentation lives at
+http://www.djangoproject.com/documentation/ . These HTML pages are generated
+automatically from the text files in source control. That means they reflect the
+"latest and greatest" in Django -- they include the very latest corrections and
+additions, and they discuss the latest Django features, which may only be
+available to users of the Django development version. (See "Differences between
+versions" below.)
+
+We encourage you to help improve the docs by submitting changes, corrections and
+suggestions in the `ticket system`_. The Django developers actively monitor the
+ticket system and use your feedback to improve the documentation for everybody.
+
+Note, however, that tickets should explicitly relate to the documentation,
+rather than asking broad tech-support questions. If you need help with your
+particular Django setup, try the `django-users mailing list`_ or the `#django
+IRC channel`_ instead.
+
+.. _ticket system: http://code.djangoproject.com/simpleticket?component=Documentation
+.. _django-users mailing list: http://groups.google.com/group/django-users
+.. _#django IRC channel: irc://irc.freenode.net/django
+
+In plain text
+-------------
+
+For offline reading, or just for convenience, you can read the Django
+documentation in plain text.
+
+If you're using an official release of Django, note that the zipped package
+(tarball) of the code includes a ``docs/`` directory, which contains all the
+documentation for that release.
+
+If you're using the development version of Django (aka the Subversion "trunk"),
+note that the ``docs/`` directory contains all of the documentation. You can
+``svn update`` it, just as you ``svn update`` the Python code, in order to get
+the latest changes.
+
+You can check out the latest Django documentation from Subversion using this
+shell command:
+
+.. code-block:: bash
+
+    $ svn co http://code.djangoproject.com/svn/django/trunk/docs/ django_docs
+
+One low-tech way of taking advantage of the text documentation is by using the
+Unix ``grep`` utility to search for a phrase in all of the documentation. For
+example, this will show you each mention of the phrase "edit_inline" in any
+Django document:
+
+.. code-block:: bash
+
+    $ grep edit_inline /path/to/django/docs/*.txt
+    
+As HTML, locally
+----------------
+
+You can get a local copy of the HTML documentation following a few easy steps:
+
+    * Django's documentation uses a system called Sphinx__ to convert from
+      plain text to HTML. You'll need to install Sphinx by either downloading
+      and installing the package from the Sphinx website, or by Python's
+      ``easy_install``:
+      
+      .. code-block:: bash
+        
+            $ easy_install Sphinx
+    
+    * Then, just use the included ``Makefile`` to turn the documentation into
+      HTML:
+      
+      .. code-block:: bash
+      
+            $ cd path/to/django/docs
+            $ make html
+    
+      You'll need `GNU Make`__ installed for this.
+      
+    * The HTML documentation will be placed in ``docs/_build/html``.
+    
+.. warning::
+
+    At the time of this writing, Django's using a version of Sphinx not
+    yet released, so you'll currently need to install Sphinx from the
+    source. We'll fix this shortly.
+    
+__ http://sphinx.pocoo.org/
+__ http://www.gnu.org/software/make/
+
+Differences between versions
+============================
+
+As previously mentioned, the text documentation in our Subversion repository
+contains the "latest and greatest" changes and additions. These changes often
+include documentation of new features added in the Django development version
+-- the Subversion ("trunk") version of Django. For that reason, it's worth
+pointing out our policy on keeping straight the documentation for various
+versions of the framework.
+
+We follow this policy:
+
+    * The primary documentation on djangoproject.com is an HTML version of the
+      latest docs in Subversion. These docs always correspond to the latest
+      official Django release, plus whatever features we've added/changed in
+      the framework *since* the latest release.
+
+    * As we add features to Django's development version, we try to update the
+      documentation in the same Subversion commit transaction.
+
+    * To distinguish feature changes/additions in the docs, we use the phrase
+      **New in Django development version**. In practice, this means that the
+      current documentation on djangoproject.com can be used by users of either
+      the latest release *or* the development version.
+
+    * Documentation for a particular Django release is frozen once the version
+      has been released officially. It remains a snapshot of the docs as of the
+      moment of the release. We will make exceptions to this rule in
+      the case of retroactive security updates or other such retroactive
+      changes. Once documentation is frozen, we add a note to the top of each
+      frozen document that says "These docs are frozen for Django version XXX"
+      and links to the current version of that document.
+
+    * The `main documentation Web page`_ includes links to documentation for
+      all previous versions.
+
+.. _main documentation Web page: http://www.djangoproject.com/documentation/

+ 0 - 69
docs/legacy_databases.txt

@@ -1,69 +0,0 @@
-==================================
-Integrating with a legacy database
-==================================
-
-While Django is best suited for developing new applications, it's quite
-possible to integrate it into legacy databases. Django includes a couple of
-utilities to automate as much of this process as possible.
-
-This document assumes you know the Django basics, as covered in the
-`official tutorial`_.
-
-.. _official tutorial: ../tutorial01/
-
-Give Django your database parameters
-====================================
-
-You'll need to tell Django what your database connection parameters are, and
-what the name of the database is. Do that by editing these settings in your
-`settings file`_:
-
-    * `DATABASE_NAME`_
-    * `DATABASE_ENGINE`_
-    * `DATABASE_USER`_
-    * `DATABASE_PASSWORD`_
-    * `DATABASE_HOST`_
-    * `DATABASE_PORT`_
-
-.. _settings file: ../settings/
-.. _DATABASE_NAME: ../settings/#database-name
-.. _DATABASE_ENGINE: ../settings/#database-engine
-.. _DATABASE_USER: ../settings/#database-user
-.. _DATABASE_PASSWORD: ../settings/#database-password
-.. _DATABASE_HOST: ../settings/#database-host
-.. _DATABASE_PORT: ../settings/#database-port
-
-Auto-generate the models
-========================
-
-Django comes with a utility that can create models by introspecting an existing
-database. You can view the output by running this command::
-
-    python manage.py inspectdb
-
-Save this as a file by using standard Unix output redirection::
-
-    python manage.py inspectdb > models.py
-
-This feature is meant as a shortcut, not as definitive model generation. See
-the `django-admin.py documentation`_ for more information.
-
-Once you've cleaned up your models, name the file ``models.py`` and put it in
-the Python package that holds your app. Then add the app to your
-``INSTALLED_APPS`` setting.
-
-.. _django-admin.py documentation: ../django-admin/
-
-Install the core Django tables
-==============================
-
-Next, run the ``manage.py syncdb`` command to install any extra needed database
-records such as admin permissions and content types::
-
-    python manage.py syncdb
-
-See whether it worked
-=====================
-
-That's it. Try accessing your data via the Django database API, and try editing
-objects via Django's admin site.

+ 0 - 733
docs/localflavor.txt

@@ -1,733 +0,0 @@
-==========================
-The "local flavor" add-ons
-==========================
-
-Following its "batteries included" philosophy, Django comes with assorted
-pieces of code that are useful for particular countries or cultures. These are
-called the "local flavor" add-ons and live in the ``django.contrib.localflavor``
-package.
-
-Inside that package, country- or culture-specific code is organized into
-subpackages, named using `ISO 3166 country codes`_.
-
-Most of the ``localflavor`` add-ons are localized form components deriving from
-the forms_ framework -- for example, a ``USStateField`` that knows how to
-validate U.S. state abbreviations, and a ``FISocialSecurityNumber`` that knows
-how to validate Finnish social security numbers.
-
-To use one of these localized components, just import the relevant subpackage.
-For example, here's how you can create a form with a field representing a
-French telephone number::
-
-    from django import forms
-    from django.contrib.localflavor import fr
-
-    class MyForm(forms.Form):
-        my_french_phone_no = fr.forms.FRPhoneNumberField()
-
-Supported countries
-===================
-
-Countries currently supported by ``localflavor`` are:
-
-    * Argentina_
-    * Australia_
-    * Austria_
-    * Brazil_
-    * Canada_
-    * Chile_
-    * Finland_
-    * France_
-    * Germany_
-    * Holland_
-    * Iceland_
-    * India_
-    * Italy_
-    * Japan_
-    * Mexico_
-    * Norway_
-    * Peru_
-    * Poland_
-    * Romania_
-    * Slovakia_
-    * `South Africa`_
-    * Spain_
-    * Switzerland_
-    * `United Kingdom`_
-    * `United States of America`_
-
-The ``localflavor`` package also includes a ``generic`` subpackage, containing
-useful code that is not specific to one particular country or culture.
-Currently, it defines date and datetime input fields based on those from
-forms_, but with non-US default formats. Here's an example of how to use
-them::
-
-    from django import forms
-    from django.contrib.localflavor import generic
-
-    class MyForm(forms.Form):
-        my_date_field = generic.forms.DateField()
-
-.. _ISO 3166 country codes: http://www.iso.org/iso/country_codes/iso_3166_code_lists/english_country_names_and_code_elements.htm
-.. _Argentina: `Argentina (django.contrib.localflavor.ar)`_
-.. _Australia: `Australia (django.contrib.localflavor.au)`_
-.. _Austria: `Austria (django.contrib.localflavor.at)`_
-.. _Brazil: `Brazil (django.contrib.localflavor.br)`_
-.. _Canada: `Canada (django.contrib.localflavor.ca)`_
-.. _Chile: `Chile (django.contrib.localflavor.cl)`_
-.. _Finland: `Finland (django.contrib.localflavor.fi)`_
-.. _France: `France (django.contrib.localflavor.fr)`_
-.. _Germany: `Germany (django.contrib.localflavor.de)`_
-.. _Holland: `Holland (django.contrib.localflavor.nl)`_
-.. _Iceland: `Iceland (django.contrib.localflavor.is\_)`_
-.. _India: `India (django.contrib.localflavor.in\_)`_
-.. _Italy: `Italy (django.contrib.localflavor.it)`_
-.. _Japan: `Japan (django.contrib.localflavor.jp)`_
-.. _Mexico: `Mexico (django.contrib.localflavor.mx)`_
-.. _Norway: `Norway (django.contrib.localflavor.no)`_
-.. _Peru: `Peru (django.contrib.localflavor.pe)`_
-.. _Poland: `Poland (django.contrib.localflavor.pl)`_
-.. _Romania: `Romania (django.contrib.localflavor.ro)`_
-.. _Slovakia: `Slovakia (django.contrib.localflavor.sk)`_
-.. _South Africa: `South Africa (django.contrib.localflavor.za)`_
-.. _Spain: `Spain (django.contrib.localflavor.es)`_
-.. _Switzerland: `Switzerland (django.contrib.localflavor.ch)`_
-.. _United Kingdom: `United Kingdom (django.contrib.localflavor.uk)`_
-.. _United States of America: `United States of America (django.contrib.localflavor.us)`_
-.. _forms: ../forms/
-
-Adding flavors
-==============
-
-We'd love to add more of these to Django, so please `create a ticket`_ with
-any code you'd like to contribute. One thing we ask is that you please use
-Unicode objects (``u'mystring'``) for strings, rather than setting the encoding
-in the file. See any of the existing flavors for examples.
-
-.. _create a ticket: http://code.djangoproject.com/simpleticket
-
-Argentina (``django.contrib.localflavor.ar``)
-=============================================
-
-ARPostalCodeField
------------------
-
-A form field that validates input as either a classic four-digit Argentinian
-postal code or a CPA_.
-
-.. _CPA: http://www.correoargentino.com.ar/consulta_cpa/home.php
-
-ARDNIField
-----------
-
-A form field that validates input as a Documento Nacional de Identidad (DNI)
-number.
-
-ARCUITField
------------
-
-A form field that validates input as a Código Único de Identificación
-Tributaria (CUIT) number.
-
-ARProvinceSelect
-----------------
-
-A ``Select`` widget that uses a list of Argentina's provinces and autonomous
-cities as its choices.
-
-Australia (``django.contrib.localflavor.au``)
-=============================================
-
-AUPostCodeField
----------------
-
-A form field that validates input as an Australian postcode.
-
-AUPhoneNumberField
-------------------
-
-A form field that validates input as an Australian phone number. Valid numbers
-have ten digits.
-
-AUStateSelect
--------------
-
-A ``Select`` widget that uses a list of Australian states/territories as its
-choices.
-
-Austria (``django.contrib.localflavor.at``)
-=============================================
-
-ATZipCodeField
----------------
-
-A form field that validates its input as an Austrian zip code.
-
-ATStateSelect
--------------
-
-A ``Select`` widget that uses a list of Austrian states as its choices. 
-
-ATSocialSecurityNumberField
----------------------------
-
-A form field that validates its input as an Austrian social security number.
-
-Brazil (``django.contrib.localflavor.br``)
-==========================================
-
-BRPhoneNumberField
-------------------
-
-A form field that validates input as a Brazilian phone number, with the format
-XX-XXXX-XXXX.
-
-BRZipCodeField
---------------
-
-A form field that validates input as a Brazilian zip code, with the format
-XXXXX-XXX.
-
-BRStateSelect
--------------
-
-A ``Select`` widget that uses a list of Brazilian states/territories as its
-choices.
-
-Canada (``django.contrib.localflavor.ca``)
-==========================================
-
-CAPhoneNumberField
-------------------
-
-A form field that validates input as a Canadian phone number, with the format
-XXX-XXX-XXXX.
-
-CAPostalCodeField
------------------
-
-A form field that validates input as a Canadian postal code, with the format
-XXX XXX.
-
-CAProvinceField
----------------
-
-A form field that validates input as a Canadian province name or abbreviation.
-
-CASocialInsuranceNumberField
-----------------------------
-
-A form field that validates input as a Canadian Social Insurance Number (SIN).
-A valid number must have the format XXX-XXX-XXX and pass a `Luhn mod-10
-checksum`_.
-
-.. _Luhn mod-10 checksum: http://en.wikipedia.org/wiki/Luhn_algorithm
-
-CAProvinceSelect
-----------------
-
-A ``Select`` widget that uses a list of Canadian provinces and territories as
-its choices.
-
-Chile (``django.contrib.localflavor.cl``)
-=========================================
-
-CLRutField
-----------
-
-A form field that validates input as a Chilean national identification number
-('Rol Unico Tributario' or RUT). The valid format is XX.XXX.XXX-X.
-
-CLRegionSelect
---------------
-
-A ``Select`` widget that uses a list of Chilean regions (Regiones) as its
-choices.
-
-Finland (``django.contrib.localflavor.fi``)
-===========================================
-
-FISocialSecurityNumber
-----------------------
-
-A form field that validates input as a Finnish social security number.
-
-FIZipCodeField
---------------
-
-A form field that validates input as a Finnish zip code. Valid codes
-consist of five digits.
-
-FIMunicipalitySelect
---------------------
-
-A ``Select`` widget that uses a list of Finnish municipalities as its
-choices.
-
-France (``django.contrib.localflavor.fr``)
-==========================================
-
-FRPhoneNumberField
-------------------
-
-A form field that validates input as a French local phone number. The
-correct format is 0X XX XX XX XX. 0X.XX.XX.XX.XX and 0XXXXXXXXX validate
-but are corrected to 0X XX XX XX XX.
-
-FRZipCodeField
---------------
-
-A form field that validates input as a French zip code. Valid codes
-consist of five digits.
-
-FRDepartmentSelect
-------------------
-
-A ``Select`` widget that uses a list of French departments as its choices.
-
-Germany (``django.contrib.localflavor.de``)
-===========================================
-
-DEIdentityCardNumberField
--------------------------
-
-A form field that validates input as a German identity card number
-(Personalausweis_). Valid numbers have the format
-XXXXXXXXXXX-XXXXXXX-XXXXXXX-X, with no group consisting entirely of zeroes.
-
-.. _Personalausweis: http://de.wikipedia.org/wiki/Personalausweis
-
-DEZipCodeField
---------------
-
-A form field that validates input as a German zip code. Valid codes
-consist of five digits.
-
-DEStateSelect
--------------
-
-A ``Select`` widget that uses a list of German states as its choices.
-
-Holland (``django.contrib.localflavor.nl``)
-===========================================
-
-NLPhoneNumberField
-------------------
-
-A form field that validates input as a Dutch telephone number.
-
-NLSofiNumberField
------------------
-
-A form field that validates input as a Dutch social security number
-(SoFI/BSN).
-
-NLZipCodeField
---------------
-
-A form field that validates input as a Dutch zip code.
-
-NLProvinceSelect
-----------------
-
-A ``Select`` widget that uses a list of Dutch provinces as its list of
-choices.
-
-Iceland (``django.contrib.localflavor.is_``)
-============================================
-
-ISIdNumberField
----------------
-
-A form field that validates input as an Icelandic identification number
-(kennitala). The format is XXXXXX-XXXX.
-
-ISPhoneNumberField
-------------------
-
-A form field that validates input as an Icelandtic phone number (seven
-digits with an optional hyphen or space after the first three digits).
-
-ISPostalCodeSelect
-------------------
-
-A ``Select`` widget that uses a list of Icelandic postal codes as its
-choices.
-
-India (``django.contrib.localflavor.in_``)
-==========================================
-
-INStateField
-------------
-
-A form field that validates input as an Indian state/territory name or
-abbreviation. Input is normalized to the standard two-letter vehicle
-registration abbreviation for the given state or territory.
-
-INZipCodeField
---------------
-
-A form field that validates input as an Indian zip code, with the
-format XXXXXXX.
-
-INStateSelect
--------------
-
-A ``Select`` widget that uses a list of Indian states/territories as its
-choices.
-
-Italy (``django.contrib.localflavor.it``)
-=========================================
-
-ITSocialSecurityNumberField
----------------------------
-
-A form field that validates input as an Italian social security number
-(`codice fiscale`_).
-
-.. _codice fiscale: http://www.agenziaentrate.it/ilwwcm/connect/Nsi/Servizi/Codice+fiscale+-+tessera+sanitaria/Codice+fiscale/NSI+Informazioni+sulla+codificazione+delle+persone+fisiche
-
-ITVatNumberField
-----------------
-
-A form field that validates Italian VAT numbers (partita IVA).
-
-ITZipCodeField
---------------
-
-A form field that validates input as an Italian zip code. Valid codes
-must have five digits.
-
-ITProvinceSelect
-----------------
-
-A ``Select`` widget that uses a list of Italian provinces as its choices.
-
-ITRegionSelect
---------------
-
-A ``Select`` widget that uses a list of Italian regions as its choices.
-
-Japan (``django.contrib.localflavor.jp``)
-=========================================
-
-JPPostalCodeField
------------------
-
-A form field that validates input as a Japanese postcode. It accepts seven
-digits, with or without a hyphen.
-
-JPPrefectureSelect
-------------------
-
-A ``Select`` widget that uses a list of Japanese prefectures as its choices.
-
-Mexico (``django.contrib.localflavor.mx``)
-==========================================
-
-MXStateSelect
--------------
-
-A ``Select`` widget that uses a list of Mexican states as its choices.
-
-Norway (``django.contrib.localflavor.no``)
-==========================================
-
-NOSocialSecurityNumber
-----------------------
-
-A form field that validates input as a Norwegian social security number
-(personnummer_).
-
-.. _personnummer: http://no.wikipedia.org/wiki/Personnummer
-
-NOZipCodeField
---------------
-
-A form field that validates input as a Norwegian zip code. Valid codes
-have four digits.
-
-NOMunicipalitySelect
---------------------
-
-A ``Select`` widget that uses a list of Norwegian municipalities (fylker) as
-its choices.
-
-Peru (``django.contrib.localflavor.pe``)
-========================================
-
-PEDNIField
-----------
-
-A form field that validates input as a DNI (Peruvian national identity)
-number.
-
-PERUCField
-----------
-
-A form field that validates input as an RUC (Registro Unico de
-Contribuyentes) number. Valid RUC numbers have 11 digits.
-
-PEDepartmentSelect
-------------------
-
-A ``Select`` widget that uses a list of Peruvian Departments as its choices.
-
-Poland (``django.contrib.localflavor.pl``)
-==========================================
-
-PLNationalIdentificationNumberField
------------------------------------
-
-A form field that validates input as a Polish national identification number
-(PESEL_).
-
-.. _PESEL: http://en.wikipedia.org/wiki/PESEL
-
-PLNationalBusinessRegisterField
--------------------------------
-
-A form field that validates input as a Polish National Official Business
-Register Number (REGON_), having either seven or nine digits. The checksum
-algorithm used for REGONs is documented at
-http://wipos.p.lodz.pl/zylla/ut/nip-rego.html.
-
-.. _REGON: http://www.stat.gov.pl/bip/regon_ENG_HTML.htm
-
-PLPostalCodeField
------------------
-
-A form field that validates input as a Polish postal code. The valid format
-is XX-XXX, where X is a digit.
-
-PLTaxNumberField
-----------------
-
-A form field that validates input as a Polish Tax Number (NIP). Valid
-formats are XXX-XXX-XX-XX or XX-XX-XXX-XXX. The checksum algorithm used
-for NIPs is documented at http://wipos.p.lodz.pl/zylla/ut/nip-rego.html.
-
-PLAdministrativeUnitSelect
---------------------------
-
-A ``Select`` widget that uses a list of Polish administrative units as its
-choices.
-
-PLVoivodeshipSelect
--------------------
-
-A ``Select`` widget that uses a list of Polish voivodeships (administrative
-provinces) as its choices.
-
-Romania (``django.contrib.localflavor.ro``)
-============================================
-
-ROCIFField
-----------
-
-A form field that validates Romanian fiscal identification codes (CIF). The
-return value strips the leading RO, if given.
-
-ROCNPField
-----------
-
-A form field that validates Romanian personal numeric codes (CNP).
-
-ROCountyField
--------------
-
-A form field that validates its input as a Romanian county (judet) name or
-abbreviation. It normalizes the input to the standard vehicle registration
-abbreviation for the given county. This field will only accept names written
-with diacritics; consider using ROCountySelect as an alternative.
-
-ROCountySelect
---------------
-
-A ``Select`` widget that uses a list of Romanian counties (judete) as its
-choices.
-
-ROIBANField
------------
-
-A form field that validates its input as a Romanian International Bank 
-Account Number (IBAN). The valid format is ROXX-XXXX-XXXX-XXXX-XXXX-XXXX,
-with or without hyphens.
-
-ROPhoneNumberField
-------------------
-
-A form field that validates Romanian phone numbers, short special numbers
-excluded.
-
-ROPostalCodeField
------------------
-
-A form field that validates Romanian postal codes.
-
-Slovakia (``django.contrib.localflavor.sk``)
-============================================
-
-SKPostalCodeField
------------------
-
-A form field that validates input as a Slovak postal code. Valid formats
-are XXXXX or XXX XX, where X is a digit.
-
-SKDistrictSelect
-----------------
-
-A ``Select`` widget that uses a list of Slovak districts as its choices.
-
-SKRegionSelect
---------------
-
-A ``Select`` widget that uses a list of Slovak regions as its choices.
-
-South Africa (``django.contrib.localflavor.za``)
-================================================
-
-ZAIDField
----------
-
-A form field that validates input as a South African ID number. Validation
-uses the Luhn checksum and a simplistic (i.e., not entirely accurate) check
-for birth date.
-
-ZAPostCodeField
----------------
-
-A form field that validates input as a South African postcode. Valid
-postcodes must have four digits.
-
-Spain (``django.contrib.localflavor.es``)
-=========================================
-
-ESIdentityCardNumberField
--------------------------
-
-A form field that validates input as a Spanish NIF/NIE/CIF (Fiscal
-Identification Number) code.
-
-ESCCCField
-----------
-
-A form field that validates input as a Spanish bank account number (Codigo
-Cuenta Cliente or CCC). A valid CCC number has the format
-EEEE-OOOO-CC-AAAAAAAAAA, where the E, O, C and A digits denote the entity,
-office, checksum and account, respectively. The first checksum digit
-validates the entity and office. The second checksum digit validates the
-account. It is also valid to use a space as a delimiter, or to use no
-delimiter.
-
-ESPhoneNumberField
-------------------
-
-A form field that validates input as a Spanish phone number. Valid numbers
-have nine digits, the first of which is 6, 8 or 9.
-
-ESPostalCodeField
------------------
-
-A form field that validates input as a Spanish postal code. Valid codes
-have five digits, the first two being in the range 01 to 52, representing
-the province.
-
-ESProvinceSelect
-----------------
-
-A ``Select`` widget that uses a list of Spanish provinces as its choices.
-
-ESRegionSelect
---------------
-
-A ``Select`` widget that uses a list of Spanish regions as its choices.
-
-Switzerland (``django.contrib.localflavor.ch``)
-===============================================
-
-CHIdentityCardNumberField
--------------------------
-
-A form field that validates input as a Swiss identity card number.
-A valid number must confirm to the X1234567<0 or 1234567890 format and
-have the correct checksums -- see http://adi.kousz.ch/artikel/IDCHE.htm.
-
-CHPhoneNumberField
-------------------
-
-A form field that validates input as a Swiss phone number. The correct
-format is 0XX XXX XX XX. 0XX.XXX.XX.XX and 0XXXXXXXXX validate but are
-corrected to 0XX XXX XX XX.
-
-CHZipCodeField
---------------
-
-A form field that validates input as a Swiss zip code. Valid codes
-consist of four digits.
-
-CHStateSelect
--------------
-
-A ``Select`` widget that uses a list of Swiss states as its choices.
-
-United Kingdom (``django.contrib.localflavor.uk``)
-==================================================
-
-UKPostcodeField
----------------
-
-A form field that validates input as a UK postcode. The regular
-expression used is sourced from the schema for British Standard BS7666
-address types at http://www.govtalk.gov.uk/gdsc/schemas/bs7666-v2-0.xsd.
-
-UKCountySelect
---------------
-
-A ``Select`` widget that uses a list of UK counties/regions as its choices.
-
-UKNationSelect
---------------
-
-A ``Select`` widget that uses a list of UK nations as its choices.
-
-United States of America (``django.contrib.localflavor.us``)
-============================================================
-
-USPhoneNumberField
-------------------
-
-A form field that validates input as a U.S. phone number.
-
-USSocialSecurityNumberField
----------------------------
-
-A form field that validates input as a U.S. Social Security Number (SSN).
-A valid SSN must obey the following rules:
-
-    * Format of XXX-XX-XXXX
-    * No group of digits consisting entirely of zeroes
-    * Leading group of digits cannot be 666
-    * Number not in promotional block 987-65-4320 through 987-65-4329
-    * Number not one known to be invalid due to widespread promotional
-      use or distribution (e.g., the Woolworth's number or the 1962
-      promotional number)
-
-USStateField
-------------
-
-A form field that validates input as a U.S. state name or abbreviation. It
-normalizes the input to the standard two-letter postal service abbreviation
-for the given state.
-
-USZipCodeField
---------------
-
-A form field that validates input as a U.S. ZIP code. Valid formats are
-XXXXX or XXXXX-XXXX.
-
-USStateSelect
--------------
-
-A form ``Select`` widget that uses a list of U.S. states/territories as its
-choices.

+ 1 - 2
docs/man/django-admin.1

@@ -159,8 +159,7 @@ The file extension(s) to examine (default: ".html", separate multiple
 extensions with commas, or use -e multiple times).
 .TP
 .I \-a, \-\-all
-Process all available locales when using makemessages.
-.SH "ENVIRONMENT"
+Process all available locales when using makemessages..SH "ENVIRONMENT"
 .TP
 .I DJANGO_SETTINGS_MODULE
 In the absence of the

+ 0 - 288
docs/middleware.txt

@@ -1,288 +0,0 @@
-==========
-Middleware
-==========
-
-Middleware is a framework of hooks into Django's request/response processing.
-It's a light, low-level "plugin" system for globally altering Django's input
-and/or output.
-
-Each middleware component is responsible for doing some specific function. For
-example, Django includes a middleware component, ``XViewMiddleware``, that adds
-an ``"X-View"`` HTTP header to every response to a ``HEAD`` request.
-
-This document explains all middleware components that come with Django, how to
-use them, and how to write your own middleware.
-
-Activating middleware
-=====================
-
-To activate a middleware component, add it to the ``MIDDLEWARE_CLASSES`` list
-in your Django settings. In ``MIDDLEWARE_CLASSES``, each middleware component
-is represented by a string: the full Python path to the middleware's class
-name. For example, here's the default ``MIDDLEWARE_CLASSES`` created by
-``django-admin.py startproject``::
-
-    MIDDLEWARE_CLASSES = (
-        'django.middleware.common.CommonMiddleware',
-        'django.contrib.sessions.middleware.SessionMiddleware',
-        'django.contrib.auth.middleware.AuthenticationMiddleware',
-        'django.middleware.doc.XViewMiddleware',
-    )
-
-Django applies middleware in the order it's defined in ``MIDDLEWARE_CLASSES``,
-except in the case of response and exception middleware, which is applied in
-reverse order.
-
-A Django installation doesn't require any middleware -- e.g.,
-``MIDDLEWARE_CLASSES`` can be empty, if you'd like -- but it's strongly
-suggested that you use ``CommonMiddleware``.
-
-Available middleware
-====================
-
-django.middleware.cache.CacheMiddleware
----------------------------------------
-
-Enables site-wide cache. If this is enabled, each Django-powered page will be
-cached for as long as the ``CACHE_MIDDLEWARE_SECONDS`` setting defines. See
-the `cache documentation`_.
-
-.. _`cache documentation`: ../cache/#the-per-site-cache
-
-django.middleware.common.CommonMiddleware
------------------------------------------
-
-Adds a few conveniences for perfectionists:
-
-* Forbids access to user agents in the ``DISALLOWED_USER_AGENTS`` setting,
-  which should be a list of strings.
-
-* Performs URL rewriting based on the ``APPEND_SLASH`` and ``PREPEND_WWW``
-  settings.
-
-  If ``APPEND_SLASH`` is ``True`` and the initial URL doesn't end with a slash,
-  and it is not found in the URLconf, then a new URL is formed by appending a
-  slash at the end. If this new URL is found in the URLconf, then Django
-  redirects the request to this new URL. Otherwise, the initial URL is
-  processed as usual.
-
-  For example, ``foo.com/bar`` will be redirected to ``foo.com/bar/`` if you
-  don't have a valid URL pattern for ``foo.com/bar`` but *do* have a valid
-  pattern for ``foo.com/bar/``.
-
-  **New in Django development version:** The behavior of ``APPEND_SLASH`` has
-  changed slightly in the development version. It didn't used to check whether
-  the pattern was matched in the URLconf.
-
-  If ``PREPEND_WWW`` is ``True``, URLs that lack a leading "www." will be
-  redirected to the same URL with a leading "www."
-
-  Both of these options are meant to normalize URLs. The philosophy is that
-  each URL should exist in one, and only one, place. Technically a URL
-  ``foo.com/bar`` is distinct from ``foo.com/bar/`` -- a search-engine
-  indexer would treat them as separate URLs -- so it's best practice to
-  normalize URLs.
-
-* Handles ETags based on the ``USE_ETAGS`` setting. If ``USE_ETAGS`` is set
-  to ``True``, Django will calculate an ETag for each request by
-  MD5-hashing the page content, and it'll take care of sending
-  ``Not Modified`` responses, if appropriate.
-
-django.middleware.doc.XViewMiddleware
--------------------------------------
-
-Sends custom ``X-View`` HTTP headers to HEAD requests that come from IP
-addresses defined in the ``INTERNAL_IPS`` setting. This is used by Django's
-automatic documentation system.
-
-django.middleware.gzip.GZipMiddleware
--------------------------------------
-
-Compresses content for browsers that understand gzip compression (all modern
-browsers).
-
-It is suggested to place this first in the middleware list, so that the
-compression of the response content is the last thing that happens. Will not
-compress content bodies less than 200 bytes long, when the response code is
-something other than 200, JavaScript files (for IE compatibitility), or
-responses that have the ``Content-Encoding`` header already specified.
-
-django.middleware.http.ConditionalGetMiddleware
------------------------------------------------
-
-Handles conditional GET operations. If the response has a ``ETag`` or
-``Last-Modified`` header, and the request has ``If-None-Match`` or
-``If-Modified-Since``, the response is replaced by an HttpNotModified.
-
-Also sets the ``Date`` and ``Content-Length`` response-headers.
-
-django.middleware.http.SetRemoteAddrFromForwardedFor
-----------------------------------------------------
-
-Sets ``request.META['REMOTE_ADDR']`` based on
-``request.META['HTTP_X_FORWARDED_FOR']``, if the latter is set. This is useful
-if you're sitting behind a reverse proxy that causes each request's
-``REMOTE_ADDR`` to be set to ``127.0.0.1``.
-
-**Important note:** This does NOT validate ``HTTP_X_FORWARDED_FOR``. If you're
-not behind a reverse proxy that sets ``HTTP_X_FORWARDED_FOR`` automatically, do
-not use this middleware. Anybody can spoof the value of
-``HTTP_X_FORWARDED_FOR``, and because this sets ``REMOTE_ADDR`` based on
-``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
-----------------------------------------------------
-
-Enables session support. See the `session documentation`_.
-
-.. _`session documentation`: ../sessions/
-
-django.contrib.auth.middleware.AuthenticationMiddleware
--------------------------------------------------------
-
-Adds the ``user`` attribute, representing the currently-logged-in user, to
-every incoming ``HttpRequest`` object. See `Authentication in Web requests`_.
-
-.. _Authentication in Web requests: ../authentication/#authentication-in-web-requests
-
-django.contrib.csrf.middleware.CsrfMiddleware
----------------------------------------------
-
-**New in Django development version**
-
-Adds protection against Cross Site Request Forgeries by adding hidden form
-fields to POST forms and checking requests for the correct value. See the
-`Cross Site Request Forgery protection documentation`_.
-
-.. _`Cross Site Request Forgery protection documentation`: ../csrf/
-
-django.middleware.transaction.TransactionMiddleware
----------------------------------------------------
-
-Binds commit and rollback to the request/response phase. If a view function runs
-successfully, a commit is done. If it fails with an exception, a rollback is
-done.
-
-The order of this middleware in the stack is important: middleware modules
-running outside of it run with commit-on-save - the default Django behavior.
-Middleware modules running inside it (coming later in the stack) will be under
-the same transaction control as the view functions.
-
-See the `transaction management documentation`_.
-
-.. _`transaction management documentation`: ../transactions/
-
-Writing your own middleware
-===========================
-
-Writing your own middleware is easy. Each middleware component is a single
-Python class that defines one or more of the following methods:
-
-``process_request``
--------------------
-
-Interface: ``process_request(self, request)``
-
-``request`` is an ``HttpRequest`` object. This method is called on each
-request, before Django decides which view to execute.
-
-``process_request()`` should return either ``None`` or an ``HttpResponse``
-object. If it returns ``None``, Django will continue processing this request,
-executing any other middleware and, then, the appropriate view. If it returns
-an ``HttpResponse`` object, Django won't bother calling ANY other request,
-view or exception middleware, or the appropriate view; it'll return that
-``HttpResponse``. Response middleware is always called on every response.
-
-``process_view``
-----------------
-
-Interface: ``process_view(self, request, view_func, view_args, view_kwargs)``
-
-``request`` is an ``HttpRequest`` object. ``view_func`` is the Python function
-that Django is about to use. (It's the actual function object, not the name of
-the function as a string.) ``view_args`` is a list of positional arguments that
-will be passed to the view, and ``view_kwargs`` is a dictionary of keyword
-arguments that will be passed to the view. Neither ``view_args`` nor
-``view_kwargs`` include the first view argument (``request``).
-
-``process_view()`` is called just before Django calls the view. It should
-return either ``None`` or an ``HttpResponse`` object. If it returns ``None``,
-Django will continue processing this request, executing any other
-``process_view()`` middleware and, then, the appropriate view. If it returns an
-``HttpResponse`` object, Django won't bother calling ANY other request, view
-or exception middleware, or the appropriate view; it'll return that
-``HttpResponse``. Response middleware is always called on every response.
-
-``process_response``
---------------------
-
-Interface: ``process_response(self, request, response)``
-
-``request`` is an ``HttpRequest`` object. ``response`` is the ``HttpResponse``
-object returned by a Django view.
-
-``process_response()`` should return an ``HttpResponse`` object. It could alter
-the given ``response``, or it could create and return a brand-new
-``HttpResponse``.
-
-``process_exception``
----------------------
-
-Interface: ``process_exception(self, request, exception)``
-
-``request`` is an ``HttpRequest`` object. ``exception`` is an ``Exception``
-object raised by the view function.
-
-Django calls ``process_exception()`` when a view raises an exception.
-``process_exception()`` should return either ``None`` or an ``HttpResponse``
-object. If it returns an ``HttpResponse`` object, the response will be returned
-to the browser. Otherwise, default exception handling kicks in.
-
-``__init__``
-------------
-
-Most middleware classes won't need an initializer since middleware classes are
-essentially placeholders for the ``process_*`` methods. If you do need some
-global state you may use ``__init__`` to set up. However, keep in mind a couple
-of caveats:
-
-    * Django initializes your middleware without any arguments, so you can't
-      define ``__init__`` as requiring any arguments.
-      
-    * Unlike the ``process_*`` methods which get called once per request,
-      ``__init__`` gets called only *once*, when the web server starts up.
-
-Marking middleware as unused
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-It's sometimes useful to determine at run-time whether a piece of middleware
-should be used. In these cases, your middleware's ``__init__`` method may raise
-``django.core.exceptions.MiddlewareNotUsed``. Django will then remove that piece
-of middleware from the middleware process.
-
-Guidelines
-----------
-
-    * Middleware classes don't have to subclass anything.
-
-    * The middleware class can live anywhere on your Python path. All Django
-      cares about is that the ``MIDDLEWARE_CLASSES`` setting includes the path
-      to it.
-
-    * Feel free to look at Django's available middleware for examples. The
-      core Django middleware classes are in ``django/middleware/`` in the
-      Django distribution. The session middleware is in
-      ``django/contrib/sessions``.
-
-    * If you write a middleware component that you think would be useful to
-      other people, contribute to the community! Let us know, and we'll
-      consider adding it to Django.

+ 95 - 0
docs/misc/api-stability.txt

@@ -0,0 +1,95 @@
+.. _misc-api-stability:
+
+=============
+API stability
+=============
+
+Although Django has not reached a 1.0 release, the bulk of Django's public APIs are
+stable as of the 0.95 release. This document explains which APIs will and will not
+change before the 1.0 release.
+
+What "stable" means
+===================
+
+In this context, stable means:
+
+   - All the public APIs -- everything documented in the linked documents, and
+     all methods that don't begin with an underscore -- will not be moved or
+     renamed without providing backwards-compatible aliases.
+     
+   - If new features are added to these APIs -- which is quite possible --
+     they will not break or change the meaning of existing methods. In other
+     words, "stable" does not (necessarily) mean "complete."
+     
+   - If, for some reason, an API declared stable must be removed or replaced, it
+     will be declared deprecated but will remain in the API until at least
+     version 1.1. Warnings will be issued when the deprecated method is
+     called.
+     
+   - We'll only break backwards compatibility of these APIs if a bug or
+     security hole makes it completely unavoidable.
+
+Stable APIs
+===========
+
+These APIs are stable:
+
+   - :ref:`Caching <topics-cache>`.
+   
+   - :ref:`Custom template tags and libraries <howto-custom-template-tags>`.
+     
+   - :ref:`Database lookup <topics-db-queries>` (with the exception of validation; see below).
+    
+   - :ref:`django-admin utility <ref-django-admin>`.
+   
+   - :ref:`FastCGI and mod_python integration <howto-deployment-index>`.
+   
+   - :ref:`Flatpages <ref-contrib-flatpages>`.
+   
+   - :ref:`Generic views <topics-http-generic-views>`.
+   
+   - :ref:`Internationalization <topics-i18n>`.
+   
+   - :ref:`Legacy database integration <howto-legacy-databases>`.
+   
+   - :ref:`Model definition <topics-db-models>` (with the exception of generic relations; see below).
+      
+   - :ref:`Redirects <ref-contrib-redirects>`.
+   
+   - :ref:`Request/response objects <ref-request-response>`.
+   
+   - :ref:`Sending e-mail <topics-email>`.
+   
+   - :ref:`Sessions <topics-http-sessions>`.
+   
+   - :ref:`Settings <topics-settings>`.
+   
+   - :ref:`Syndication <ref-contrib-syndication>`.
+   
+   - :ref:`Template language <topics-templates>` (with the exception of some
+     possible disambiguation of how tag arguments are passed to tags and
+     filters).
+   
+   - :ref:`Transactions <topics-db-transactions>`.
+   
+   - :ref:`URL dispatch <topics-http-urls>`.
+   
+You'll notice that this list comprises the bulk of Django's APIs. That's right
+-- most of the changes planned between now and Django 1.0 are either under the
+hood, feature additions, or changes to a few select bits. A good estimate is
+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:
+
+   - :ref:`Serialization <topics-serialization>` is under development; changes
+     are possible.
+
+   - Generic relations will most likely be moved out of core and into the
+     content-types contrib package to avoid core dependencies on optional
+     components.
+     
+     **New in development version**: this has now been done.
+
+   - The comments framework, which is yet undocumented, will get a complete
+     rewrite before Django 1.0.

+ 37 - 4
docs/design_philosophies.txt → docs/misc/design-philosophies.txt

@@ -1,3 +1,5 @@
+.. _misc-design-philosophies:
+
 ===================
 Design philosophies
 ===================
@@ -9,9 +11,13 @@ the future.
 Overall
 =======
 
+.. _loose-coupling:
+
 Loose coupling
 --------------
 
+.. index:: coupling; loose
+
 A fundamental goal of Django's stack is `loose coupling and tight cohesion`_.
 The various layers of the framework shouldn't "know" about each other unless
 absolutely necessary.
@@ -25,6 +31,8 @@ stack are independent of another wherever possible.
 
 .. _`loose coupling and tight cohesion`: http://c2.com/cgi/wiki?CouplingAndCohesion
 
+.. _less-code:
+
 Less code
 ---------
 
@@ -32,6 +40,8 @@ Django apps should use as little code as possible; they should lack boilerplate.
 Django should take full advantage of Python's dynamic capabilities, such as
 introspection.
 
+.. _quick-development:
+
 Quick development
 -----------------
 
@@ -39,15 +49,29 @@ The point of a Web framework in the 21st century is to make the tedious aspects
 of Web development fast. Django should allow for incredibly quick Web
 development.
 
+.. _dry:
+
 Don't repeat yourself (DRY)
 ---------------------------
 
+.. index::
+   single: DRY
+   single: Don't repeat yourself
+
 Every distinct concept and/or piece of data should live in one, and only one,
 place. Redundancy is bad. Normalization is good.
 
 The framework, within reason, should deduce as much as possible from as little
 as possible.
 
+.. seealso::
+
+    The `discussion of DRY on the Portland Pattern Repository`__
+
+    __ http://c2.com/cgi/wiki?DontRepeatYourself
+    
+.. _explicit-is-better-than-implicit:
+
 Explicit is better than implicit
 --------------------------------
 
@@ -59,6 +83,8 @@ learn how to use the feature.
 
 .. _`core Python principle`: http://www.python.org/dev/peps/pep-0020/
 
+.. _consistency:
+
 Consistency
 -----------
 
@@ -155,19 +181,25 @@ File extensions in Web-page URLs should be avoided.
 
 Vignette-style commas in URLs deserve severe punishment.
 
+.. _definitive-urls:
+
 Definitive URLs
 ---------------
 
+.. index:: urls; definitive
+
 Technically, ``foo.com/bar`` and ``foo.com/bar/`` are two different URLs, and
 search-engine robots (and some Web traffic-analyzing tools) would treat them as
 separate pages. Django should make an effort to "normalize" URLs so that
 search-engine robots don't get confused.
 
-This is the reasoning behind the ``APPEND_SLASH`` setting.
+This is the reasoning behind the :setting:`APPEND_SLASH` setting.
 
 Template system
 ===============
 
+.. _separation-of-logic-and-presentation:
+
 Separate logic from presentation
 --------------------------------
 
@@ -186,9 +218,8 @@ a common header, footer, navigation bar, etc. The Django template system should
 make it easy to store those elements in a single place, eliminating duplicate
 code.
 
-This is the philosophy behind `template inheritance`_.
-
-.. _template inheritance: ../templates/#template-inheritance
+This is the philosophy behind :ref:`template inheritance
+<template-inheritance>`.
 
 Be decoupled from HTML
 ----------------------
@@ -200,6 +231,8 @@ text.
 XML should not be used for template languages
 ---------------------------------------------
 
+.. index:: xml; suckiness of
+
 Using an XML engine to parse templates introduces a whole new world of human
 error in editing templates -- and incurs an unacceptable level of overhead in
 template processing.

+ 4 - 4
docs/distributions.txt → docs/misc/distributions.txt

@@ -1,3 +1,5 @@
+.. _misc-distributions:
+
 ===================================
 Third-party distributions of Django
 ===================================
@@ -10,10 +12,8 @@ requires.
 
 Typically, these packages are based on the latest stable release of Django, so
 if you want to use the development version of Django you'll need to follow the
-instructions for `installing the development version`_ from our Subversion
-repository.
-
-.. _installing the development version: ../install/#installing-the-development-version
+instructions for :ref:`installing the development version
+<installing-development-version>` from our Subversion repository.
 
 FreeBSD
 =======

+ 14 - 0
docs/misc/index.txt

@@ -0,0 +1,14 @@
+.. _misc-index:
+
+Meta-documentation and miscellany
+=================================
+
+Documentation that we can't find a more organized place for. Like that drawer in
+your kitchen with the scissors, batteries, duct tape, and other junk.
+
+.. toctree::
+   :maxdepth: 2
+   
+   api-stability
+   design-philosophies
+   distributions

+ 0 - 2145
docs/model-api.txt

@@ -1,2145 +0,0 @@
-===============
-Model reference
-===============
-
-A model is the single, definitive source of data about your data. It contains
-the essential fields and behaviors of the data you're storing. Generally, each
-model maps to a single database table.
-
-The basics:
-
-    * Each model is a Python class that subclasses ``django.db.models.Model``.
-    * Each attribute of the model represents a database field.
-    * Model metadata (non-field information) goes in an inner class named
-      ``Meta``.
-    * With all of this, Django gives you an automatically-generated
-      database-access API, which is explained in the `Database API reference`_.
-
-A companion to this document is the `official repository of model examples`_.
-(In the Django source distribution, these examples are in the
-``tests/modeltests`` directory.)
-
-.. _Database API reference: ../db-api/
-.. _official repository of model examples: ../models/
-
-Quick example
-=============
-
-This example model defines a ``Person``, which has a ``first_name`` and
-``last_name``::
-
-    from django.db import models
-
-    class Person(models.Model):
-        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.
-
-The above ``Person`` model would create a database table like this::
-
-    CREATE TABLE myapp_person (
-        "id" serial NOT NULL PRIMARY KEY,
-        "first_name" varchar(30) NOT NULL,
-        "last_name" varchar(30) NOT NULL
-    );
-
-Some technical notes:
-
-    * The name of the table, ``myapp_person``, is automatically derived from
-      some model metadata but can be overridden. See `Table names`_ below.
-    * An ``id`` field is added automatically, but this behavior can be
-      overridden. See `Automatic primary key fields`_ below.
-    * The ``CREATE TABLE`` SQL in this example is formatted using PostgreSQL
-      syntax, but it's worth noting Django uses SQL tailored to the database
-      backend specified in your `settings file`_.
-
-.. _settings file: ../settings/
-
-Fields
-======
-
-The most important part of a model -- and the only required part of a model --
-is the list of database fields it defines. Fields are specified by class
-attributes.
-
-Example::
-
-    class Musician(models.Model):
-        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(max_length=100)
-        release_date = models.DateField()
-        num_stars = models.IntegerField()
-
-Field name restrictions
------------------------
-
-Django places only two restrictions on model field names:
-
-    1. A field name cannot be a Python reserved word, because that would result
-       in a Python syntax error. For example::
-
-           class Example(models.Model):
-               pass = models.IntegerField() # 'pass' is a reserved word!
-
-    2. A field name cannot contain more than one underscore in a row, due to
-       the way Django's query lookup syntax works. For example::
-
-           class Example(models.Model):
-               foo__bar = models.IntegerField() # 'foo__bar' has two underscores!
-
-These limitations can be worked around, though, because your field name doesn't
-necessarily have to match your database column name. See `db_column`_ below.
-
-SQL reserved words, such as ``join``, ``where`` or ``select``, *are* allowed as
-model field names, because Django escapes all database table names and column
-names in every underlying SQL query. It uses the quoting syntax of your
-particular database engine.
-
-Field types
------------
-
-Each field in your model should be an instance of the appropriate ``Field``
-class. Django uses the field class types to determine a few things:
-
-    * The database column type (e.g. ``INTEGER``, ``VARCHAR``).
-    * The widget to use in Django's admin interface, if you care to use it
-      (e.g. ``<input type="text">``, ``<select>``).
-    * The minimal validation requirements, used in Django's admin and in
-      automatically-generated forms.
-
-Here are all available field types:
-
-``AutoField``
-~~~~~~~~~~~~~
-
-An ``IntegerField`` that automatically increments according to available IDs.
-You usually won't need to use this directly; a primary key field will
-automatically be added to your model if you don't specify otherwise. See
-`Automatic primary key fields`_.
-
-``BooleanField``
-~~~~~~~~~~~~~~~~
-
-A true/false field.
-
-The admin represents this as a checkbox.
-
-``CharField``
-~~~~~~~~~~~~~
-
-A string field, for small- to large-sized strings.
-
-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, ``max_length``, the maximum length
-(in characters) of the field. The max_length is enforced at the database level
-and in Django's validation.
-
-``CommaSeparatedIntegerField``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-A field of integers separated by commas. As in ``CharField``, the ``max_length``
-argument is required.
-
-``DateField``
-~~~~~~~~~~~~~
-
-A date field. Has a few extra optional arguments:
-
-    ======================  ===================================================
-    Argument                Description
-    ======================  ===================================================
-    ``auto_now``            Automatically set the field to now every time the
-                            object is saved. Useful for "last-modified"
-                            timestamps. Note that the current date is *always*
-                            used; it's not just a default value that you can
-                            override.
-
-    ``auto_now_add``        Automatically set the field to now when the object
-                            is first created. Useful for creation of
-                            timestamps. Note that the current date is *always*
-                            used; it's not just a default value that you can
-                            override.
-    ======================  ===================================================
-
-The admin represents this as an ``<input type="text">`` with a JavaScript
-calendar, and a shortcut for "Today."  The JavaScript calendar will always start
-the week on a Sunday.
-
-``DateTimeField``
-~~~~~~~~~~~~~~~~~
-
-A date and time field. Takes the same extra options as ``DateField``.
-
-The admin represents this as two ``<input type="text">`` fields, with
-JavaScript shortcuts.
-
-``DecimalField``
-~~~~~~~~~~~~~~~~
-
-**New in Django development version**
-
-A fixed-precision decimal number, represented in Python by a ``Decimal`` instance.
-Has two **required** arguments:
-
-    ======================  ===================================================
-    Argument                Description
-    ======================  ===================================================
-    ``max_digits``          The maximum number of digits allowed in the number.
-
-    ``decimal_places``      The number of decimal places to store with the
-                            number.
-    ======================  ===================================================
-
-For example, to store numbers up to 999 with a resolution of 2 decimal places,
-you'd use::
-
-    models.DecimalField(..., max_digits=5, decimal_places=2)
-
-And to store numbers up to approximately one billion with a resolution of 10
-decimal places::
-
-    models.DecimalField(..., max_digits=19, decimal_places=10)
-
-The admin represents this as an ``<input type="text">`` (a single-line input).
-
-``EmailField``
-~~~~~~~~~~~~~~
-
-A ``CharField`` that checks that the value is a valid e-mail address.
-
-In Django 0.96, this doesn't accept ``max_length``; its ``max_length`` is
-automatically set to 75. In the Django development version, ``max_length`` is
-set to 75 by default, but you can specify it to override default behavior.
-
-``FileField``
-~~~~~~~~~~~~~
-
-A file-upload field. Has two special arguments, of which the first is
-**required**:
-
-    ======================  ===================================================
-    Argument                Description
-    ======================  ===================================================
-    ``upload_to``           Required. A filesystem-style path that will be
-                            prepended to the filename before being committed to
-                            the final storage destination.
-
-                            **New in Django development version**
-
-                            This may also be a callable, such as a function,
-                            which will be called to obtain the upload path,
-                            including the filename. See below for details.
-
-    ``storage``             **New in Django development version**
-
-                            Optional. A storage object, which handles the
-                            storage and retrieval of your files. See `managing
-                            files`_ for details on how to provide this object.
-    ======================  ===================================================
-
-.. _managing files: ../files/
-
-The ``upload_to`` path may contain `strftime formatting`_, which will be
-replaced by the date/time of the file upload (so that uploaded files don't fill
-up the given directory).
-
-**New in Django development version**
-
-If a callable is provided for the ``upload_to`` argument, that callable must be
-able to accept two arguments, and return a Unix-style path (with forward
-slashes) to be passed along to the storage system. The two arguments that will
-be passed are:
-
-    ======================  ===================================================
-    Argument                Description
-    ======================  ===================================================
-    ``instance``            An instance of the model where the ``FileField`` is
-                            defined. More specifically, this is the particular
-                            instance where the current file is being attached.
-
-                            **Note**: In most cases, this object will not have
-                            been saved to the database yet, so if it uses the
-                            default ``AutoField``, *it might not yet have a
-                            value for its primary key field*.
-
-    ``filename``            The filename that was originally given to the file.
-                            This may or may not be taken into account when
-                            determining the final destination path.
-    ======================  ===================================================
-
-The admin represents this field as an ``<input type="file">`` (a file-upload
-widget).
-
-Using a ``FileField`` or an ``ImageField`` (see below) in a model without a
-specified storage system takes a few steps:
-
-    1. In your settings file, you'll need to define ``MEDIA_ROOT`` as the
-       full path to a directory where you'd like Django to store uploaded
-       files. (For performance, these files are not stored in the database.)
-       Define ``MEDIA_URL`` as the base public URL of that directory. Make
-       sure that this directory is writable by the Web server's user
-       account.
-
-    2. Add the ``FileField`` or ``ImageField`` to your model, making sure
-       to define the ``upload_to`` option to tell Django to which
-       subdirectory of ``MEDIA_ROOT`` it should upload files.
-
-    3. All that will be stored in your database is a path to the file
-       (relative to ``MEDIA_ROOT``). You'll most likely want to use
-       ``object.<field>.url`` to get the actual URL. For example, if your
-       ``ImageField`` is called ``mug_shot``, you can get the absolute URL to
-       your image in a template with ``{{ object.mug_shot.url }}``.
-
-For example, say your ``MEDIA_ROOT`` is set to ``'/home/media'``, and
-``upload_to`` is set to ``'photos/%Y/%m/%d'``. The ``'%Y/%m/%d'`` part of
-``upload_to`` is strftime formatting; ``'%Y'`` is the four-digit year,
-``'%m'`` is the two-digit month and ``'%d'`` is the two-digit day. If you
-upload a file on Jan. 15, 2007, it will be saved in the directory
-``/home/media/photos/2007/01/15``.
-
-Information about the uploaded ``File`` object, such as its on-disk filename,
-its size, or its URL, is available via attributes on the object itself. See the
-`managing files`__ documentation for more information about ``File`` objects.
-
-__ ../files/
-
-Note that whenever you deal with uploaded files, you should pay close attention
-to where you're uploading them and what type of files they are, to avoid
-security holes. *Validate all uploaded files* so that you're sure the files are
-what you think they are. For example, if you blindly let somebody upload files,
-without validation, to a directory that's within your Web server's document
-root, then somebody could upload a CGI or PHP script and execute that script by
-visiting its URL on your site. Don't allow that.
-
-.. _`strftime formatting`: http://docs.python.org/lib/module-time.html#l2h-1941
-
-**New in development version:**  By default, ``FileField`` instances are
-created as ``varchar(100)`` columns in your database. As with other fields, you
-can change the maximum length using the ``max_length`` argument.
-
-``FilePathField``
-~~~~~~~~~~~~~~~~~
-
-A field whose choices are limited to the filenames in a certain directory
-on the filesystem. Has three special arguments, of which the first is
-**required**:
-
-    ======================  ===================================================
-    Argument                Description
-    ======================  ===================================================
-    ``path``                Required. The absolute filesystem path to a
-                            directory from which this ``FilePathField`` should
-                            get its choices. Example: ``"/home/images"``.
-
-    ``match``               Optional. A regular expression, as a string, that
-                            ``FilePathField`` will use to filter filenames.
-                            Note that the regex will be applied to the
-                            base filename, not the full path. Example:
-                            ``"foo.*\.txt$"``, which will match a file called
-                            ``foo23.txt`` but not ``bar.txt`` or ``foo23.gif``.
-
-    ``recursive``           Optional. Either ``True`` or ``False``. Default is
-                            ``False``. Specifies whether all subdirectories of
-                            ``path`` should be included.
-    ======================  ===================================================
-
-Of course, these arguments can be used together.
-
-The one potential gotcha is that ``match`` applies to the base filename,
-not the full path. So, this example::
-
-    FilePathField(path="/home/images", match="foo.*", recursive=True)
-
-...will match ``/home/images/foo.gif`` but not ``/home/images/foo/bar.gif``
-because the ``match`` applies to the base filename (``foo.gif`` and
-``bar.gif``).
-
-**New in development version:**  By default, ``FilePathField`` instances are
-created as ``varchar(100)`` columns in your database. As with other fields, you
-can change the maximum length using the ``max_length`` argument.
-
-``FloatField``
-~~~~~~~~~~~~~~
-
-**Changed in Django development version**
-
-A floating-point number represented in Python by a ``float`` instance.
-
-The admin represents this as an ``<input type="text">`` (a single-line input).
-
-**NOTE:** The semantics of ``FloatField`` have changed in the Django
-development version. See the `Django 0.96 documentation`_ for the old behavior.
-
-.. _Django 0.96 documentation: http://www.djangoproject.com/documentation/0.96/model-api/#floatfield
-
-``ImageField``
-~~~~~~~~~~~~~~
-
-Like `FileField`_, but validates that the uploaded object is a valid
-image. Has two extra optional arguments, ``height_field`` and
-``width_field``, which, if set, will be auto-populated with the height and
-width of the image each time a model instance is saved.
-
-In addition to the `standard attributes and methods`_ that are available for
-``FileField``, an ``ImageField`` also has ``width`` and ``height`` attributes.
-
-Requires the `Python Imaging Library`_.
-
-**New in development version:**  By default, ``ImageField`` instances are
-created as ``varchar(100)`` columns in your database. As with other fields, you
-can change the maximum length using the ``max_length`` argument.
-
-.. _standard attributes and methods: ../files/#file-attributes-and-methods
-.. _Python Imaging Library: http://www.pythonware.com/products/pil/
-
-``IntegerField``
-~~~~~~~~~~~~~~~~
-
-An integer.
-
-The admin represents this as an ``<input type="text">`` (a single-line input).
-
-``IPAddressField``
-~~~~~~~~~~~~~~~~~~
-
-An IP address, in string format (e.g. "192.0.2.30").
-
-The admin represents this as an ``<input type="text">`` (a single-line input).
-
-``NullBooleanField``
-~~~~~~~~~~~~~~~~~~~~
-
-Like a ``BooleanField``, but allows ``NULL`` as one of the options.  Use this
-instead of a ``BooleanField`` with ``null=True``.
-
-The admin represents this as a ``<select>`` box with "Unknown", "Yes" and "No" choices.
-
-``PhoneNumberField``
-~~~~~~~~~~~~~~~~~~~~
-
-A ``CharField`` that checks that the value is a valid U.S.A.-style phone
-number (in the format ``XXX-XXX-XXXX``).
-
-``PositiveIntegerField``
-~~~~~~~~~~~~~~~~~~~~~~~~
-
-Like an ``IntegerField``, but must be positive.
-
-``PositiveSmallIntegerField``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Like a ``PositiveIntegerField``, but only allows values under a certain
-(database-dependent) point.
-
-``SlugField``
-~~~~~~~~~~~~~
-
-"Slug" is a newspaper term. A slug is a short label for something,
-containing only letters, numbers, underscores or hyphens. They're generally
-used in URLs.
-
-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``.
-
-``SmallIntegerField``
-~~~~~~~~~~~~~~~~~~~~~
-
-Like an ``IntegerField``, but only allows values under a certain
-(database-dependent) point.
-
-``TextField``
-~~~~~~~~~~~~~
-
-A large text field.
-
-The admin represents this as a ``<textarea>`` (a multi-line input).
-
-``TimeField``
-~~~~~~~~~~~~~
-
-A time. Accepts the same auto-population options as ``DateField`` and
-``DateTimeField``.
-
-The admin represents this as an ``<input type="text">`` with some
-JavaScript shortcuts.
-
-``URLField``
-~~~~~~~~~~~~
-
-A field for a URL. If the ``verify_exists`` option is ``True`` (default),
-the URL given will be checked for existence (i.e., the URL actually loads
-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, ``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``
-~~~~~~~~~~~~~~~~
-
-A two-letter U.S. state abbreviation.
-
-The admin represents this as an ``<input type="text">`` (a single-line input).
-
-``XMLField``
-~~~~~~~~~~~~
-
-A ``TextField`` that checks that the value is valid XML that matches a
-given schema. Takes one required argument, ``schema_path``, which is the
-filesystem path to a RelaxNG_ schema against which to validate the field.
-
-.. _RelaxNG: http://www.relaxng.org/
-
-Field options
--------------
-
-The following arguments are available to all field types. All are optional.
-
-``null``
-~~~~~~~~
-
-If ``True``, Django will store empty values as ``NULL`` in the database.
-Default is ``False``.
-
-Note that empty string values will always get stored as empty strings, not
-as ``NULL``. Only use ``null=True`` for non-string fields such as integers,
-booleans and dates. For both types of fields, you will also need to set
-``blank=True`` if you wish to permit empty values in forms, as the ``null``
-parameter only affects database storage (see blank_, below).
-
-Avoid using ``null`` on string-based fields such as ``CharField`` and
-``TextField`` unless you have an excellent reason. If a string-based field
-has ``null=True``, that means it has two possible values for "no data":
-``NULL``, and the empty string. In most cases, it's redundant to have two
-possible values for "no data;" Django convention is to use the empty
-string, not ``NULL``.
-
-.. note::
-    When using the Oracle database backend, the ``null=True`` option will
-    be coerced for string-based fields that can blank, and the value
-    ``NULL`` will be stored to denote the empty string.
-
-``blank``
-~~~~~~~~~
-
-If ``True``, the field is allowed to be blank. Default is ``False``.
-
-Note that this is different than ``null``. ``null`` is purely
-database-related, whereas ``blank`` is validation-related. If a field has
-``blank=True``, validation on Django's admin site will allow entry of an
-empty value. If a field has ``blank=False``, the field will be required.
-
-``choices``
-~~~~~~~~~~~
-
-An iterable (e.g., a list or tuple) of 2-tuples to use as choices for this
-field.
-
-If this is given, Django's admin will use a select box instead of the
-standard text field and will limit choices to the choices given.
-
-A choices list looks like this::
-
-    YEAR_IN_SCHOOL_CHOICES = (
-        ('FR', 'Freshman'),
-        ('SO', 'Sophomore'),
-        ('JR', 'Junior'),
-        ('SR', 'Senior'),
-        ('GR', 'Graduate'),
-    )
-
-The first element in each tuple is the actual value to be stored. The
-second element is the human-readable name for the option.
-
-The choices list can be defined either as part of your model class::
-
-    class Foo(models.Model):
-        GENDER_CHOICES = (
-            ('M', 'Male'),
-            ('F', 'Female'),
-        )
-        gender = models.CharField(max_length=1, choices=GENDER_CHOICES)
-
-or outside your model class altogether::
-
-    GENDER_CHOICES = (
-        ('M', 'Male'),
-        ('F', 'Female'),
-    )
-    class Foo(models.Model):
-        gender = models.CharField(max_length=1, choices=GENDER_CHOICES)
-
-You can also collect your available choices into named groups that can
-be used for organizational purposes::
-
-    MEDIA_CHOICES = (
-        ('Audio', (
-                ('vinyl', 'Vinyl'),
-                ('cd', 'CD'),
-            )
-        ),
-        ('Video', (
-                ('vhs', 'VHS Tape'),
-                ('dvd', 'DVD'),
-            )
-        ),
-        ('unknown', 'Unknown'),
-    )
-
-The first element in each tuple is the name to apply to the group. The
-second element is an iterable of 2-tuples, with each 2-tuple containing
-a value and a human-readable name for an option. Grouped options may be
-combined with ungrouped options within a single list (such as the
-`unknown` option in this example).
-
-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
-`get_FOO_display`_ in the database API documentation.
-
-.. _get_FOO_display: ../db-api/#get-foo-display
-
-Finally, note that choices can be any iterable object -- not necessarily a
-list or tuple. This lets you construct choices dynamically. But if you find
-yourself hacking ``choices`` to be dynamic, you're probably better off using
-a proper database table with a ``ForeignKey``. ``choices`` is meant for static
-data that doesn't change much, if ever.
-
-``core``
-~~~~~~~~
-
-For objects that are edited inline to a related object.
-
-In the Django admin, if all "core" fields in an inline-edited object are
-cleared, the object will be deleted.
-
-It is an error to have an inline-editable relation without at least one
-``core=True`` field.
-
-Please note that each field marked "core" is treated as a required field by the
-Django admin site. Essentially, this means you should put ``core=True`` on all
-required fields in your related object that is being edited inline.
-
-``db_column``
-~~~~~~~~~~~~~
-
-The name of the database column to use for this field. If this isn't given,
-Django will use the field's name.
-
-If your database column name is an SQL reserved word, or contains
-characters that aren't allowed in Python variable names -- notably, the
-hyphen -- that's OK. Django quotes column and table names behind the
-scenes.
-
-``db_index``
-~~~~~~~~~~~~
-
-If ``True``, ``django-admin.py sqlindexes`` will output a ``CREATE INDEX``
-statement for this field.
-
-``db_tablespace``
-~~~~~~~~~~~~~~~~~
-
-**New in Django development version**
-
-The name of the database tablespace to use for this field's index, if
-this field is indexed. The default is the project's
-``DEFAULT_INDEX_TABLESPACE`` setting, if set, or the ``db_tablespace``
-of the model, if any. If the backend doesn't support tablespaces, this
-option is ignored.
-
-``default``
-~~~~~~~~~~~
-
-The default value for the field. This can be a value or a callable object. If
-callable it will be called every time a new object is created.
-
-``editable``
-~~~~~~~~~~~~
-
-If ``False``, the field will not be editable in the admin or via forms
-automatically generated from the model class. Default is ``True``.
-
-``help_text``
-~~~~~~~~~~~~~
-
-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>."
-
-Alternatively you can use plain text and
-``django.utils.html.escape()`` to escape any HTML special characters.
-
-``primary_key``
-~~~~~~~~~~~~~~~
-
-If ``True``, this field is the primary key for the model.
-
-If you don't specify ``primary_key=True`` for any fields in your model,
-Django will automatically add this field::
-
-    id = models.AutoField('ID', primary_key=True)
-
-Thus, you don't need to set ``primary_key=True`` on any of your fields
-unless you want to override the default primary-key behavior.
-
-``primary_key=True`` implies ``null=False`` and ``unique=True``. Only
-one primary key is allowed on an object.
-
-``unique``
-~~~~~~~~~~
-
-If ``True``, this field must be unique throughout the table.
-
-This is enforced at the database level and at the Django admin-form level. If
-you try to save a model with a duplicate value in a ``unique`` field, a
-``django.db.IntegrityError`` will be raised by the model's ``save()`` method.
-
-``unique_for_date``
-~~~~~~~~~~~~~~~~~~~
-
-Set this to the name of a ``DateField`` or ``DateTimeField`` to require
-that this field be unique for the value of the date field.
-
-For example, if you have a field ``title`` that has
-``unique_for_date="pub_date"``, then Django wouldn't allow the entry of
-two records with the same ``title`` and ``pub_date``.
-
-This is enforced at the Django admin-form level but not at the database level.
-
-``unique_for_month``
-~~~~~~~~~~~~~~~~~~~~
-
-Like ``unique_for_date``, but requires the field to be unique with respect
-to the month.
-
-``unique_for_year``
-~~~~~~~~~~~~~~~~~~~
-
-Like ``unique_for_date`` and ``unique_for_month``.
-
-``validator_list``
-~~~~~~~~~~~~~~~~~~
-
-A list of extra validators to apply to the field. Each should be a callable
-that takes the parameters ``field_data, all_data`` and raises
-``django.core.validators.ValidationError`` for errors. (See the
-`validator docs`_.)
-
-Django comes with quite a few validators. They're in ``django.core.validators``.
-
-.. _validator docs: ../oldforms/#validators
-
-Verbose field names
--------------------
-
-Each field type, except for ``ForeignKey``, ``ManyToManyField`` and
-``OneToOneField``, takes an optional first positional argument -- a
-verbose name. If the verbose name isn't given, Django will automatically create
-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", max_length=30)
-
-In this example, the verbose name is ``"first name"``::
-
-    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::
-
-    poll = models.ForeignKey(Poll, verbose_name="the related poll")
-    sites = models.ManyToManyField(Site, verbose_name="list of sites")
-    place = models.OneToOneField(Place, verbose_name="related place")
-
-Convention is not to capitalize the first letter of the ``verbose_name``.
-Django will automatically capitalize the first letter where it needs to.
-
-Relationships
--------------
-
-Clearly, the power of relational databases lies in relating tables to each
-other. Django offers ways to define the three most common types of database
-relationships: Many-to-one, many-to-many and one-to-one.
-
-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
-related.
-
-For example, if a ``Car`` model has a ``Manufacturer`` -- that is, a
-``Manufacturer`` makes multiple cars but each ``Car`` only has one
-``Manufacturer`` -- use the following definitions::
-
-    class Manufacturer(models.Model):
-        # ...
-
-    class Car(models.Model):
-        manufacturer = models.ForeignKey(Manufacturer)
-        # ...
-
-To create a recursive relationship -- an object that has a many-to-one
-relationship with itself -- use ``models.ForeignKey('self')``.
-
-If you need to create a relationship on a model that has not yet been defined,
-you can use the name of the model, rather than the model object itself::
-
-    class Car(models.Model):
-        manufacturer = models.ForeignKey('Manufacturer')
-        # ...
-
-    class Manufacturer(models.Model):
-        # ...
-
-Note, however, that this only refers to models in the same models.py file -- you
-cannot use a string to reference a model defined in another application or
-imported from elsewhere.
-
-**New in Django development version:** To refer to models defined in another
-application, you must instead explicitly specify the application label. For
-example, if the ``Manufacturer`` model above is defined in another application
-called ``production``, you'd need to use::
-
-    class Car(models.Model):
-        manufacturer = models.ForeignKey('production.Manufacturer')
-
-Behind the scenes, Django appends ``"_id"`` to the field name to create its
-database column name. In the above example, the database table for the ``Car``
-model will have a ``manufacturer_id`` column. (You can change this explicitly
-by specifying ``db_column``; see ``db_column`` below.)  However, your code
-should never have to deal with the database column name, unless you write
-custom SQL. You'll always deal with the field names of your model object.
-
-It's suggested, but not required, that the name of a ``ForeignKey`` field
-(``manufacturer`` in the example above) be the name of the model, lowercase.
-You can, of course, call the field whatever you want. For example::
-
-    class Car(models.Model):
-        company_that_makes_it = models.ForeignKey(Manufacturer)
-        # ...
-
-See the `Many-to-one relationship model example`_ for a full example.
-
-.. _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:
-
-    =======================  ============================================================
-    Argument                 Description
-    =======================  ============================================================
-    ``limit_choices_to``     A dictionary of lookup arguments and values (see
-                             the `Database API reference`_) that limit the
-                             available admin choices for this object. Use this
-                             with functions from the Python ``datetime`` module
-                             to limit choices of objects by date. For example::
-
-                                limit_choices_to = {'pub_date__lte': datetime.now}
-
-                             only allows the choice of related objects with a
-                             ``pub_date`` before the current date/time to be
-                             chosen.
-
-                             Instead of a dictionary this can also be a ``Q`` object
-                             (an object with a ``get_sql()`` method) for more complex
-                             queries.
-
-                             ``limit_choices_to`` has no effect on the inline FormSets
-                             that are created to display related objects in the admin.
-
-    ``related_name``         The name to use for the relation from the related
-                             object back to this one. See the
-                             `related objects documentation`_ for a full
-                             explanation and example.
-
-                             If using this in an `abstract base class`_, be
-                             sure to read the `extra notes`_ in that section
-                             about ``related_name``.
-
-    ``to_field``             The field on the related object that the relation
-                             is to. By default, Django uses the primary key of
-                             the related object.
-    =======================  ============================================================
-
-.. _`Database API reference`: ../db-api/
-.. _related objects documentation: ../db-api/#related-objects
-.. _abstract base class: `Abstract base classes`_
-.. _extra notes: `Be careful with related_name`_
-
-Many-to-many relationships
-~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-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
-model is related.
-
-For example, if a ``Pizza`` has multiple ``Topping`` objects -- that is, a
-``Topping`` can be on multiple pizzas and each ``Pizza`` has multiple toppings --
-here's how you'd represent that::
-
-    class Topping(models.Model):
-        # ...
-
-    class Pizza(models.Model):
-        # ...
-        toppings = models.ManyToManyField(Topping)
-
-As with ``ForeignKey``, a relationship to self can be defined by using the
-string ``'self'`` instead of the model name, and you can refer to as-yet
-undefined models by using a string containing the model name. However, you
-can only use strings to refer to models in the same models.py file -- you
-cannot use a string to reference a model in a different application, or to
-reference a model that has been imported from elsewhere.
-
-It's suggested, but not required, that the name of a ``ManyToManyField``
-(``toppings`` in the example above) be a plural describing the set of related
-model objects.
-
-Behind the scenes, Django creates an intermediary join table to represent the
-many-to-many relationship.
-
-It doesn't matter which model gets the ``ManyToManyField``, but you only need
-it in one of the models -- not in both.
-
-Generally, ``ManyToManyField`` instances should go in the object that's going
-to be edited in the admin interface, if you're using Django's admin. In the
-above example, ``toppings`` is in ``Pizza`` (rather than ``Topping`` having a
-``pizzas`` ``ManyToManyField`` ) because it's more natural to think about a
-``Pizza`` having toppings than a topping being on multiple pizzas. The way it's
-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: ../models/many_to_many/
-
-``ManyToManyField`` objects take a number of extra arguments for defining how
-the relationship should work. All are optional:
-
-    =======================  ============================================================
-    Argument                 Description
-    =======================  ============================================================
-    ``related_name``         See the description under ``ForeignKey`` above.
-
-    ``limit_choices_to``     See the description under ``ForeignKey`` above.
-    
-                             ``limit_choices_to`` has no effect when used on a
-                             ``ManyToManyField`` with an intermediate table.
-
-    ``symmetrical``          Only used in the definition of ManyToManyFields on self.
-                             Consider the following model::
-
-                                 class Person(models.Model):
-                                     friends = models.ManyToManyField("self")
-
-                             When Django processes this model, it identifies that it has
-                             a ``ManyToManyField`` on itself, and as a result, it
-                             doesn't add a ``person_set`` attribute to the ``Person``
-                             class. Instead, the ``ManyToManyField`` is assumed to be
-                             symmetrical -- that is, if I am your friend, then you are
-                             my friend.
-
-                             If you do not want symmetry in ``ManyToMany`` relationships
-                             with ``self``, set ``symmetrical`` to ``False``. This will
-                             force Django to add the descriptor for the reverse
-                             relationship, allowing ``ManyToMany`` relationships to be
-                             non-symmetrical.
-
-    ``db_table``             The name of the table to create for storing the many-to-many
-                             data. If this is not provided, Django will assume a default
-                             name based upon the names of the two tables being joined.
-
-    =======================  ============================================================
-
-Extra fields on many-to-many relationships
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-**New in Django development version**
-
-When you're only dealing with simple many-to-many relationships such as
-mixing and matching pizzas and toppings, a standard ``ManyToManyField``
-is all you need. However, sometimes you may need to associate data with the
-relationship between two models.
-
-For example, consider the case of an application tracking the musical groups
-which musicians belong to. There is a many-to-many relationship between a person
-and the groups of which they are a member, so you could use a ManyToManyField
-to represent this relationship. However, there is a lot of detail about the
-membership that you might want to collect, such as the date at which the person
-joined the group.
-
-For these situations, Django allows you to specify the model that will be used
-to govern the many-to-many relationship. You can then put extra fields on the
-intermediate model. The intermediate model is associated with the
-``ManyToManyField`` using the ``through`` argument to point to the model
-that will act as an intermediary. For our musician example, the code would look
-something like this::
-
-    class Person(models.Model):
-        name = models.CharField(max_length=128)
-
-        def __unicode__(self):
-            return self.name
-
-    class Group(models.Model):
-        name = models.CharField(max_length=128)
-        members = models.ManyToManyField(Person, through='Membership')
-
-        def __unicode__(self):
-            return self.name
-
-    class Membership(models.Model):
-        person = models.ForeignKey(Person)
-        group = models.ForeignKey(Group)
-        date_joined = models.DateField()
-        invite_reason = models.CharField(max_length=64)
-
-When you set up the intermediary model, you explicitly specify foreign
-keys to the models that are involved in the ManyToMany relation. This
-explicit declaration defines how the two models are related.
-
-There are a few restrictions on the intermediate model:
-
-    * Your intermediate model must contain one - and *only* one - foreign key
-      on the target model (this would be ``Person`` in our example). If you
-      have more than one foreign key, a validation error will be raised.
-
-    * Your intermediate model must contain one - and *only* one - foreign key
-      on the source model (this would be ``Group`` in our example). If you
-      have more than one foreign key, a validation error will be raised.
-
-    * The only exception to this is a model which has a many-to-many
-      relationship to itself, through an intermediary model. In this
-      case, two foreign keys to the same model are permitted, but they
-      will be treated as the two (different) sides of the many-to-many
-      relation.
-
-    * When defining a many-to-many relationship from a model to
-      itself, using an intermediary model, you *must* use
-      ``symmetrical=False`` (see the documentation for
-      ``ManyToManyField`` above).
-
-Now that you have set up your ``ManyToManyField`` to use your intermediary
-model (Membership, in this case), you're ready to start creating some
-many-to-many relationships. You do this by creating instances of the
-intermediate model::
-
-    >>> ringo = Person.objects.create(name="Ringo Starr")
-    >>> paul = Person.objects.create(name="Paul McCartney")
-    >>> beatles = Group.objects.create(name="The Beatles")
-    >>> m1 = Membership(person=ringo, group=beatles,
-    ...     date_joined=date(1962, 8, 16),
-    ...     invite_reason= "Needed a new drummer.")
-    >>> m1.save()
-    >>> beatles.members.all()
-    [<Person: Ringo Starr>]
-    >>> ringo.group_set.all()
-    [<Group: The Beatles>]
-    >>> m2 = Membership.objects.create(person=paul, group=beatles,
-    ...     date_joined=date(1960, 8, 1),
-    ...     invite_reason= "Wanted to form a band.")
-    >>> beatles.members.all()
-    [<Person: Ringo Starr>, <Person: Paul McCartney>]
-
-Unlike normal many-to-many fields, you *can't* use ``add``, ``create``,
-or assignment (i.e., ``beatles.members = [...]``) to create relationships::
-
-    # THIS WILL NOT WORK
-    >>> beatles.members.add(john)
-    # NEITHER WILL THIS
-    >>> beatles.members.create(name="George Harrison")
-    # AND NEITHER WILL THIS
-    >>> beatles.members = [john, paul, ringo, george]
-
-Why? You can't just create a relationship between a Person and a Group - you
-need to specify all the detail for the relationship required by the
-Membership table. The simple ``add``, ``create`` and assignment calls
-don't provide a way to specify this extra detail. As a result, they are
-disabled for many-to-many relationships that use an intermediate model.
-The only way to create a many-to-many relationship with an intermediate table
-is to create instances of the intermediate model.
-
-The ``remove`` method is disabled for similar reasons. However, the
-``clear()`` method can be used to remove all many-to-many relationships
-for an instance::
-
-    # Beatles have broken up
-    >>> beatles.members.clear()
-
-Once you have established the many-to-many relationships by creating instances
-of your intermediate model, you can issue queries. Just as with normal
-many-to-many relationships, you can query using the attributes of the
-many-to-many-related model::
-
-    # Find all the groups with a member whose name starts with 'Paul'
-    >>> Groups.objects.filter(person__name__startswith='Paul')
-    [<Group: The Beatles>]
-
-As you are using an intermediate table, you can also query on the attributes
-of the intermediate model::
-
-    # Find all the members of the Beatles that joined after 1 Jan 1961
-    >>> Person.objects.filter(
-    ...     group__name='The Beatles',
-    ...     membership__date_joined__gt=date(1961,1,1))
-    [<Person: Ringo Starr]
-
-One-to-one relationships
-~~~~~~~~~~~~~~~~~~~~~~~~
-
-To define a one-to-one relationship, use ``OneToOneField``. You use it just
-like any other ``Field`` type: by including it as a class attribute of your
-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
-model is related.
-
-For example, if you're building a database of "places", you would build pretty
-standard stuff such as address, phone number, etc. in the database. Then, if you
-wanted to build a database of restaurants on top of the places, instead of
-repeating yourself and replicating those fields in the ``Restaurant`` model, you
-could make ``Restaurant`` have a ``OneToOneField`` to ``Place`` (because a
-restaurant "is-a" place).
-
-As with ``ForeignKey``, a relationship to self can be defined by using the
-string ``"self"`` instead of the model name; references to as-yet undefined
-models can be made by using a string containing the model name.
-
-Finally, ``OneToOneField`` takes the following extra option:
-
-    =======================  ============================================================
-    Argument                 Description
-    =======================  ============================================================
-    ``parent_link``          When ``True`` and used in a model inherited from
-                             another model, indicates that this field should
-                             be used as the link from the child back to the
-                             parent. See `Model inheritance`_ for more
-                             details.
-
-                             **New in Django development version**
-
-    =======================  ============================================================
-
-**New in Django development version:** ``OneToOneField`` classes used to
-automatically become the primary key on a model. This is no longer true,
-although you can manually pass in the ``primary_key`` attribute if you like.
-Thus, it's now possible to have multiple fields of type ``OneToOneField`` on a
-single model.
-
-See the `One-to-one relationship model example`_ for a full example.
-
-.. _One-to-one relationship model example: ../models/one_to_one/
-
-Custom field types
-------------------
-
-**New in Django development version**
-
-If one of the existing model fields cannot be used to fit your purposes, or if
-you wish to take advantage of some less common database column types, you can
-create your own field class. Full coverage of creating your own fields is
-provided in the `Custom Model Fields`_ documentation.
-
-.. _Custom Model Fields: ../custom_model_fields/
-
-Meta options
-============
-
-Give your model metadata by using an inner ``class Meta``, like so::
-
-    class Foo(models.Model):
-        bar = models.CharField(max_length=30)
-
-        class Meta:
-            # ...
-
-Model metadata is "anything that's not a field", such as ordering options, etc.
-
-Here's a list of all possible ``Meta`` options. No options are required. Adding
-``class Meta`` to a model is completely optional.
-
-``abstract``
-------------
-
-**New in Django development version**
-
-When set to ``True``, denotes this model as an abstract base class. See
-`Abstract base classes`_ for more details. Defaults to ``False``.
-
-``db_table``
-------------
-
-The name of the database table to use for the model::
-
-    db_table = 'music_album'
-
-If this isn't given, Django will use ``app_label + '_' + model_class_name``.
-See "Table names" below for more.
-
-If your database table name is an SQL reserved word, or contains characters
-that aren't allowed in Python variable names -- notably, the hyphen --
-that's OK. Django quotes column and table names behind the scenes.
-
-``db_tablespace``
------------------
-
-**New in Django development version**
-
-The name of the database tablespace to use for the model. If the backend
-doesn't support tablespaces, this option is ignored.
-
-``get_latest_by``
------------------
-
-The name of a ``DateField`` or ``DateTimeField`` in the model. This specifies
-the default field to use in your model ``Manager``'s ``latest()`` method.
-
-Example::
-
-    get_latest_by = "order_date"
-
-See the `docs for latest()`_ for more.
-
-.. _docs for latest(): ../db-api/#latest-field-name-none
-
-``order_with_respect_to``
--------------------------
-
-Marks this object as "orderable" with respect to the given field. This is
-almost always used with related objects to allow them to be ordered with
-respect to a parent object. For example, if an ``Answer`` relates to a
-``Question`` object, and a question has more than one answer, and the order
-of answers matters, you'd do this::
-
-    class Answer(models.Model):
-        question = models.ForeignKey(Question)
-        # ...
-
-        class Meta:
-            order_with_respect_to = 'question'
-
-``ordering``
-------------
-
-The default ordering for the object, for use when obtaining lists of objects::
-
-    ordering = ['-order_date']
-
-This is a tuple or list of strings. Each string is a field name with an
-optional "-" prefix, which indicates descending order. Fields without a
-leading "-" will be ordered ascending. Use the string "?" to order randomly.
-
-For example, to order by a ``pub_date`` field ascending, use this::
-
-    ordering = ['pub_date']
-
-To order by ``pub_date`` descending, use this::
-
-    ordering = ['-pub_date']
-
-To order by ``pub_date`` descending, then by ``author`` ascending, use this::
-
-    ordering = ['-pub_date', 'author']
-
-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: ../models/ordering/
-
-``permissions``
----------------
-
-Extra permissions to enter into the permissions table when creating this
-object. Add, delete and change permissions are automatically created for
-each object that has ``admin`` set. This example specifies an extra
-permission, ``can_deliver_pizzas``::
-
-    permissions = (("can_deliver_pizzas", "Can deliver pizzas"),)
-
-This is a list or tuple of 2-tuples in the format
-``(permission_code, human_readable_permission_name)``.
-
-``unique_together``
--------------------
-
-Sets of field names that, taken together, must be unique::
-
-    unique_together = (("driver", "restaurant"),)
-
-This is a list of lists of fields that must be unique when considered
-together. It's used in the Django admin and is enforced at the database
-level (i.e., the appropriate ``UNIQUE`` statements are included in the
-``CREATE TABLE`` statement).
-
-All the fields specified in ``unique_together`` must be part of the current
-model. If you are using `model inheritance`_, you cannot refer to fields from
-any parent classes in ``unique_together``.
-
-**New in Django development version**
-
-For convenience, unique_together can be a single list when dealing
-with a single set of fields::
-
-    unique_together = ("driver", "restaurant")
-
-``verbose_name``
-----------------
-
-A human-readable name for the object, singular::
-
-    verbose_name = "pizza"
-
-If this isn't given, Django will use a munged version of the class name:
-``CamelCase`` becomes ``camel case``.
-
-``verbose_name_plural``
------------------------
-
-The plural name for the object::
-
-    verbose_name_plural = "stories"
-
-If this isn't given, Django will use ``verbose_name + "s"``.
-
-Table names
-===========
-
-To save you time, Django automatically derives the name of the database table
-from the name of your model class and the app that contains it. A model's
-database table name is constructed by joining the model's "app label" -- the
-name you used in ``manage.py startapp`` -- to the model's class name, with an
-underscore between them.
-
-For example, if you have an app ``bookstore`` (as created by
-``manage.py startapp bookstore``), a model defined as ``class Book`` will have
-a database table named ``bookstore_book``.
-
-To override the database table name, use the ``db_table`` parameter in
-``class Meta``.
-
-Automatic primary key fields
-============================
-
-By default, Django gives each model the following field::
-
-    id = models.AutoField(primary_key=True)
-
-This is an auto-incrementing primary key.
-
-If you'd like to specify a custom primary key, just specify ``primary_key=True``
-on one of your fields. If Django sees you've explicitly set ``primary_key``, it
-won't add the automatic ``id`` column.
-
-Each model requires exactly one field to have ``primary_key=True``.
-
-The ``pk`` property
--------------------
-**New in Django development version**
-
-Regardless of whether you define a primary key field yourself, or let Django
-supply one for you, each model will have a property called ``pk``. It behaves
-like a normal attribute on the model, but is actually an alias for whichever
-attribute is the primary key field for the model. You can read and set this
-value, just as you would for any other attribute, and it will update the
-correct field in the model.
-
-Managers
-========
-
-A ``Manager`` is the interface through which database query operations are
-provided to Django models. At least one ``Manager`` exists for every model in
-a Django application.
-
-The way ``Manager`` classes work is documented in the `Retrieving objects`_
-section of the database API docs, but this section specifically touches on
-model options that customize ``Manager`` behavior.
-
-.. _Retrieving objects: ../db-api/#retrieving-objects
-
-Manager names
--------------
-
-By default, Django adds a ``Manager`` with the name ``objects`` to every Django
-model class. However, if you want to use ``objects`` as a field name, or if you
-want to use a name other than ``objects`` for the ``Manager``, you can rename
-it on a per-model basis. To rename the ``Manager`` for a given class, define a
-class attribute of type ``models.Manager()`` on that model. For example::
-
-    from django.db import models
-
-    class Person(models.Model):
-        #...
-        people = models.Manager()
-
-Using this example model, ``Person.objects`` will generate an
-``AttributeError`` exception, but ``Person.people.all()`` will provide a list
-of all ``Person`` objects.
-
-Custom Managers
----------------
-
-You can use a custom ``Manager`` in a particular model by extending the base
-``Manager`` class and instantiating your custom ``Manager`` in your model.
-
-There are two reasons you might want to customize a ``Manager``: to add extra
-``Manager`` methods, and/or to modify the initial ``QuerySet`` the ``Manager``
-returns.
-
-Adding extra Manager methods
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Adding extra ``Manager`` methods is the preferred way to add "table-level"
-functionality to your models. (For "row-level" functionality -- i.e., functions
-that act on a single instance of a model object -- use `Model methods`_, not
-custom ``Manager`` methods.)
-
-A custom ``Manager`` method can return anything you want. It doesn't have to
-return a ``QuerySet``.
-
-For example, this custom ``Manager`` offers a method ``with_counts()``, which
-returns a list of all ``OpinionPoll`` objects, each with an extra
-``num_responses`` attribute that is the result of an aggregate query::
-
-    class PollManager(models.Manager):
-        def with_counts(self):
-            from django.db import connection
-            cursor = connection.cursor()
-            cursor.execute("""
-                SELECT p.id, p.question, p.poll_date, COUNT(*)
-                FROM polls_opinionpoll p, polls_response r
-                WHERE p.id = r.poll_id
-                GROUP BY 1, 2, 3
-                ORDER BY 3 DESC""")
-            result_list = []
-            for row in cursor.fetchall():
-                p = self.model(id=row[0], question=row[1], poll_date=row[2])
-                p.num_responses = row[3]
-                result_list.append(p)
-            return result_list
-
-    class OpinionPoll(models.Model):
-        question = models.CharField(max_length=200)
-        poll_date = models.DateField()
-        objects = PollManager()
-
-    class Response(models.Model):
-        poll = models.ForeignKey(Poll)
-        person_name = models.CharField(max_length=50)
-        response = models.TextField()
-
-With this example, you'd use ``OpinionPoll.objects.with_counts()`` to return
-that list of ``OpinionPoll`` objects with ``num_responses`` attributes.
-
-Another thing to note about this example is that ``Manager`` methods can
-access ``self.model`` to get the model class to which they're attached.
-
-Modifying initial Manager QuerySets
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-A ``Manager``'s base ``QuerySet`` returns all objects in the system. For
-example, using this model::
-
-    class Book(models.Model):
-        title = models.CharField(max_length=100)
-        author = models.CharField(max_length=50)
-
-...the statement ``Book.objects.all()`` will return all books in the database.
-
-You can override a ``Manager``\'s base ``QuerySet`` by overriding the
-``Manager.get_query_set()`` method. ``get_query_set()`` should return a
-``QuerySet`` with the properties you require.
-
-For example, the following model has *two* ``Manager``\s -- one that returns
-all objects, and one that returns only the books by Roald Dahl::
-
-    # First, define the Manager subclass.
-    class DahlBookManager(models.Manager):
-        def get_query_set(self):
-            return super(DahlBookManager, self).get_query_set().filter(author='Roald Dahl')
-
-    # Then hook it into the Book model explicitly.
-    class Book(models.Model):
-        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.
-
-With this sample model, ``Book.objects.all()`` will return all books in the
-database, but ``Book.dahl_objects.all()`` will only return the ones written by
-Roald Dahl.
-
-Of course, because ``get_query_set()`` returns a ``QuerySet`` object, you can
-use ``filter()``, ``exclude()`` and all the other ``QuerySet`` methods on it.
-So these statements are all legal::
-
-    Book.dahl_objects.all()
-    Book.dahl_objects.filter(title='Matilda')
-    Book.dahl_objects.count()
-
-This example also pointed out another interesting technique: using multiple
-managers on the same model. You can attach as many ``Manager()`` instances to
-a model as you'd like. This is an easy way to define common "filters" for your
-models.
-
-For example::
-
-    class MaleManager(models.Manager):
-        def get_query_set(self):
-            return super(MaleManager, self).get_query_set().filter(sex='M')
-
-    class FemaleManager(models.Manager):
-        def get_query_set(self):
-            return super(FemaleManager, self).get_query_set().filter(sex='F')
-
-    class Person(models.Model):
-        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()
-
-This example allows you to request ``Person.men.all()``, ``Person.women.all()``,
-and ``Person.people.all()``, yielding predictable results.
-
-If you use custom ``Manager`` objects, take note that the first
-``Manager`` Django encounters (in the order in which they're defined
-in the model) has a special status. Django interprets this first
-``Manager`` defined in a class as the "default" ``Manager``, and
-several parts of Django (though not the admin application) will use
-that ``Manager`` exclusively for that model. As a result, it's often a
-good idea to be careful in your choice of default manager, in order to
-avoid a situation where overriding of ``get_query_set()`` results in
-an inability to retrieve objects you'd like to work with.
-
-Using managers for related object access
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-By default, Django uses a "bare" (i.e. default) manager when accessing related
-objects (i.e. ``choice.poll``). If this default isn't appropriate for your
-default manager, you can force Django to use a custom manager for related object
-attributes by giving it a ``use_for_related_fields`` property::
-
-    class MyManager(models.Manager)::
-        use_for_related_fields = True
-
-        ...
-
-Model methods
-=============
-
-Define custom methods on a model to add custom "row-level" functionality to
-your objects. Whereas ``Manager`` methods are intended to do "table-wide"
-things, model methods should act on a particular model instance.
-
-This is a valuable technique for keeping business logic in one place -- the
-model.
-
-For example, this model has a few custom methods::
-
-    class Person(models.Model):
-        first_name = models.CharField(max_length=50)
-        last_name = models.CharField(max_length=50)
-        birth_date = models.DateField()
-        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):
-            "Returns the person's baby-boomer status."
-            import datetime
-            if datetime.date(1945, 8, 1) <= self.birth_date <= datetime.date(1964, 12, 31):
-                return "Baby boomer"
-            if self.birth_date < datetime.date(1945, 8, 1):
-                return "Pre-boomer"
-            return "Post-boomer"
-
-        def is_midwestern(self):
-            "Returns True if this person is from the Midwest."
-            return self.state in ('IL', 'WI', 'MI', 'IN', 'OH', 'IA', 'MO')
-
-        def _get_full_name(self):
-            "Returns the person's full name."
-            return '%s %s' % (self.first_name, self.last_name)
-        full_name = property(_get_full_name)
-
-The last method in this example is a *property*. `Read more about properties`_.
-
-.. _Read more about properties: http://www.python.org/download/releases/2.2/descrintro/#property
-
-A few object methods have special meaning:
-
-``__str__``
------------
-
-``__str__()`` is a Python "magic method" that defines what should be returned
-if you call ``str()`` on the object. Django uses ``str(obj)`` (or the related
-function, ``unicode(obj)`` -- see below) in a number of places, most notably
-as the value displayed to render an object in the Django admin site and as the
-value inserted into a template when it displays an object. Thus, you should
-always return a nice, human-readable string for the object's ``__str__``.
-Although this isn't required, it's strongly encouraged (see the description of
-``__unicode__``, below, before putting ``__str__`` methods everywhere).
-
-For example::
-
-    class Person(models.Model):
-        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
-            # first_name and last_name will be unicode strings.
-            return smart_str('%s %s' % (self.first_name, self.last_name))
-
-``__unicode__``
----------------
-
-The ``__unicode__()`` method is called whenever you call ``unicode()`` on an
-object. Since Django's database backends will return Unicode strings in your
-model's attributes, you would normally want to write a ``__unicode__()``
-method for your model. The example in the previous section could be written
-more simply as::
-
-    class Person(models.Model):
-        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)
-
-If you define a ``__unicode__()`` method on your model and not a ``__str__()``
-method, Django will automatically provide you with a ``__str__()`` that calls
-``__unicode__()`` and then converts the result correctly to a UTF-8 encoded
-string object. This is recommended development practice: define only
-``__unicode__()`` and let Django take care of the conversion to string objects
-when required.
-
-``get_absolute_url``
---------------------
-
-Define a ``get_absolute_url()`` method to tell Django how to calculate the
-URL for an object. For example::
-
-    def get_absolute_url(self):
-        return "/people/%i/" % self.id
-
-Django uses this in its admin interface. If an object defines
-``get_absolute_url()``, the object-editing page will have a "View on site"
-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`_,
-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::
-
-    <a href="/people/{{ object.id }}/">{{ object.name }}</a>
-
-But this template code is good::
-
-    <a href="{{ object.get_absolute_url }}">{{ object.name }}</a>
-
-.. note::
-    The string you return from ``get_absolute_url()`` must contain only ASCII
-    characters (required by the URI spec, `RFC 2396`_) that have been
-    URL-encoded, if necessary. Code and templates using ``get_absolute_url()``
-    should be able to use the result directly without needing to do any
-    further processing. You may wish to use the
-    ``django.utils.encoding.iri_to_uri()`` function to help with this if you
-    are using unicode strings a lot.
-
-.. _RFC 2396: http://www.ietf.org/rfc/rfc2396.txt
-
-The ``permalink`` decorator
-~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The problem with the way we wrote ``get_absolute_url()`` above is that it
-slightly violates the DRY principle: the URL for this object is defined both
-in the URLConf file and in the model.
-
-You can further decouple your models from the URLconf using the ``permalink``
-decorator. This decorator is passed the view function, a list of positional
-parameters and (optionally) a dictionary of named parameters. Django then
-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'),
-
-...your model could have a ``get_absolute_url`` method that looked like this::
-
-    from django.db.models import permalink
-
-    def get_absolute_url(self):
-        return ('people.views.details', [str(self.id)])
-    get_absolute_url = permalink(get_absolute_url)
-
-Similarly, if you had a URLconf entry that looked like::
-
-    (r'/archive/(?P<year>\d{4})/(?P<month>\d{1,2})/(?P<day>\d{1,2})/$', archive_view)
-
-...you could reference this using ``permalink()`` as follows::
-
-    def get_absolute_url(self):
-        return ('archive_view', (), {
-            'year': self.created.year,
-            'month': self.created.month,
-            'day': self.created.day})
-    get_absolute_url = permalink(get_absolute_url)
-
-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
-use the ``get_absolute_url`` method in templates, as before.
-
-In some cases, such as the use of generic views or the re-use of
-custom views for multiple models, specifying the view function may
-confuse the reverse URL matcher (because multiple patterns point to
-the same view).
-
-For that problem, Django has **named URL patterns**. Using a named
-URL pattern, it's possible to give a name to a pattern, and then
-reference the name rather than the view function. A named URL
-pattern is defined by replacing the pattern tuple by a call to
-the ``url`` function)::
-
-    from django.conf.urls.defaults import *
-
-    url(r'^people/(\d+)/$',
-        'django.views.generic.list_detail.object_detail',
-        name='people_view'),
-
-...and then using that name to perform the reverse URL resolution instead
-of the view name::
-
-    from django.db.models import permalink
-
-    def get_absolute_url(self):
-        return ('people_view', [str(self.id)])
-    get_absolute_url = permalink(get_absolute_url)
-
-More details on named URL patterns are in the `URL dispatch documentation`_.
-
-.. _URL dispatch documentation: ../url_dispatch/#naming-url-patterns
-
-Executing custom SQL
---------------------
-
-Feel free to write custom SQL statements in custom model methods and
-module-level methods. The object ``django.db.connection`` represents the
-current database connection. To use it, call ``connection.cursor()`` to get a
-cursor object. Then, call ``cursor.execute(sql, [params])`` to execute the SQL
-and ``cursor.fetchone()`` or ``cursor.fetchall()`` to return the resulting
-rows. Example::
-
-    def my_custom_sql(self):
-        from django.db import connection
-        cursor = connection.cursor()
-        cursor.execute("SELECT foo FROM bar WHERE baz = %s", [self.baz])
-        row = cursor.fetchone()
-        return row
-
-``connection`` and ``cursor`` mostly implement the standard `Python DB-API`_
-(except when it comes to `transaction handling`_). If you're not familiar with
-the Python DB-API, note that the SQL statement in ``cursor.execute()`` uses
-placeholders, ``"%s"``, rather than adding parameters directly within the SQL.
-If you use this technique, the underlying database library will automatically
-add quotes and escaping to your parameter(s) as necessary. (Also note that
-Django expects the ``"%s"`` placeholder, *not* the ``"?"`` placeholder, which is
-used by the SQLite Python bindings. This is for the sake of consistency and
-sanity.)
-
-A final note: If all you want to do is a custom ``WHERE`` clause, you can just
-use the ``where``, ``tables`` and ``params`` arguments to the standard lookup
-API. See `Other lookup options`_.
-
-.. _Python DB-API: http://www.python.org/peps/pep-0249.html
-.. _Other lookup options: ../db-api/#extra-select-none-where-none-params-none-tables-none
-.. _transaction handling: ../transactions/
-
-Overriding default model methods
---------------------------------
-
-As explained in the `database API docs`_, each model gets a few methods
-automatically -- most notably, ``save()`` and ``delete()``. You can override
-these methods to alter behavior.
-
-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(max_length=100)
-        tagline = models.TextField()
-
-        def save(self):
-            do_something()
-            super(Blog, self).save() # Call the "real" save() method.
-            do_something_else()
-
-You can also prevent saving::
-
-    class Blog(models.Model):
-        name = models.CharField(max_length=100)
-        tagline = models.TextField()
-
-        def save(self):
-            if self.name == "Yoko Ono's blog":
-                return # Yoko shall never have her own blog!
-            else:
-                super(Blog, self).save() # Call the "real" save() method.
-
-.. _database API docs: ../db-api/
-
-Model inheritance
-=================
-
-**New in Django development version**
-
-Model inheritance in Django works almost identically to the way normal class
-inheritance works in Python. The only decision you have to make is whether you
-want the parent models to be models in their own right (with their own
-database tables), or if the parents are just holders of common information
-that will only be visible through the child models.
-
-Often, you will just want to use the parent class to hold information that you
-don't want to have to type out for each child model. This class isn't going to
-ever be used in isolation, so `abstract base classes`_ are what you're after. However, if you're subclassing an existing model (perhaps something from another application entirely), or want each model to have its own database table, `multi-table inheritance`_ is the way to go.
-
-Abstract base classes
----------------------
-
-Abstract base classes are useful when you want to put some common information
-into a number of other models. You write your base class and put
-``abstract=True`` in the ``Meta`` class. This model will then not be used to
-create any database table. Instead, when it is used as a base class for other
-models, its fields will be added to those of the child class. It is an error
-to have fields in the abstract base class with the same name as those in the
-child (and Django will raise an exception).
-
-An example::
-
-    class CommonInfo(models.Model):
-        name = models.CharField(max_length=100)
-        age = models.PositiveIntegerField()
-
-        class Meta:
-            abstract = True
-
-    class Student(CommonInfo):
-        home_group = models.CharField(max_length=5)
-
-The ``Student`` model will have three fields: ``name``, ``age`` and
-``home_group``. The ``CommonInfo`` model cannot be used as a normal Django
-model, since it is an abstract base class. It does not generate a database
-table or have a manager or anything like that.
-
-For many uses, this type of model inheritance will be exactly what you want.
-It provides a way to factor out common information at the Python level, whilst
-still only creating one database table per child model at the database level.
-
-``Meta`` inheritance
-~~~~~~~~~~~~~~~~~~~~
-
-When an abstract base class is created, Django makes any ``Meta`` inner class
-you declared on the base class available as an attribute. If a child class
-does not declare its own ``Meta`` class, it will inherit the parent's
-``Meta``. If the child wants to extend the parent's ``Meta`` class, it can
-subclass it. For example::
-
-    class CommonInfo(models.Model):
-        ...
-        class Meta:
-            abstract = True
-            ordering = ['name']
-
-    class Student(CommonInfo):
-        ...
-        class Meta(CommonInfo.Meta):
-            db_table = 'student_info'
-
-Django does make one adjustment to the ``Meta`` class of an abstract base
-class: before installing the ``Meta`` attribute, it sets ``abstract=False``.
-This means that children of abstract base classes don't automatically become
-abstract classes themselves. Of course, you can make an abstract base class
-that inherits from another abstract base class. You just need to remember to
-explicitly set ``abstract=True`` each time.
-
-Some attributes won't make sense to include in the ``Meta`` class of an
-abstract base class. For example, including ``db_table`` would mean that all
-the child classes (the ones that don't specify their own ``Meta``) would use
-the same database table, which is almost certainly not what you want.
-
-Be careful with ``related_name``
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-If you are using the ``related_name`` attribute on a ``ForeignKey`` or
-``ManyToManyField``, you must always specify a *unique* reverse name for the
-field. This would normally cause a problem in abstract base classes, since the
-fields on this class are included into each of the child classes, with exactly
-the same values for the attributes (including ``related_name``) each time.
-
-To work around this problem, when you are using ``related_name`` in an
-abstract base class (only), part of the name should be the string
-``'%(class)s'``. This is replaced by the lower-cased name of the child class
-that the field is used in. Since each class has a different name, each related
-name will end up being different. For example::
-
-    class Base(models.Model):
-        m2m = models.ManyToMany(OtherModel, related_name="%(class)s_related")
-
-        class Meta:
-            abstract = True
-
-    class ChildA(Base):
-        pass
-
-    class ChildB(Base):
-        pass
-
-The reverse name of the ``ChildA.m2m`` field will be ``childa_related``,
-whilst the reverse name of the ``ChildB.m2m`` field will be
-``childb_related``. It is up to you how you use the ``'%(class)s'`` portion to
-construct your related name, but if you forget to use it, Django will raise
-errors when you validate your models (or run ``syncdb``).
-
-If you don't specify a ``related_name`` attribute for a field in an abstract
-base class, the default reverse name will be the name of the child class
-followed by ``'_set'``, just as it normally would be if you'd declared the field directly on the child class. For example, in the above code, if the ``related_name`` attribute was omitted, the reverse name for the ``m2m`` field would be ``childa_set`` in the ``ChildA`` case and ``childb_set`` for the ``ChildB`` field.
-
-Multi-table inheritance
------------------------
-
-The second type of model inheritance supported by Django is when each model in
-the hierarchy is a model all by itself. Each model corresponds to its own
-database table and can be queried and created individually. The inheritance
-relationship introduces links between the child model and each of its parents
-(via an automatically created ``OneToOneField``). For example::
-
-    class Place(models.Model):
-        name = models.CharField(max_length=50)
-        address = models.CharField(max_length=80)
-
-    class Restaurant(Place):
-        serves_hot_dogs = models.BooleanField()
-        serves_pizza = models.BooleanField()
-
-All of the fields of ``Place`` will also be available in ``Restaurant``,
-although the data will reside in a different database table. So these are both
-possible::
-
-    >>> Place.objects.filter(name="Bob's Cafe")
-    >>> Restaurant.objects.filter(name="Bob's Cafe")
-
-If you have a ``Place`` that is also a ``Restaurant``, you can get from the
-``Place`` object to the ``Restaurant`` object by using the lower-case version
-of the model name::
-
-    >>> p = Place.objects.filter(name="Bob's Cafe")
-    # If Bob's Cafe is a Restaurant object, this will give the child class:
-    >>> p.restaurant
-    <Restaurant: ...>
-
-However, if ``p`` in the above example was *not* a ``Restaurant`` (it had been
-created directly as a ``Place`` object or was the parent of some other class),
-referring to ``p.restaurant`` would give an error.
-
-``Meta`` and multi-table inheritance
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-In the multi-table inheritance situation, it doesn't make sense for a child
-class to inherit from its parent's ``Meta`` class. All the ``Meta`` options
-have already been applied to the parent class and applying them again would
-normally only lead to contradictory behaviour (this is in contrast with the
-abstract base class case, where the base class doesn't exist in its own
-right).
-
-So a child model does not have access to its parent's ``Meta`` class. However,
-there are a few limited cases where the child inherits behaviour from the
-parent: if the child does not specify an ``ordering`` attribute or a
-``get_latest_by`` attribute, it will inherit these from its parent.
-
-If the parent has an ordering and you don't want the child to have any natural
-ordering, you can explicitly set it to be empty::
-
-    class ChildModel(ParentModel):
-        ...
-        class Meta:
-            # Remove parent's ordering effect
-            ordering = []
-
-Inheritance and reverse relations
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Because multi-table inheritance uses an implicit ``OneToOneField`` to link the
-child and the parent, it's possible to move from the parent down to the child,
-as in the above example. However, this uses up the name that is the default
-``related_name`` value for ``ForeignKey`` and ``ManyToManyField`` relations.
-If you are putting those type of relations on a subclass of another model, you
-**must** specify the ``related_name`` attribute on each such field. If you
-forget, Django will raise an error when you run ``manage.py validate`` or try
-to syncdb.
-
-For example, using the above ``Place`` class again, let's create another
-subclass with a ``ManyToManyField``::
-
-    class Supplier(Place):
-        # Must specify related_name on all relations.
-        customers = models.ManyToManyField(Restaurant,
-                related_name='provider')
-
-For more information about reverse relations, refer to the `Database API
-reference`_ . For now, just remember to run ``manage.py validate`` when
-you're writing your models and pay attention to the error messages.
-
-Specifying the parent link field
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-As mentioned, Django will automatically create a ``OneToOneField`` linking
-your child class back any non-abstract parent models. If you want to control
-the name of the attribute linking back to the parent, you can create your own
-link field and pass it ``parent_link=True``. For example, to explicitly
-specify the field that will link ``Supplier`` to ``Place`` in the above
-example, you could write::
-
-    class Supplier(Place):
-        parent = models.OneToOneField(Place, parent_link=True)
-        ...
-
-Multiple inheritance
---------------------
-
-Just as with Python's subclassing, it's possible for a Django model to inherit
-from multiple parent models. Keep in mind that normal Python name resolution
-rules apply. The first base class that a particular name appears in (e.g.
-``Meta``) will be the one that is used. We stop searching once we find the
-name once. This means that if multiple parents contain a ``Meta`` class, only
-the first one is going to be used. All others will be ignored.
-
-Generally, you won't need to inherit from multiple parents. The main use-case
-where this is useful is for ''mix-in'' classes: adding a particular extra
-field or method to every class that inherits the mix-in. Try to keep your
-inheritance hierarchies as simple and straightforward as possible so that you
-won't have to struggle to work out where a particular piece of information is
-coming from.
-
-Models across files
-===================
-
-It's perfectly OK to relate a model to one from another app. To do this, just
-import the related model at the top of the model that holds your model. Then,
-just refer to the other model class wherever needed. For example::
-
-    from mysite.geography.models import ZipCode
-
-    class Restaurant(models.Model):
-        # ...
-        zip_code = models.ForeignKey(ZipCode)
-
-Using models
-============
-
-Once you have created your models, the final step is to tell Django you're
-going to *use* those models.
-
-Do this by editing your settings file and changing the ``INSTALLED_APPS``
-setting to add the name of the module that contains your ``models.py``.
-
-For example, if the models for your application live in the module
-``mysite.myapp.models`` (the package structure that is created for an
-application by the ``manage.py startapp`` script), ``INSTALLED_APPS`` should
-read, in part::
-
-    INSTALLED_APPS = (
-        #...
-        'mysite.myapp',
-        #...
-    )
-
-Providing initial SQL data
-==========================
-
-Django provides a hook for passing the database arbitrary SQL that's executed
-just after the CREATE TABLE statements. Use this hook, for example, if you want
-to populate default records, or create SQL functions, automatically.
-
-The hook is simple: Django just looks for a file called
-``<appname>/sql/<modelname>.sql``, where ``<appname>`` is your app directory and
-``<modelname>`` is the model's name in lowercase.
-
-In the ``Person`` example model at the top of this document, assuming it lives
-in an app called ``myapp``, you could add arbitrary SQL to the file
-``myapp/sql/person.sql``. Here's an example of what the file might contain::
-
-    INSERT INTO myapp_person (first_name, last_name) VALUES ('John', 'Lennon');
-    INSERT INTO myapp_person (first_name, last_name) VALUES ('Paul', 'McCartney');
-
-Each SQL file, if given, is expected to contain valid SQL statements
-which will insert the desired data (e.g., properly-formatted
-``INSERT`` statements separated by semicolons).
-
-The SQL files are read by the ``sqlcustom``, ``sqlreset``, ``sqlall`` and
-``reset`` commands in ``manage.py``. Refer to the `manage.py documentation`_
-for more information.
-
-Note that if you have multiple SQL data files, there's no guarantee of the
-order in which they're executed. The only thing you can assume is that, by the
-time your custom data files are executed, all the database tables already will
-have been created.
-
-.. _`manage.py documentation`: ../django-admin/#sqlcustom-appname-appname
-
-Database-backend-specific SQL data
-----------------------------------
-
-There's also a hook for backend-specific SQL data. For example, you can have
-separate initial-data files for PostgreSQL and MySQL. For each app, Django
-looks for a file called ``<appname>/sql/<modelname>.<backend>.sql``, where
-``<appname>`` is your app directory, ``<modelname>`` is the model's name in
-lowercase and ``<backend>`` is the value of ``DATABASE_ENGINE`` in your
-settings file (e.g., ``postgresql``, ``mysql``).
-
-Backend-specific SQL data is executed before non-backend-specific SQL data. For
-example, if your app contains the files ``sql/person.sql`` and
-``sql/person.postgresql.sql`` and you're installing the app on PostgreSQL,
-Django will execute the contents of ``sql/person.postgresql.sql`` first, then
-``sql/person.sql``.

BIN
docs/obsolete/_images/formrow.gif


BIN
docs/obsolete/_images/module.gif


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