Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

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

  • Loading branch information...
commit 97cb07c3a10ff0e584a260a7ee1001614691eb1d 1 parent b3688e8
@jacobian jacobian authored
Showing with 9,851 additions and 15,049 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. +8 −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 −1,173 docs/authentication.txt
  19. +22 −9 docs/conf.py
  20. +36 −0 docs/contents.txt
  21. +0 −297 docs/contenttypes.txt
  22. +0 −2,421 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 −2,468 docs/forms.txt
  37. +0 −1,273 docs/generic_views.txt
  38. +80 −0 docs/glossary.txt
  39. +15 −9 docs/{apache_auth.txt → 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/{custom_model_fields.txt → howto/custom-model-fields.txt}
  43. +78 −664 docs/{templates_python.txt → 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/{outputting_csv.txt → howto/outputting-csv.txt}
  52. +20 −16 docs/{outputting_pdf.txt → howto/outputting-pdf.txt}
  53. +29 −23 docs/{static_files.txt → 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/{design_philosophies.txt → misc/design-philosophies.txt}
  96. +4 −4 docs/{ → misc}/distributions.txt
  97. +14 −0 docs/misc/index.txt
  98. +0 −2,145 docs/model-api.txt
  99. BIN  docs/obsolete/_images/formrow.gif
  100. BIN  docs/obsolete/_images/module.gif
  101. BIN  docs/obsolete/_images/objecttools_01.gif
  102. BIN  docs/obsolete/_images/objecttools_02.gif
  103. +23 −8 docs/{admin_css.txt → obsolete/admin-css.txt}
  104. +13 −17 docs/{oldforms.txt → obsolete/forms.txt}
  105. +16 −0 docs/obsolete/index.txt
  106. +48 −0 docs/obsolete/newforms-migration.txt
  107. BIN  docs/ref/contrib/_images/flatfiles_admin.png
  108. BIN  docs/ref/contrib/_images/users_changelist.png
  109. +23 −32 docs/{ → ref/contrib}/admin.txt
  110. +6 −0 docs/ref/contrib/auth.txt
  111. +347 −0 docs/ref/contrib/contenttypes.txt
  112. +8 −3 docs/{ → ref/contrib}/csrf.txt
  113. +26 −20 docs/{ → ref/contrib}/databrowse.txt
  114. +58 −46 docs/{ → ref/contrib}/flatpages.txt
  115. +110 −0 docs/ref/contrib/formtools/form-preview.txt
  116. +316 −0 docs/ref/contrib/formtools/form-wizard.txt
  117. +12 −0 docs/ref/contrib/formtools/index.txt
  118. +91 −0 docs/ref/contrib/humanize.txt
  119. +43 −121 docs/{add_ons.txt → ref/contrib/index.txt}
  120. +651 −0 docs/ref/contrib/localflavor.txt
  121. +21 −20 docs/{ → ref/contrib}/redirects.txt
  122. +343 −0 docs/ref/contrib/sitemaps.txt
  123. +117 −84 docs/{ → ref/contrib}/sites.txt
  124. +204 −175 docs/{syndication_feeds.txt → ref/contrib/syndication.txt}
  125. +13 −8 docs/{ → ref/contrib}/webdesign.txt
  126. +27 −25 docs/{ → ref}/databases.txt
  127. +99 −126 docs/{ → ref}/django-admin.txt
  128. +117 −0 docs/ref/files/file.txt
  129. +13 −0 docs/ref/files/index.txt
  130. +50 −0 docs/ref/files/storage.txt
  131. +688 −0 docs/ref/forms/api.txt
  132. +751 −0 docs/ref/forms/fields.txt
  133. +14 −0 docs/ref/forms/index.txt
  134. +109 −0 docs/ref/forms/validation.txt
  135. +156 −0 docs/ref/forms/widgets.txt
  136. +1,106 −0 docs/ref/generic-views.txt
  137. +21 −0 docs/ref/index.txt
  138. +200 −0 docs/ref/middleware.txt
Sorry, we could not display the entire diff because it was too big.
View
1  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>
View
18 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
View
88 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())
View
146 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
+
View
171 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
View
3  docs/_static/default.css
@@ -0,0 +1,3 @@
+@import url(reset-fonts-grids.css);
+@import url(djangodocs.css);
+@import url(homepage.css);
View
126 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%; }
View
BIN  docs/_static/docicons-behindscenes.gif
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  docs/_static/docicons-note.gif
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN  docs/_static/docicons-philosophy.gif
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
22 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; }
View
8 docs/_static/reset-fonts-grids.css
@@ -0,0 +1,8 @@
+/*
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 2.5.1
+*/
+html{color:#000;background:#FFF;}body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,textarea,p,blockquote,th,td{margin:0;padding:0;}table{border-collapse:collapse;border-spacing:0;}fieldset,img{border:0;}address,caption,cite,code,dfn,em,strong,th,var{font-style:normal;font-weight:normal;}li{list-style:none;}caption,th{text-align:left;}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal;}q:before,q:after{content:'';}abbr,acronym {border:0;font-variant:normal;}sup {vertical-align:text-top;}sub {vertical-align:text-bottom;}input,textarea,select{font-family:inherit;font-size:inherit;font-weight:inherit;}input,textarea,select{*font-size:100%;}legend{color:#000;}body {font:13px/1.231 arial,helvetica,clean,sans-serif;*font-size:small;*font:x-small;}table {font-size:inherit;font:100%;}pre,code,kbd,samp,tt{font-family:monospace;*font-size:108%;line-height:100%;}
+body{text-align:center;}#ft{clear:both;}#doc,#doc2,#doc3,#doc4,.yui-t1,.yui-t2,.yui-t3,.yui-t4,.yui-t5,.yui-t6,.yui-t7{margin:auto;text-align:left;width:57.69em;*width:56.25em;min-width:750px;}#doc2{width:73.076em;*width:71.25em;}#doc3{margin:auto 10px;width:auto;}#doc4{width:74.923em;*width:73.05em;}.yui-b{position:relative;}.yui-b{_position:static;}#yui-main .yui-b{position:static;}#yui-main{width:100%;}.yui-t1 #yui-main,.yui-t2 #yui-main,.yui-t3 #yui-main{float:right;margin-left:-25em;}.yui-t4 #yui-main,.yui-t5 #yui-main,.yui-t6 #yui-main{float:left;margin-right:-25em;}.yui-t1 .yui-b{float:left;width:12.30769em;*width:12.00em;}.yui-t1 #yui-main .yui-b{margin-left:13.30769em;*margin-left:13.05em;}.yui-t2 .yui-b{float:left;width:13.8461em;*width:13.50em;}.yui-t2 #yui-main .yui-b{margin-left:14.8461em;*margin-left:14.55em;}.yui-t3 .yui-b{float:left;width:23.0769em;*width:22.50em;}.yui-t3 #yui-main .yui-b{margin-left:24.0769em;*margin-left:23.62em;}.yui-t4 .yui-b{float:right;width:13.8456em;*width:13.50em;}.yui-t4 #yui-main .yui-b{margin-right:14.8456em;*margin-right:14.55em;}.yui-t5 .yui-b{float:right;width:18.4615em;*width:18.00em;}.yui-t5 #yui-main .yui-b{margin-right:19.4615em;*margin-right:19.125em;}.yui-t6 .yui-b{float:right;width:23.0769em;*width:22.50em;}.yui-t6 #yui-main .yui-b{margin-right:24.0769em;*margin-right:23.62em;}.yui-t7 #yui-main .yui-b{display:block;margin:0 0 1em 0;}#yui-main .yui-b{float:none;width:auto;}.yui-gb .yui-u,.yui-g .yui-gb .yui-u,.yui-gb .yui-g,.yui-gb .yui-gb,.yui-gb .yui-gc,.yui-gb .yui-gd,.yui-gb .yui-ge,.yui-gb .yui-gf,.yui-gc .yui-u,.yui-gc .yui-g,.yui-gd .yui-u{float:left;}.yui-g .yui-u,.yui-g .yui-g,.yui-g .yui-gb,.yui-g .yui-gc,.yui-g .yui-gd,.yui-g .yui-ge,.yui-g .yui-gf,.yui-gc .yui-u,.yui-gd .yui-g,.yui-g .yui-gc .yui-u,.yui-ge .yui-u,.yui-ge .yui-g,.yui-gf .yui-g,.yui-gf .yui-u{float:right;}.yui-g div.first,.yui-gb div.first,.yui-gc div.first,.yui-gd div.first,.yui-ge div.first,.yui-gf div.first,.yui-g .yui-gc div.first,.yui-g .yui-ge div.first,.yui-gc div.first div.first{float:left;}.yui-g .yui-u,.yui-g .yui-g,.yui-g .yui-gb,.yui-g .yui-gc,.yui-g .yui-gd,.yui-g .yui-ge,.yui-g .yui-gf{width:49.1%;}.yui-gb .yui-u,.yui-g .yui-gb .yui-u,.yui-gb .yui-g,.yui-gb .yui-gb,.yui-gb .yui-gc,.yui-gb .yui-gd,.yui-gb .yui-ge,.yui-gb .yui-gf,.yui-gc .yui-u,.yui-gc .yui-g,.yui-gd .yui-u{width:32%;margin-left:1.99%;}.yui-gb .yui-u{*margin-left:1.9%;*width:31.9%;}.yui-gc div.first,.yui-gd .yui-u{width:66%;}.yui-gd div.first{width:32%;}.yui-ge div.first,.yui-gf .yui-u{width:74.2%;}.yui-ge .yui-u,.yui-gf div.first{width:24%;}.yui-g .yui-gb div.first,.yui-gb div.first,.yui-gc div.first,.yui-gd div.first{margin-left:0;}.yui-g .yui-g .yui-u,.yui-gb .yui-g .yui-u,.yui-gc .yui-g .yui-u,.yui-gd .yui-g .yui-u,.yui-ge .yui-g .yui-u,.yui-gf .yui-g .yui-u{width:49%;*width:48.1%;*margin-left:0;}.yui-g .yui-gb div.first,.yui-gb .yui-gb div.first{*margin-right:0;*width:32%;_width:31.7%;}.yui-g .yui-gc div.first,.yui-gd .yui-g{width:66%;}.yui-gb .yui-g div.first{*margin-right:4%;_margin-right:1.3%;}.yui-gb .yui-gc div.first,.yui-gb .yui-gd div.first{*margin-right:0;}.yui-gb .yui-gb .yui-u,.yui-gb .yui-gc .yui-u{*margin-left:1.8%;_margin-left:4%;}.yui-g .yui-gb .yui-u{_margin-left:1.0%;}.yui-gb .yui-gd .yui-u{*width:66%;_width:61.2%;}.yui-gb .yui-gd div.first{*width:31%;_width:29.5%;}.yui-g .yui-gc .yui-u,.yui-gb .yui-gc .yui-u{width:32%;_float:right;margin-right:0;_margin-left:0;}.yui-gb .yui-gc div.first{width:66%;*float:left;*margin-left:0;}.yui-gb .yui-ge .yui-u,.yui-gb .yui-gf .yui-u{margin:0;}.yui-gb .yui-gb .yui-u{_margin-left:.7%;}.yui-gb .yui-g div.first,.yui-gb .yui-gb div.first{*margin-left:0;}.yui-gc .yui-g .yui-u,.yui-gd .yui-g .yui-u{*width:48.1%;*margin-left:0;}s .yui-gb .yui-gd div.first{width:32%;}.yui-g .yui-gd div.first{_width:29.9%;}.yui-ge .yui-g{width:24%;}.yui-gf .yui-g{width:74.2%;}.yui-gb .yui-ge div.yui-u,.yui-gb .yui-gf div.yui-u{float:right;}.yui-gb .yui-ge div.first,.yui-gb .yui-gf div.first{float:left;}.yui-gb .yui-ge .yui-u,.yui-gb .yui-gf div.first{*width:24%;_width:20%;}.yui-gb .yui-ge div.first,.yui-gb .yui-gf .yui-u{*width:73.5%;_width:65.5%;}.yui-ge div.first .yui-gd .yui-u{width:65%;}.yui-ge div.first .yui-gd div.first{width:32%;}#bd:after,.yui-g:after,.yui-gb:after,.yui-gc:after,.yui-gd:after,.yui-ge:after,.yui-gf:after{content:".";display:block;height:0;clear:both;visibility:hidden;}#bd,.yui-g,.yui-gb,.yui-gc,.yui-gd,.yui-ge,.yui-gf{zoom:1;}
View
4 docs/_templates/genindex.html
@@ -0,0 +1,4 @@
+{% extends "!genindex.html" %}
+
+{% block bodyclass %}{% endblock %}
+{% block sidebarwrapper %}{% endblock %}
View
87 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 %}
View
3  docs/_templates/modindex.html
@@ -0,0 +1,3 @@
+{% extends "!modindex.html" %}
+{% block bodyclass %}{% endblock %}
+{% block sidebarwrapper %}{% endblock %}
View
3  docs/_templates/search.html
@@ -0,0 +1,3 @@
+{% extends "!search.html" %}
+{% block bodyclass %}{% endblock %}
+{% block sidebarwrapper %}{% endblock %}
View
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/
View
1,173 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
View
0  docs/cache.txt
Sorry, we could not display the changes to this file because there were too many other changes to display.
View
31 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 @@
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 @@
# 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 @@
# 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 @@
# 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 @@
# 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 @@
# 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
+
View
36 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
View
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.