summaryrefslogtreecommitdiff
path: root/parts/django/docs/intro
diff options
context:
space:
mode:
authorNishanth Amuluru2011-01-11 22:41:51 +0530
committerNishanth Amuluru2011-01-11 22:41:51 +0530
commitb03203c8cb991c16ac8a3d74c8c4078182d0bb48 (patch)
tree7cf13b2deacbfaaec99edb431b83ddd5ea734a52 /parts/django/docs/intro
parent0c50203cd9eb94b819883c3110922e873f003138 (diff)
downloadpytask-b03203c8cb991c16ac8a3d74c8c4078182d0bb48.tar.gz
pytask-b03203c8cb991c16ac8a3d74c8c4078182d0bb48.tar.bz2
pytask-b03203c8cb991c16ac8a3d74c8c4078182d0bb48.zip
removed all the buildout files
Diffstat (limited to 'parts/django/docs/intro')
-rw-r--r--parts/django/docs/intro/_images/admin01.pngbin18233 -> 0 bytes
-rw-r--r--parts/django/docs/intro/_images/admin02.pngbin64260 -> 0 bytes
-rw-r--r--parts/django/docs/intro/_images/admin02t.pngbin24726 -> 0 bytes
-rw-r--r--parts/django/docs/intro/_images/admin03.pngbin75434 -> 0 bytes
-rw-r--r--parts/django/docs/intro/_images/admin03t.pngbin28131 -> 0 bytes
-rw-r--r--parts/django/docs/intro/_images/admin04.pngbin57718 -> 0 bytes
-rw-r--r--parts/django/docs/intro/_images/admin04t.pngbin22806 -> 0 bytes
-rw-r--r--parts/django/docs/intro/_images/admin05.pngbin28875 -> 0 bytes
-rw-r--r--parts/django/docs/intro/_images/admin05t.pngbin22754 -> 0 bytes
-rw-r--r--parts/django/docs/intro/_images/admin06.pngbin22780 -> 0 bytes
-rw-r--r--parts/django/docs/intro/_images/admin06t.pngbin18156 -> 0 bytes
-rw-r--r--parts/django/docs/intro/_images/admin07.pngbin19804 -> 0 bytes
-rw-r--r--parts/django/docs/intro/_images/admin08.pngbin31552 -> 0 bytes
-rw-r--r--parts/django/docs/intro/_images/admin08t.pngbin23883 -> 0 bytes
-rw-r--r--parts/django/docs/intro/_images/admin09.pngbin16318 -> 0 bytes
-rw-r--r--parts/django/docs/intro/_images/admin10.pngbin10914 -> 0 bytes
-rw-r--r--parts/django/docs/intro/_images/admin11.pngbin33563 -> 0 bytes
-rw-r--r--parts/django/docs/intro/_images/admin11t.pngbin26365 -> 0 bytes
-rw-r--r--parts/django/docs/intro/_images/admin12.pngbin12682 -> 0 bytes
-rw-r--r--parts/django/docs/intro/_images/admin13.pngbin22062 -> 0 bytes
-rw-r--r--parts/django/docs/intro/_images/admin13t.pngbin18690 -> 0 bytes
-rw-r--r--parts/django/docs/intro/_images/admin14.pngbin28987 -> 0 bytes
-rw-r--r--parts/django/docs/intro/_images/admin14t.pngbin23460 -> 0 bytes
-rw-r--r--parts/django/docs/intro/index.txt36
-rw-r--r--parts/django/docs/intro/install.txt84
-rw-r--r--parts/django/docs/intro/overview.txt324
-rw-r--r--parts/django/docs/intro/tutorial01.txt690
-rw-r--r--parts/django/docs/intro/tutorial02.txt465
-rw-r--r--parts/django/docs/intro/tutorial03.txt546
-rw-r--r--parts/django/docs/intro/tutorial04.txt346
-rw-r--r--parts/django/docs/intro/whatsnext.txt231
31 files changed, 0 insertions, 2722 deletions
diff --git a/parts/django/docs/intro/_images/admin01.png b/parts/django/docs/intro/_images/admin01.png
deleted file mode 100644
index 28f14d6..0000000
--- a/parts/django/docs/intro/_images/admin01.png
+++ /dev/null
Binary files differ
diff --git a/parts/django/docs/intro/_images/admin02.png b/parts/django/docs/intro/_images/admin02.png
deleted file mode 100644
index 4b49ebb..0000000
--- a/parts/django/docs/intro/_images/admin02.png
+++ /dev/null
Binary files differ
diff --git a/parts/django/docs/intro/_images/admin02t.png b/parts/django/docs/intro/_images/admin02t.png
deleted file mode 100644
index d7519d1..0000000
--- a/parts/django/docs/intro/_images/admin02t.png
+++ /dev/null
Binary files differ
diff --git a/parts/django/docs/intro/_images/admin03.png b/parts/django/docs/intro/_images/admin03.png
deleted file mode 100644
index 635226c..0000000
--- a/parts/django/docs/intro/_images/admin03.png
+++ /dev/null
Binary files differ
diff --git a/parts/django/docs/intro/_images/admin03t.png b/parts/django/docs/intro/_images/admin03t.png
deleted file mode 100644
index 94273cb..0000000
--- a/parts/django/docs/intro/_images/admin03t.png
+++ /dev/null
Binary files differ
diff --git a/parts/django/docs/intro/_images/admin04.png b/parts/django/docs/intro/_images/admin04.png
deleted file mode 100644
index 982420a..0000000
--- a/parts/django/docs/intro/_images/admin04.png
+++ /dev/null
Binary files differ
diff --git a/parts/django/docs/intro/_images/admin04t.png b/parts/django/docs/intro/_images/admin04t.png
deleted file mode 100644
index a2ec8bb..0000000
--- a/parts/django/docs/intro/_images/admin04t.png
+++ /dev/null
Binary files differ
diff --git a/parts/django/docs/intro/_images/admin05.png b/parts/django/docs/intro/_images/admin05.png
deleted file mode 100644
index b424393..0000000
--- a/parts/django/docs/intro/_images/admin05.png
+++ /dev/null
Binary files differ
diff --git a/parts/django/docs/intro/_images/admin05t.png b/parts/django/docs/intro/_images/admin05t.png
deleted file mode 100644
index a5da950..0000000
--- a/parts/django/docs/intro/_images/admin05t.png
+++ /dev/null
Binary files differ
diff --git a/parts/django/docs/intro/_images/admin06.png b/parts/django/docs/intro/_images/admin06.png
deleted file mode 100644
index 5f24d4e..0000000
--- a/parts/django/docs/intro/_images/admin06.png
+++ /dev/null
Binary files differ
diff --git a/parts/django/docs/intro/_images/admin06t.png b/parts/django/docs/intro/_images/admin06t.png
deleted file mode 100644
index fb65e0a..0000000
--- a/parts/django/docs/intro/_images/admin06t.png
+++ /dev/null
Binary files differ
diff --git a/parts/django/docs/intro/_images/admin07.png b/parts/django/docs/intro/_images/admin07.png
deleted file mode 100644
index b21022f..0000000
--- a/parts/django/docs/intro/_images/admin07.png
+++ /dev/null
Binary files differ
diff --git a/parts/django/docs/intro/_images/admin08.png b/parts/django/docs/intro/_images/admin08.png
deleted file mode 100644
index ddac57e..0000000
--- a/parts/django/docs/intro/_images/admin08.png
+++ /dev/null
Binary files differ
diff --git a/parts/django/docs/intro/_images/admin08t.png b/parts/django/docs/intro/_images/admin08t.png
deleted file mode 100644
index 83773bb..0000000
--- a/parts/django/docs/intro/_images/admin08t.png
+++ /dev/null
Binary files differ
diff --git a/parts/django/docs/intro/_images/admin09.png b/parts/django/docs/intro/_images/admin09.png
deleted file mode 100644
index ba7de1b..0000000
--- a/parts/django/docs/intro/_images/admin09.png
+++ /dev/null
Binary files differ
diff --git a/parts/django/docs/intro/_images/admin10.png b/parts/django/docs/intro/_images/admin10.png
deleted file mode 100644
index 07a9bf3..0000000
--- a/parts/django/docs/intro/_images/admin10.png
+++ /dev/null
Binary files differ
diff --git a/parts/django/docs/intro/_images/admin11.png b/parts/django/docs/intro/_images/admin11.png
deleted file mode 100644
index 6c583fd..0000000
--- a/parts/django/docs/intro/_images/admin11.png
+++ /dev/null
Binary files differ
diff --git a/parts/django/docs/intro/_images/admin11t.png b/parts/django/docs/intro/_images/admin11t.png
deleted file mode 100644
index af792b8..0000000
--- a/parts/django/docs/intro/_images/admin11t.png
+++ /dev/null
Binary files differ
diff --git a/parts/django/docs/intro/_images/admin12.png b/parts/django/docs/intro/_images/admin12.png
deleted file mode 100644
index aac5c0d..0000000
--- a/parts/django/docs/intro/_images/admin12.png
+++ /dev/null
Binary files differ
diff --git a/parts/django/docs/intro/_images/admin13.png b/parts/django/docs/intro/_images/admin13.png
deleted file mode 100644
index 49a5950..0000000
--- a/parts/django/docs/intro/_images/admin13.png
+++ /dev/null
Binary files differ
diff --git a/parts/django/docs/intro/_images/admin13t.png b/parts/django/docs/intro/_images/admin13t.png
deleted file mode 100644
index 7dc01e1..0000000
--- a/parts/django/docs/intro/_images/admin13t.png
+++ /dev/null
Binary files differ
diff --git a/parts/django/docs/intro/_images/admin14.png b/parts/django/docs/intro/_images/admin14.png
deleted file mode 100644
index b1f4a54..0000000
--- a/parts/django/docs/intro/_images/admin14.png
+++ /dev/null
Binary files differ
diff --git a/parts/django/docs/intro/_images/admin14t.png b/parts/django/docs/intro/_images/admin14t.png
deleted file mode 100644
index 86c3acc..0000000
--- a/parts/django/docs/intro/_images/admin14t.png
+++ /dev/null
Binary files differ
diff --git a/parts/django/docs/intro/index.txt b/parts/django/docs/intro/index.txt
deleted file mode 100644
index bc61be7..0000000
--- a/parts/django/docs/intro/index.txt
+++ /dev/null
@@ -1,36 +0,0 @@
-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 \ No newline at end of file
diff --git a/parts/django/docs/intro/install.txt b/parts/django/docs/intro/install.txt
deleted file mode 100644
index 327686f..0000000
--- a/parts/django/docs/intro/install.txt
+++ /dev/null
@@ -1,84 +0,0 @@
-Quick install guide
-===================
-
-Before you can use Django, you'll need to get it installed. We have a
-:doc:`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 from 2.4 to 2.7 (due to backwards
-incompatibilities in Python 3.0, Django does not currently work with
-Python 3.0; see :doc:`the Django FAQ </faq/install>` for more
-information on supported Python versions and the 3.0 transition), 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.
-
-.. admonition:: Django on Jython
-
- If you use Jython_ (a Python implementation for the Java platform), you'll
- need to follow a few additional steps. See :doc:`/howto/jython` for details.
-
-.. _jython: http://www.jython.org/
-
-You can verify that Python's installed by 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 :doc:`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.
-
-.. admonition:: Always refer to the documentation that corresponds to the
- version of Django you're using!
-
- If you 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, and
- they likely won't work with an official release.
-
-That's it!
-----------
-
-That's it -- you can now :doc:`move onto the tutorial </intro/tutorial01>`.
-
-
-
diff --git a/parts/django/docs/intro/overview.txt b/parts/django/docs/intro/overview.txt
deleted file mode 100644
index 34572a6..0000000
--- a/parts/django/docs/intro/overview.txt
+++ /dev/null
@@ -1,324 +0,0 @@
-==================
-Django at a glance
-==================
-
-Because Django was developed in a fast-paced newsroom environment, it was
-designed to make common Web-development tasks fast and easy. Here's an informal
-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 -- but we've got both! When you're ready to start a project, you can
-:doc:`start with the tutorial </intro/tutorial01>` or :doc:`dive right into more
-detailed documentation </topics/index>`.
-
-Design your model
-=================
-
-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 :doc:`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, which might be saved in
-the file ``mysite/news/models.py``::
-
- class Reporter(models.Model):
- full_name = models.CharField(max_length=70)
-
- def __unicode__(self):
- return self.full_name
-
- class Article(models.Model):
- pub_date = models.DateTimeField()
- headline = models.CharField(max_length=200)
- content = models.TextField()
- reporter = models.ForeignKey(Reporter)
-
- def __unicode__(self):
- return self.headline
-
-Install it
-==========
-
-Next, run the Django command-line utility to create the database tables
-automatically:
-
-.. code-block:: bash
-
- manage.py syncdb
-
-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, :doc:`Python API </topics/db/queries>` to
-access your data. The API is created on the fly, no code generation necessary::
-
- # Import the models we created from our "news" app
- >>> from news.models import Reporter, Article
-
- # No reporters are in the system yet.
- >>> Reporter.objects.all()
- []
-
- # Create a new Reporter.
- >>> r = Reporter(full_name='John Smith')
-
- # Save the object into the database. You have to call save() explicitly.
- >>> r.save()
-
- # Now it has an ID.
- >>> r.id
- 1
-
- # Now the new reporter is in the database.
- >>> Reporter.objects.all()
- [<Reporter: John Smith>]
-
- # Fields are represented as attributes on the Python object.
- >>> r.full_name
- 'John Smith'
-
- # Django provides a rich database lookup API.
- >>> Reporter.objects.get(id=1)
- <Reporter: John Smith>
- >>> Reporter.objects.get(full_name__startswith='John')
- <Reporter: John Smith>
- >>> Reporter.objects.get(full_name__contains='mith')
- <Reporter: John Smith>
- >>> Reporter.objects.get(id=2)
- Traceback (most recent call last):
- ...
- DoesNotExist: Reporter matching query does not exist.
-
- # Create an article.
- >>> from datetime import datetime
- >>> a = Article(pub_date=datetime.now(), headline='Django is cool',
- ... content='Yeah.', reporter=r)
- >>> a.save()
-
- # Now the article is in the database.
- >>> Article.objects.all()
- [<Article: Django is cool>]
-
- # Article objects get API access to related Reporter objects.
- >>> r = a.reporter
- >>> r.full_name
- 'John Smith'
-
- # And vice versa: Reporter objects get API access to Article objects.
- >>> r.article_set.all()
- [<Article: Django is cool>]
-
- # The API follows relationships as far as you need, performing efficient
- # JOINs for you behind the scenes.
- # This finds all articles by a reporter whose name starts with "John".
- >>> Article.objects.filter(reporter__full_name__startswith="John")
- [<Article: Django is cool>]
-
- # Change an object by altering its attributes and calling save().
- >>> r.full_name = 'Billy Goat'
- >>> r.save()
-
- # Delete an object with delete().
- >>> r.delete()
-
-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 :doc:`administrative interface </ref/contrib/admin/index>` -- a Web
-site that lets authenticated users add, change and delete objects. It's as easy
-as registering your model in the admin site::
-
- # In models.py...
-
- from django.db import models
-
- class Article(models.Model):
- pub_date = models.DateTimeField()
- headline = models.CharField(max_length=200)
- content = models.TextField()
- reporter = models.ForeignKey(Reporter)
-
-
- # In admin.py in the same directory...
-
- import models
- from django.contrib import admin
-
- admin.site.register(models.Article)
-
-The philosophy here is that your site is edited by a staff, or a client, or
-maybe just you -- and you don't want to have to deal with creating backend
-interfaces just to manage content.
-
-One typical workflow in creating Django apps is to create models and get the
-admin sites up and running as fast as possible, so your staff (or clients) can
-start populating data. Then, develop the way data is presented to the public.
-
-Design your URLs
-================
-
-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 :doc:`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::
-
- from django.conf.urls.defaults import *
-
- urlpatterns = patterns('',
- (r'^articles/(\d{4})/$', 'news.views.year_archive'),
- (r'^articles/(\d{4})/(\d{2})/$', 'news.views.month_archive'),
- (r'^articles/(\d{4})/(\d{2})/(\d+)/$', 'news.views.article_detail'),
- )
-
-The code above maps URLs, as simple regular expressions, to the location of
-Python callback functions ("views"). The regular expressions use parenthesis to
-"capture" values from the URLs. When a user requests a page, Django runs
-through each pattern, in order, and stops at the first one that matches the
-requested URL. (If none of them matches, Django calls a special-case 404 view.)
-This is blazingly fast, because the regular expressions are compiled at load
-time.
-
-Once one of the regexes matches, Django imports and calls the given view, which
-is a simple Python function. Each view gets passed a request object --
-which contains request metadata -- and the values captured in the regex.
-
-For example, if a user requested the URL "/articles/2005/05/39323/", Django
-would call the function ``news.views.article_detail(request,
-'2005', '05', '39323')``.
-
-Write your views
-================
-
-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 :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
-``year_archive`` from above::
-
- def year_archive(request, year):
- 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 :doc:`template system </topics/templates>`, which has
-several powerful features but strives to stay simple enough for non-programmers
-to use.
-
-Design your templates
-=====================
-
-The code above loads the ``news/year_archive.html`` template.
-
-Django has a template search path, which allows you to minimize redundancy among
-templates. In your Django settings, you specify a list of directories to check
-for templates. If a template doesn't exist in the first directory, it checks the
-second, and so on.
-
-Let's say the ``news/article_detail.html`` template was found. Here's what that
-might look like:
-
-.. code-block:: html+django
-
- {% extends "base.html" %}
-
- {% block title %}Articles for {{ year }}{% endblock %}
-
- {% block content %}
- <h1>Articles for {{ year }}</h1>
-
- {% for article in article_list %}
- <p>{{ article.headline }}</p>
- <p>By {{ article.reporter.full_name }}</p>
- <p>Published {{ article.pub_date|date:"F j, Y" }}</p>
- {% endfor %}
- {% endblock %}
-
-Variables are surrounded by double-curly braces. ``{{ article.headline }}``
-means "Output the value of the article's headline attribute." But dots aren't
-used only for attribute lookup: They also can do dictionary-key lookup, index
-lookup and function calls.
-
-Note ``{{ article.pub_date|date:"F j, Y" }}`` uses a Unix-style "pipe" (the "|"
-character). This is called a template filter, and it's a way to filter the value
-of a variable. In this case, the date filter formats a Python datetime object in
-the given format (as found in PHP's date function; yes, there is one good idea
-in PHP).
-
-You can chain together as many filters as you'd like. You can write custom
-filters. You can write custom template tags, which run custom Python code behind
-the scenes.
-
-Finally, Django uses the concept of "template inheritance": That's what the
-``{% extends "base.html" %}`` does. It means "First load the template called
-'base', which has defined a bunch of blocks, and fill the blocks with the
-following blocks." In short, that lets you dramatically cut down on redundancy
-in templates: each template has to define only what's unique to that template.
-
-Here's what the "base.html" template might look like:
-
-.. code-block:: html+django
-
- <html>
- <head>
- <title>{% block title %}{% endblock %}</title>
- </head>
- <body>
- <img src="sitelogo.gif" alt="Logo" />
- {% block content %}{% endblock %}
- </body>
- </html>
-
-Simplistically, it defines the look-and-feel of the site (with the site's logo),
-and provides "holes" for child templates to fill. This makes a site redesign as
-easy as changing a single file -- the base template.
-
-It also lets you create multiple versions of a site, with different base
-templates, while reusing child templates. Django's creators have used this
-technique to create strikingly different cell-phone editions of sites -- simply
-by creating a new base template.
-
-Note that you don't have to use Django's template system if you prefer another
-system. While Django's template system is particularly well-integrated with
-Django's model layer, nothing forces you to use it. For that matter, you don't
-have to use Django's database API, either. You can use another database
-abstraction layer, you can read XML files, you can read files off disk, or
-anything you want. Each piece of Django -- models, views, templates -- is
-decoupled from the next.
-
-This is just the surface
-========================
-
-This has been only a quick overview of Django's functionality. Some more useful
-features:
-
- * A :doc:`caching framework </topics/cache>` that integrates with memcached
- or other backends.
-
- * A :doc:`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.
-
-The next obvious steps are for you to `download Django`_, read :doc:`the
-tutorial </intro/tutorial01>` and join `the community`_. Thanks for your
-interest!
-
-.. _download Django: http://www.djangoproject.com/download/
-.. _the community: http://www.djangoproject.com/community/
diff --git a/parts/django/docs/intro/tutorial01.txt b/parts/django/docs/intro/tutorial01.txt
deleted file mode 100644
index 560070b..0000000
--- a/parts/django/docs/intro/tutorial01.txt
+++ /dev/null
@@ -1,690 +0,0 @@
-=====================================
-Writing your first Django app, part 1
-=====================================
-
-Let's learn by example.
-
-Throughout this tutorial, we'll walk you through the creation of a basic
-poll application.
-
-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 :doc:`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
- with other Django users who might be able to help.
-
-__ 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 :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.
-
-.. admonition:: Script name may differ in distribution packages
-
- If you installed Django using a Linux distribution's package manager
- (e.g. apt-get or yum) ``django-admin.py`` may have been renamed to
- ``django-admin``. You may continue through this documentation by omitting
- ``.py`` from each command.
-
-.. 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 :doc:`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 ``test`` (which
- conflicts with a built-in Python package).
-
-:doc:`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 :doc:`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
- security.
-
- Put your code in some directory **outside** of the document root, such as
- :file:`/home/mycode`.
-
-Let's look at what :djadmin:`startproject` created::
-
- mysite/
- __init__.py
- manage.py
- settings.py
- urls.py
-
-These files are:
-
- * :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.)
-
- * :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 :doc:`/ref/django-admin`.
-
- * :file:`settings.py`: Settings/configuration for this Django project.
- :doc:`/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
- :doc:`/topics/http/urls`.
-
-.. _more about packages: http://docs.python.org/tutorial/modules.html#packages
-
-The development server
-----------------------
-
-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 1.0, using settings 'mysite.settings'
- Development server is running at http://127.0.0.1:8000/
- Quit the server with CONTROL-C.
-
-You've started the Django development server, a lightweight Web server written
-purely in Python. We've included this with Django so you can develop things
-rapidly, without having to deal with configuring a production server -- such as
-Apache -- until you're ready for production.
-
-Now's a good time to note: DON'T use this server in anything resembling a
-production environment. It's intended only for use while developing. (We're in
-the business of making Web frameworks, not Web servers.)
-
-Now that the server's running, visit http://127.0.0.1:8000/ with your Web
-browser. You'll see a "Welcome to Django" page, in pleasant, light-blue pastel.
-It worked!
-
-.. admonition:: Changing the port
-
- By default, the :djadmin:`runserver` command starts the development server
- on the internal IP at 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
-
- If you want to change the server's IP, pass it along with the port. So to
- listen on all public IPs (useful if you want to show off your work on other
- computers), use:
-
- .. code-block:: bash
-
- python manage.py runserver 0.0.0.0:8000
-
- Full docs for the development server can be found in the
- :djadmin:`runserver` reference.
-
-Database setup
---------------
-
-Now, edit :file:`settings.py`. It's a normal Python module with
-module-level variables representing Django settings. Change the
-following keys in the :setting:`DATABASES` ``'default'`` item to match
-your databases connection settings.
-
- * :setting:`ENGINE` -- Either
- ``'django.db.backends.postgresql_psycopg2'``,
- ``'django.db.backends.mysql'`` or
- ``'django.db.backends.sqlite3'``. Other backends are
- :setting:`also available <ENGINE>`.
-
- * :setting:`NAME` -- The name of your database. If you're using
- SQLite, the database will be a file on your computer; in that
- case, :setting:`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).
-
- When specifying the path, always use forward slashes, even on
- Windows (e.g. ``C:/homes/user/mysite/sqlite3.db``).
-
- * :setting:`USER` -- Your database username (not used for SQLite).
-
- * :setting:`PASSWORD` -- Your database password (not used for
- SQLite).
-
- * :setting:`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:`ENGINE` to ``'django.db.backends.sqlite3'``). SQLite
-is included as part of Python 2.5 and later, so you won't need to
-install anything else.
-
-.. 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
- database's interactive prompt.
-
- 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 :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.
-
- * :mod:`django.contrib.contenttypes` -- A framework for content types.
-
- * :mod:`django.contrib.sessions` -- A session framework.
-
- * :mod:`django.contrib.sites` -- A framework for managing multiple sites
- with one Django installation.
-
- * :mod:`django.contrib.messages` -- A messaging framework.
-
-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:
-
-.. code-block:: bash
-
- python manage.py syncdb
-
-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
-display the tables Django created.
-
-.. admonition:: For the minimalists
-
- 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
- :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
-===============
-
-Now that your environment -- a "project" -- is set up, you're set to start
-doing work.
-
-Each application you write in Django consists of a Python package, somewhere
-on your `Python path`_, that follows a certain convention. Django comes with a
-utility that automatically generates the basic directory structure of an app,
-so you can focus on writing code rather than creating directories.
-
-.. admonition:: Projects vs. apps
-
- What's the difference between a project and an app? An app is a Web
- application that does something -- e.g., a Weblog system, a database of
- public records or a simple poll app. A project is a collection of
- configuration and apps for a particular Web site. A project can contain
- multiple apps. An app can be in multiple projects.
-
-Your apps can live anywhere on your `Python path`_. In this tutorial, we'll
-create our poll app in the :file:`mysite` directory for simplicity.
-
-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 :file:`polls`, which is laid out like this::
-
- polls/
- __init__.py
- models.py
- tests.py
- views.py
-
-This directory structure will house the poll application.
-
-The first step in writing a database Web app in Django is to define your models
--- essentially, your database layout, with additional metadata.
-
-.. 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 :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
-:file:`polls/models.py` file so it looks like this::
-
- from django.db import models
-
- class Poll(models.Model):
- question = models.CharField(max_length=200)
- pub_date = models.DateTimeField('date published')
-
- class Choice(models.Model):
- poll = models.ForeignKey(Poll)
- choice = models.CharField(max_length=200)
- votes = models.IntegerField()
-
-The code is straightforward. Each model is represented by a class that
-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 :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
-: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/tutorial/modules.html#the-module-search-path
-
-Activating models
-=================
-
-That small bit of model code gives Django a lot of information. With it, Django
-is able to:
-
- * Create a database schema (``CREATE TABLE`` statements) for this app.
- * Create a Python database-access API for accessing Poll and Choice objects.
-
-But first we need to tell our project that the ``polls`` app is installed.
-
-.. admonition:: Philosophy
-
- Django apps are "pluggable": You can use an app in multiple projects, and
- you can distribute apps, because they don't have to be tied to a given
- Django installation.
-
-Edit the :file:`settings.py` file again, and change the
-:setting:`INSTALLED_APPS` setting to include the string ``'polls'``. So
-it'll look like this::
-
- INSTALLED_APPS = (
- 'django.contrib.auth',
- 'django.contrib.contenttypes',
- 'django.contrib.sessions',
- 'django.contrib.sites',
- 'polls'
- )
-
-Now Django knows to include 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):
-
-.. code-block:: sql
-
- BEGIN;
- CREATE TABLE "polls_poll" (
- "id" serial NOT NULL PRIMARY KEY,
- "question" varchar(200) NOT NULL,
- "pub_date" timestamp with time zone NOT NULL
- );
- CREATE TABLE "polls_choice" (
- "id" serial NOT NULL PRIMARY KEY,
- "poll_id" integer NOT NULL REFERENCES "polls_poll" ("id"),
- "choice" varchar(200) NOT NULL,
- "votes" integer NOT NULL
- );
- COMMIT;
-
-Note the following:
-
- * The exact output will vary depending on the database you are using.
-
- * Table names are automatically generated by combining the name of the app
- (``polls``) and the lowercase name of the model -- ``poll`` and
- ``choice``. (You can override this behavior.)
-
- * Primary keys (IDs) are added automatically. (You can override this, too.)
-
- * 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.
-
- * It's tailored to the database you're using, so database-specific field
- types such as ``auto_increment`` (MySQL), ``serial`` (PostgreSQL), or
- ``integer primary key`` (SQLite) are handled for you automatically. Same
- goes for quoting of field names -- e.g., using double quotes or single
- quotes. The author of this tutorial runs PostgreSQL, so the example
- output is in PostgreSQL syntax.
-
- * 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:
-
- * :djadmin:`python manage.py validate <validate>` -- Checks for any errors
- in the construction of your models.
-
- * :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.
-
- * :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).
-
- * :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 :djadmin:`syncdb` again to create those model tables in your database:
-
-.. code-block:: bash
-
- python manage.py syncdb
-
-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.
-
-Read the :doc:`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:
-
-.. code-block:: bash
-
- python manage.py shell
-
-We're using this instead of simply typing "python", because ``manage.py`` sets
-up the project's environment for you. "Setting up the environment" involves two
-things:
-
- * Putting ``polls`` on ``sys.path``. For flexibility, several pieces of
- Django refer to projects in Python dotted-path notation (e.g.
- ``'polls.models'``). In order for this to work, the ``polls``
- package has to be on ``sys.path``.
-
- 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``
- and ``polls`` are at the root level on the Python path (i.e., ``import mysite``
- and ``import polls`` work) and set the ``DJANGO_SETTINGS_MODULE`` environment
- variable to ``mysite.settings``.
-
- For more information on all of this, see the :doc:`django-admin.py
- documentation </ref/django-admin>`.
-
-Once you're in the shell, explore the :doc:`database API </topics/db/queries>`::
-
- >>> from polls.models import Poll, Choice # Import the model classes we just wrote.
-
- # No polls are in the system yet.
- >>> Poll.objects.all()
- []
-
- # Create a new Poll.
- >>> import datetime
- >>> p = Poll(question="What's up?", pub_date=datetime.datetime.now())
-
- # Save the object into the database. You have to call save() explicitly.
- >>> p.save()
-
- # Now it has an ID. Note that this might say "1L" instead of "1", depending
- # on which database you're using. That's no biggie; it just means your
- # database backend prefers to return integers as Python long integer
- # objects.
- >>> p.id
- 1
-
- # Access database columns via Python attributes.
- >>> p.question
- "What's up?"
- >>> p.pub_date
- datetime.datetime(2007, 7, 15, 12, 00, 53)
-
- # Change values by changing the attributes, then calling save().
- >>> p.pub_date = datetime.datetime(2007, 4, 1, 0, 0)
- >>> p.save()
-
- # objects.all() displays all the polls in the database.
- >>> Poll.objects.all()
- [<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
-:meth:`~django.db.models.Model.__unicode__` method to both ``Poll`` and
-``Choice``::
-
- class Poll(models.Model):
- # ...
- def __unicode__(self):
- return self.question
-
- class Choice(models.Model):
- # ...
- def __unicode__(self):
- return self.choice
-
-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 :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
- :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::
-
- import datetime
- # ...
- class Poll(models.Model):
- # ...
- def was_published_today(self):
- return self.pub_date.date() == datetime.date.today()
-
-Note the addition of ``import datetime`` to reference Python's standard
-``datetime`` module.
-
-Save these changes and start a new Python interactive shell by running
-``python manage.py shell`` again::
-
- >>> from polls.models import Poll, Choice
-
- # Make sure our __unicode__() addition worked.
- >>> Poll.objects.all()
- [<Poll: What's up?>]
-
- # Django provides a rich database lookup API that's entirely driven by
- # keyword arguments.
- >>> Poll.objects.filter(id=1)
- [<Poll: What's up?>]
- >>> Poll.objects.filter(question__startswith='What')
- [<Poll: What's up?>]
-
- # Get the poll whose year is 2007.
- >>> Poll.objects.get(pub_date__year=2007)
- <Poll: What's up?>
-
- >>> Poll.objects.get(id=2)
- Traceback (most recent call last):
- ...
- DoesNotExist: Poll matching query does not exist.
-
- # Lookup by a primary key is the most common case, so Django provides a
- # shortcut for primary-key exact lookups.
- # The following is identical to Poll.objects.get(id=1).
- >>> Poll.objects.get(pk=1)
- <Poll: What's up?>
-
- # Make sure our custom method worked.
- >>> p = Poll.objects.get(pk=1)
- >>> p.was_published_today()
- False
-
- # Give the Poll a couple of Choices. The create call constructs a new
- # choice object, does the INSERT statement, adds the choice to the set
- # of available choices and returns the new Choice object. Django creates
- # a set to hold the "other side" of a ForeignKey relation
- # (e.g. a poll's choices) which can be accessed via the API.
- >>> p = Poll.objects.get(pk=1)
-
- # Display any choices from the related object set -- none so far.
- >>> p.choice_set.all()
- []
-
- # Create three choices.
- >>> p.choice_set.create(choice='Not much', votes=0)
- <Choice: Not much>
- >>> p.choice_set.create(choice='The sky', votes=0)
- <Choice: The sky>
- >>> c = p.choice_set.create(choice='Just hacking again', votes=0)
-
- # Choice objects have API access to their related Poll objects.
- >>> c.poll
- <Poll: What's up?>
-
- # And vice versa: Poll objects get access to Choice objects.
- >>> p.choice_set.all()
- [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]
- >>> p.choice_set.count()
- 3
-
- # The API automatically follows relationships as far as you need.
- # Use double underscores to separate relationships.
- # This works as many levels deep as you want; there's no limit.
- # Find all Choices for any poll whose pub_date is in 2007.
- >>> Choice.objects.filter(poll__pub_date__year=2007)
- [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]
-
- # Let's delete one of the choices. Use delete() for that.
- >>> c = p.choice_set.filter(choice__startswith='Just hacking')
- >>> c.delete()
-
-For more information on model relations, see :doc:`Accessing related objects
-</ref/models/relations>`. For full details on the database API, see our
-:doc:`Database API reference </topics/db/queries>`.
-
-When you're comfortable with the API, read :doc:`part 2 of this tutorial
-</intro/tutorial02>` to get Django's automatic admin working.
diff --git a/parts/django/docs/intro/tutorial02.txt b/parts/django/docs/intro/tutorial02.txt
deleted file mode 100644
index c80d87d..0000000
--- a/parts/django/docs/intro/tutorial02.txt
+++ /dev/null
@@ -1,465 +0,0 @@
-=====================================
-Writing your first Django app, part 2
-=====================================
-
-This tutorial begins where :doc:`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.
-
- 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.
-
-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 :setting:`INSTALLED_APPS` setting.
-
- * Run ``python manage.py syncdb``. Since you have added a new application
- to :setting:`INSTALLED_APPS`, the database tables need to be updated.
-
- * Edit your ``mysite/urls.py`` file and uncomment the lines that reference
- the admin -- there are three lines in total to uncomment. This file is a
- URLconf; we'll dig into URLconfs in the next tutorial. For now, all you
- need to know is that it maps URL roots to applications. In the end, you
- should have a ``urls.py`` file that looks like this:
-
- .. versionchanged:: 1.1
- The method for adding admin urls has changed in Django 1.1.
-
- .. parsed-literal::
-
- from django.conf.urls.defaults import *
-
- # Uncomment the next two lines to enable the admin:
- **from django.contrib import admin**
- **admin.autodiscover()**
-
- urlpatterns = patterns('',
- # Example:
- # (r'^mysite/', include('mysite.foo.urls')),
-
- # Uncomment the admin/doc line below and add 'django.contrib.admindocs'
- # to INSTALLED_APPS to enable admin documentation:
- # (r'^admin/doc/', include('django.contrib.admindocs.urls')),
-
- # Uncomment the next line to enable the admin:
- **(r'^admin/', include(admin.site.urls)),**
- )
-
- (The bold lines are the ones that needed to be uncommented.)
-
-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:
-
-.. 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:: _images/admin01.png
- :alt: Django admin login screen
-
-Enter the admin site
-====================
-
-Now, try logging in. (You created a superuser account in the first part of this
-tutorial, remember? If you didn't create one or forgot the password you can
-:ref:`create another one <topics-auth-creating-superusers>`.) You should see
-the Django admin index page:
-
-.. image:: _images/admin02t.png
- :alt: Django admin index page
-
-You should see a few other types of editable content, including groups, users
-and sites. These are core features Django ships with by default.
-
-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. To do this, create a file called
-``admin.py`` in your ``polls`` directory, and edit it to look like this::
-
- from polls.models import Poll
- from django.contrib import admin
-
- admin.site.register(Poll)
-
-You'll need to restart the development server to see your changes. Normally,
-the server auto-reloads code every time you modify a file, but the action of
-creating a new file doesn't trigger the auto-reloading logic.
-
-Explore the free admin functionality
-====================================
-
-Now that we've registered ``Poll``, Django knows that it should be displayed on
-the admin index page:
-
-.. image:: _images/admin03t.png
- :alt: Django admin index page, now with polls displayed
-
-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:: _images/admin04t.png
- :alt: Polls change list page
-
-Click the "What's up?" poll to edit it:
-
-.. image:: _images/admin05t.png
- :alt: Editing form for poll object
-
-Things to note here:
-
- * 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.
-
-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:: _images/admin06t.png
- :alt: History page for poll object
-
-Customize the admin form
-========================
-
-Take a few minutes to marvel at all the code you didn't have to write. By
-registering the Poll model with ``admin.site.register(Poll)``, Django was able
-to construct a default form representation. Often, you'll want to customize how
-the admin form looks and works. You'll do this by telling Django the options
-you want when you register the object.
-
-Let's see how this works by re-ordering the fields on the edit form. Replace
-the ``admin.site.register(Poll)`` line with::
-
- class PollAdmin(admin.ModelAdmin):
- fields = ['pub_date', 'question']
-
- admin.site.register(Poll, PollAdmin)
-
-You'll follow this pattern -- create a model admin object, then pass it as the
-second argument to ``admin.site.register()`` -- any time you need to change the
-admin options for an object.
-
-This particular change above makes the "Publication date" come before the
-"Question" field:
-
-.. image:: _images/admin07.png
- :alt: Fields have been reordered
-
-This isn't impressive with only two fields, but for admin forms with dozens
-of fields, choosing an intuitive order is an important usability detail.
-
-And speaking of forms with dozens of fields, you might want to split the form
-up into fieldsets::
-
- class PollAdmin(admin.ModelAdmin):
- fieldsets = [
- (None, {'fields': ['question']}),
- ('Date information', {'fields': ['pub_date']}),
- ]
-
- admin.site.register(Poll, PollAdmin)
-
-The first element of each tuple in ``fieldsets`` is the title of the fieldset.
-Here's what our form looks like now:
-
-.. image:: _images/admin08t.png
- :alt: Form has fieldsets now
-
-You can assign arbitrary HTML classes to each fieldset. Django provides a
-``"collapse"`` class that displays a particular fieldset initially collapsed.
-This is useful when you have a long form that contains a number of fields that
-aren't commonly used::
-
- class PollAdmin(admin.ModelAdmin):
- fieldsets = [
- (None, {'fields': ['question']}),
- ('Date information', {'fields': ['pub_date'], 'classes': ['collapse']}),
- ]
-
-.. image:: _images/admin09.png
- :alt: Fieldset is initially collapsed
-
-Adding related objects
-======================
-
-OK, we have our Poll admin page. But a ``Poll`` has multiple ``Choices``, and
-the admin page doesn't display choices.
-
-Yet.
-
-There are two ways to solve this problem. The first is to register ``Choice``
-with the admin just as we did with ``Poll``. That's easy::
-
- from 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:: _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 :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
-Another," you'll get a popup window with the "Add poll" form. If you add a poll
-in that window and click "Save," Django will save the poll to the database and
-dynamically add it as the selected choice on the "Add choice" form you're
-looking at.
-
-But, really, this is an inefficient way of adding Choice objects to the system.
-It'd be better if you could add a bunch of Choices directly when you create the
-Poll object. Let's make that happen.
-
-Remove the ``register()`` call for the Choice model. Then, edit the ``Poll``
-registration code to read::
-
- class ChoiceInline(admin.StackedInline):
- model = Choice
- extra = 3
-
- class PollAdmin(admin.ModelAdmin):
- fieldsets = [
- (None, {'fields': ['question']}),
- ('Date information', {'fields': ['pub_date'], 'classes': ['collapse']}),
- ]
- inlines = [ChoiceInline]
-
- admin.site.register(Poll, PollAdmin)
-
-This tells Django: "Choice objects are edited on the Poll admin page. By
-default, provide enough fields for 3 choices."
-
-Load the "Add poll" page to see how that looks, you may need to restart your development server:
-
-.. image:: _images/admin11t.png
- :alt: Add poll page now has choices on it
-
-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 a
-tabular way of displaying inline related objects; you just need to change
-the ``ChoiceInline`` declaration to read::
-
- class ChoiceInline(admin.TabularInline):
- #...
-
-With that ``TabularInline`` (instead of ``StackedInline``), the
-related objects are displayed in a more compact, table-based format:
-
-.. image:: _images/admin12.png
- :alt: Add poll page now has more compact choices
-
-Customize the admin change list
-===============================
-
-Now that the Poll admin page is looking good, let's make some tweaks to the
-"change list" page -- the one that displays all the polls in the system.
-
-Here's what it looks like at this point:
-
-.. image:: _images/admin04t.png
- :alt: Polls change list page
-
-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
-``list_display`` admin option, which is a tuple of field names to display, as
-columns, on the change list page for the object::
-
- class PollAdmin(admin.ModelAdmin):
- # ...
- list_display = ('question', 'pub_date')
-
-Just for good measure, let's also include the ``was_published_today`` custom
-method from Tutorial 1::
-
- class PollAdmin(admin.ModelAdmin):
- # ...
- list_display = ('question', 'pub_date', 'was_published_today')
-
-Now the poll change list page looks like this:
-
-.. image:: _images/admin13t.png
- :alt: Polls change list page, updated
-
-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
-an arbitrary method is not supported. Also note that the column header for
-``was_published_today`` is, by default, the name of the method (with
-underscores replaced with spaces). But you can change that by giving that
-method (in ``models.py``) a ``short_description`` attribute::
-
- def was_published_today(self):
- return self.pub_date.date() == datetime.date.today()
- was_published_today.short_description = 'Published today?'
-
-Edit your admin.py file again and add an improvement to the Poll change list page: Filters. Add the
-following line to ``PollAdmin``::
-
- list_filter = ['pub_date']
-
-That adds a "Filter" sidebar that lets people filter the change list by the
-``pub_date`` field:
-
-.. image:: _images/admin14t.png
- :alt: Polls change list page, updated
-
-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
-filter options for DateTimeFields: "Any date," "Today," "Past 7 days,"
-"This month," "This year."
-
-This is shaping up well. Let's add some search capability::
-
- search_fields = ['question']
-
-That adds a search box at the top of the change list. When somebody enters
-search terms, Django will search the ``question`` field. You can use as many
-fields as you'd like -- although because it uses a ``LIKE`` query behind the
-scenes, keep it reasonable, to keep your database happy.
-
-Finally, because Poll objects have dates, it'd be convenient to be able to
-drill down by date. Add this line::
-
- date_hierarchy = 'pub_date'
-
-That adds hierarchical navigation, by date, to the top of the change list page.
-At top level, it displays all available years. Then it drills down to months
-and, ultimately, days.
-
-Now's also a good time to note that change lists give you free pagination. The
-default is to display 50 items per page. Change-list pagination, search boxes,
-filters, date-hierarchies and column-header-ordering all work together like you
-think they should.
-
-Customize the admin look and feel
-=================================
-
-Clearly, having "Django administration" at the top of each admin page is
-ridiculous. It's just placeholder text.
-
-That's easy to change, though, using Django's template system. The Django admin
-is powered by Django itself, and its interfaces use Django's own template
-system.
-
-Open your settings file (``mysite/settings.py``, remember) and look at the
-: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, :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.
- )
-
-Now copy the template ``admin/base_site.html`` from within the default Django
-admin template directory in the source code of Django itself
-(``django/contrib/admin/templates``) into an ``admin`` subdirectory of
-whichever directory you're using in :setting:`TEMPLATE_DIRS`. For example, if
-your :setting:`TEMPLATE_DIRS` includes ``"/home/my_username/mytemplates"``, as
-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.
-
-Then, just edit the file and replace the generic Django text with your own
-site's name as you see fit.
-
-This template file contains lots of text like ``{% block branding %}``
-and ``{{ title }}``. The ``{%`` and ``{{`` tags are part of Django's
-template language. When Django renders ``admin/base_site.html``, this
-template language will be evaluated to produce the final HTML page.
-Don't worry if you can't make any sense of the template right now --
-we'll delve into Django's templating language in Tutorial 3.
-
-Note that any of Django's default admin templates can be overridden. To
-override a template, just do the same thing you did with ``base_site.html`` --
-copy it from the default directory into your custom directory, and make
-changes.
-
-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
-==============================
-
-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 :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
-directory to your custom template directory.) Edit the file, and you'll see it
-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. Again,
-don't worry if you can't understand the template language -- we'll cover that
-in more detail in Tutorial 3.
-
-When you're comfortable with the admin site, read :doc:`part 3 of this tutorial
-</intro/tutorial03>` to start working on public poll views.
diff --git a/parts/django/docs/intro/tutorial03.txt b/parts/django/docs/intro/tutorial03.txt
deleted file mode 100644
index 0843d9e..0000000
--- a/parts/django/docs/intro/tutorial03.txt
+++ /dev/null
@@ -1,546 +0,0 @@
-=====================================
-Writing your first Django app, part 3
-=====================================
-
-This tutorial begins where :doc:`Tutorial 2 </intro/tutorial02>` left off. We're
-continuing the Web-poll application and will focus on creating the public
-interface -- "views."
-
-Philosophy
-==========
-
-A view is a "type" of Web page in your Django application that generally serves
-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.
-
-In Django, each view is represented by a simple Python function.
-
-Design your URLs
-================
-
-The first step of writing views is to design your URL structure. You do this by
-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
-: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])
-
-Django starts at the first regular expression and makes its way down the list,
-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
-: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 :class:`~django.http.HttpRequest` objects, see the
-:doc:`/ref/request-response`. For more details on URLconfs, see the
-:doc:`/topics/http/urls`.
-
-When you ran ``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 :setting:`ROOT_URLCONF` setting (in ``settings.py``) to
-point at that file::
-
- ROOT_URLCONF = 'mysite.urls'
-
-Time for an example. Edit ``mysite/urls.py`` so it looks like this::
-
- from django.conf.urls.defaults import *
-
- from django.contrib import admin
- admin.autodiscover()
-
- urlpatterns = patterns('',
- (r'^polls/$', 'polls.views.index'),
- (r'^polls/(?P<poll_id>\d+)/$', 'polls.views.detail'),
- (r'^polls/(?P<poll_id>\d+)/results/$', 'polls.views.results'),
- (r'^polls/(?P<poll_id>\d+)/vote/$', 'polls.views.vote'),
- (r'^admin/', include(admin.site.urls)),
- )
-
-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
-function ``detail()`` from ``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 parentheses
-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::
-
- (r'^polls/latest\.php$', 'polls.views.index'),
-
-But, don't do that. It's silly.
-
-Note that these regular expressions do not search GET and POST parameters, or
-the domain name. For example, in a request to ``http://www.example.com/myapp/``,
-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.
-
-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://docs.python.org/library/re.html
-
-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:
-
-.. code-block:: bash
-
- python manage.py runserver
-
-Now go to "http://localhost:8000/polls/" on your domain in your Web browser.
-You should get a pleasantly-colored error page with the following message::
-
- ViewDoesNotExist at /polls/
-
- Tried index in module polls.views. Error was: 'module'
- object has no attribute 'index'
-
-This error happened because you haven't written a function ``index()`` in the
-module ``polls/views.py``.
-
-Try "/polls/23/", "/polls/23/results/" and "/polls/23/vote/". The error
-messages tell you which view Django tried (and failed to find, because you
-haven't written any views yet).
-
-Time to write the first view. Open the file ``polls/views.py``
-and put the following Python code in it::
-
- from django.http import HttpResponse
-
- def index(request):
- return HttpResponse("Hello, world. You're at the poll index.")
-
-This is the simplest view possible. Go to "/polls/" in your browser, and you
-should see your text.
-
-Now lets add a few more views. These views are slightly different, because
-they take an argument (which, remember, is passed in from whatever was
-captured by the regular expression in the URLconf)::
-
- def detail(request, poll_id):
- return HttpResponse("You're looking at poll %s." % poll_id)
-
- def results(request, poll_id):
- return HttpResponse("You're looking at the results of poll %s." % poll_id)
-
- def vote(request, poll_id):
- return HttpResponse("You're voting on poll %s." % poll_id)
-
-Take a look in your browser, at "/polls/34/". It'll run the `detail()` method
-and display whatever ID you provide in the URL. Try "/polls/34/results/" and
-"/polls/34/vote/" too -- these will display the placeholder results and voting
-pages.
-
-Write views that actually do something
-======================================
-
-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 :class:`~django.http.HttpResponse`. Or an exception.
-
-Because it's convenient, let's use Django's own database API, which we covered
-in :doc:`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 polls.models import Poll
- from django.http import HttpResponse
-
- def index(request):
- latest_poll_list = Poll.objects.all().order_by('-pub_date')[:5]
- output = ', '.join([p.question for p in latest_poll_list])
- return HttpResponse(output)
-
-There's a problem here, though: The page's design is hard-coded in the view. If
-you want to change the way the page looks, you'll have to edit this Python code.
-So let's use Django's template system to separate the design from Python::
-
- from django.template import Context, loader
- from polls.models import Poll
- from django.http import HttpResponse
-
- def index(request):
- latest_poll_list = Poll.objects.all().order_by('-pub_date')[:5]
- t = loader.get_template('polls/index.html')
- c = Context({
- 'latest_poll_list': latest_poll_list,
- })
- 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.
-
-Reload the page. Now you'll see an error::
-
- TemplateDoesNotExist at /polls/
- 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 :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:
-
-.. code-block:: html+django
-
- {% if latest_poll_list %}
- <ul>
- {% for poll in latest_poll_list %}
- <li><a href="/polls/{{ poll.id }}/">{{ poll.question }}</a></li>
- {% endfor %}
- </ul>
- {% else %}
- <p>No polls are available.</p>
- {% endif %}
-
-Load the page in your Web browser, and you should see a bulleted-list
-containing the "What's up" poll from Tutorial 1. The link points to the poll's
-detail page.
-
-A shortcut: render_to_response()
---------------------------------
-
-It's a very common idiom to load a template, fill a context and return an
-: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 polls.models import Poll
-
- def index(request):
- 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
-:mod:`~django.template.loader`, :class:`~django.template.Context` and
-:class:`~django.http.HttpResponse`.
-
-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
-===========
-
-Now, let's tackle the poll detail view -- the page that displays the question
-for a given poll. Here's the view::
-
- from django.http import Http404
- # ...
- def detail(request, poll_id):
- try:
- p = Poll.objects.get(pk=poll_id)
- except Poll.DoesNotExist:
- raise Http404
- return render_to_response('polls/detail.html', {'poll': p})
-
-The new concept here: The view raises the :exc:`~django.http.Http404` exception
-if a poll with the requested ID doesn't exist.
-
-We'll discuss what you could put in that ``polls/detail.html`` template a bit
-later, but if you'd like to quickly get the above example working, just::
-
- {{ poll }}
-
-will get you started for now.
-
-A shortcut: get_object_or_404()
--------------------------------
-
-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
- # ...
- def detail(request, poll_id):
- p = get_object_or_404(Poll, pk=poll_id)
- return render_to_response('polls/detail.html', {'poll': p})
-
-The :func:`~django.shortcuts.get_object_or_404` function takes a Django model
-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 :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 :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 :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::
-
- from django.conf.urls.defaults import *
-
-That takes care of setting ``handler404`` in the current module. As you can see
-in ``django/conf/urls/defaults.py``, ``handler404`` is set to
-:func:`django.views.defaults.page_not_found` by default.
-
-Four more things to note about 404 views:
-
- * If :setting:`DEBUG` is set to ``True`` (in your settings module) then your
- 404 view will never be used (and thus the ``404.html`` template will never
- be rendered) because the traceback will be displayed instead.
-
- * The 404 view is also called if Django doesn't find a match after checking
- every regular expression in the URLconf.
-
- * If you don't define your own 404 view -- and simply use the default, which
- is recommended -- you still have one obligation: To create a ``404.html``
- template in the root of your template directory. The default 404 view will
- use that template for all 404 errors.
-
- * If :setting:`DEBUG` is set to ``False`` (in your settings module) and if
- you didn't create a ``404.html`` file, an ``Http500`` is raised instead.
- So remember to create a ``404.html``.
-
-Write a 500 (server error) view
-===============================
-
-Similarly, URLconfs may define a ``handler500``, which points to a view to call
-in case of server errors. Server errors happen when you have runtime errors in
-view code.
-
-Use the template system
-=======================
-
-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:
-
-.. code-block:: html+django
-
- <h1>{{ poll.question }}</h1>
- <ul>
- {% for choice in poll.choice_set.all %}
- <li>{{ choice.choice }}</li>
- {% endfor %}
- </ul>
-
-The template system uses dot-lookup syntax to access variable attributes. In
-the example of ``{{ poll.question }}``, first Django does a dictionary lookup
-on the object ``poll``. Failing that, it tries attribute lookup -- which works,
-in this case. If attribute lookup had failed, it would've tried calling the
-method ``question()`` on the poll object.
-
-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 :doc:`template guide </topics/templates>` for more about templates.
-
-Simplifying the URLconfs
-========================
-
-Take some time to play around with the views and template system. As you edit
-the URLconf, you may notice there's a fair bit of redundancy in it::
-
- urlpatterns = patterns('',
- (r'^polls/$', 'polls.views.index'),
- (r'^polls/(?P<poll_id>\d+)/$', 'polls.views.detail'),
- (r'^polls/(?P<poll_id>\d+)/results/$', 'polls.views.results'),
- (r'^polls/(?P<poll_id>\d+)/vote/$', 'polls.views.vote'),
- )
-
-Namely, ``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 :func:`~django.conf.urls.defaults.patterns`, like so::
-
- urlpatterns = patterns('polls.views',
- (r'^polls/$', 'index'),
- (r'^polls/(?P<poll_id>\d+)/$', 'detail'),
- (r'^polls/(?P<poll_id>\d+)/results/$', 'results'),
- (r'^polls/(?P<poll_id>\d+)/vote/$', 'vote'),
- )
-
-This is functionally identical to the previous formatting. It's just a bit
-tidier.
-
-Since you generally don't want the prefix for one app to be applied to every
-callback in your URLconf, you can concatenate multiple
-:func:`~django.conf.urls.defaults.patterns`. Your full ``mysite/urls.py`` might
-now look like this::
-
- from django.conf.urls.defaults import *
-
- from django.contrib import admin
- admin.autodiscover()
-
- urlpatterns = patterns('polls.views',
- (r'^polls/$', 'index'),
- (r'^polls/(?P<poll_id>\d+)/$', 'detail'),
- (r'^polls/(?P<poll_id>\d+)/results/$', 'results'),
- (r'^polls/(?P<poll_id>\d+)/vote/$', 'vote'),
- )
-
- urlpatterns += patterns('',
- (r'^admin/', include(admin.site.urls)),
- )
-
-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 transferable to another Django installation
-with minimal fuss.
-
-Our poll app is pretty decoupled at this point, thanks to the strict directory
-structure that ``python manage.py startapp`` created, but one part of it is
-coupled to the Django settings: The URLconf.
-
-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 ``polls/urls.py``. Then, change
-``mysite/urls.py`` to remove the poll-specific URLs and insert an
-:func:`~django.conf.urls.defaults.include`, leaving you with::
-
- # This also imports the include function
- from django.conf.urls.defaults import *
-
- from django.contrib import admin
- admin.autodiscover()
-
- urlpatterns = patterns('',
- (r'^polls/', include('polls.urls')),
- (r'^admin/', include(admin.site.urls)),
- )
-
-: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/'``
-
- * Then, Django will strip off the matching text (``"polls/"``) and send the
- remaining text -- ``"34/"`` -- to the 'polls.urls' URLconf for
- further processing.
-
-Now that we've decoupled that, we need to decouple the ``polls.urls``
-URLconf by removing the leading "polls/" from each line, and removing the
-lines registering the admin site. Your ``polls.urls`` file should now look like
-this::
-
- from django.conf.urls.defaults import *
-
- urlpatterns = patterns('polls.views',
- (r'^$', 'index'),
- (r'^(?P<poll_id>\d+)/$', 'detail'),
- (r'^(?P<poll_id>\d+)/results/$', 'results'),
- (r'^(?P<poll_id>\d+)/vote/$', 'vote'),
- )
-
-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 path root, and the app will still work.
-
-All the poll app cares about is its relative path, not its absolute path.
-
-When you're comfortable with writing views, read :doc:`part 4 of this tutorial
-</intro/tutorial04>` to learn about simple form processing and generic views.
diff --git a/parts/django/docs/intro/tutorial04.txt b/parts/django/docs/intro/tutorial04.txt
deleted file mode 100644
index dfbd82d..0000000
--- a/parts/django/docs/intro/tutorial04.txt
+++ /dev/null
@@ -1,346 +0,0 @@
-=====================================
-Writing your first Django app, part 4
-=====================================
-
-This tutorial begins where :doc:`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:
-
-.. code-block:: html+django
-
- <h1>{{ poll.question }}</h1>
-
- {% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}
-
- <form action="/polls/{{ poll.id }}/vote/" method="post">
- {% csrf_token %}
- {% for choice in poll.choice_set.all %}
- <input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}" />
- <label for="choice{{ forloop.counter }}">{{ choice.choice }}</label><br />
- {% endfor %}
- <input type="submit" value="Vote" />
- </form>
-
-A quick rundown:
-
- * The above template displays a radio button for each poll choice. The
- ``value`` of each radio button is the associated poll choice's ID. The
- ``name`` of each radio button is ``"choice"``. That means, when somebody
- selects one of the radio buttons and submits the form, it'll send the
- POST data ``choice=3``. This is HTML Forms 101.
-
- * We set the form's ``action`` to ``/polls/{{ poll.id }}/vote/``, and we
- set ``method="post"``. Using ``method="post"`` (as opposed to
- ``method="get"``) is very important, because the act of submitting this
- form will alter data server-side. Whenever you create a form that alters
- 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 :ttag:`for` tag has gone
- through its loop
-
- * Since we're creating a POST form (which can have the effect of modifying
- data), we need to worry about Cross Site Request Forgeries.
- Thankfully, you don't have to worry too hard, because Django comes with
- a very easy-to-use system for protecting against it. In short, all POST
- forms that are targeted at internal URLs should use the ``{% csrf_token %}``
- template tag.
-
-The ``{% csrf_token %}`` tag requires information from the request object, which
-is not normally accessible from within the template context. To fix this, a
-small adjustment needs to be made to the ``detail`` view, so that it looks like
-the following::
-
- from django.template import RequestContext
- # ...
- def detail(request, poll_id):
- p = get_object_or_404(Poll, pk=poll_id)
- return render_to_response('polls/detail.html', {'poll': p},
- context_instance=RequestContext(request))
-
-The details of how this works are explained in the documentation for
-:ref:`RequestContext <subclassing-context-requestcontext>`.
-
-Now, let's create a Django view that handles the submitted data and does
-something with it. Remember, in :doc:`Tutorial 3 </intro/tutorial03>`, we
-created a URLconf for the polls application that includes this line::
-
- (r'^(?P<poll_id>\d+)/vote/$', 'vote'),
-
-We also created a dummy implementation of the ``vote()`` function. Let's
-create a real version. Add the following to ``polls/views.py``::
-
- from django.shortcuts import get_object_or_404, render_to_response
- from django.http import HttpResponseRedirect, HttpResponse
- from django.core.urlresolvers import reverse
- from django.template import RequestContext
- from polls.models import Choice, Poll
- # ...
- def vote(request, poll_id):
- p = get_object_or_404(Poll, pk=poll_id)
- try:
- selected_choice = p.choice_set.get(pk=request.POST['choice'])
- except (KeyError, Choice.DoesNotExist):
- # Redisplay the poll voting form.
- return render_to_response('polls/detail.html', {
- 'poll': p,
- 'error_message': "You didn't select a choice.",
- }, context_instance=RequestContext(request))
- else:
- selected_choice.votes += 1
- selected_choice.save()
- # Always return an HttpResponseRedirect after successfully dealing
- # with POST data. This prevents data from being posted twice if a
- # user hits the Back button.
- return HttpResponseRedirect(reverse('polls.views.results', args=(p.id,)))
-
-This code includes a few things we haven't covered yet in this tutorial:
-
- * :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 :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 :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
- :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
- :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).
-
-As mentioned in Tutorial 3, ``request`` is a :class:`~django.http.HttpRequest`
-object. For more on :class:`~django.http.HttpRequest` objects, see the
-:doc:`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::
-
- def results(request, poll_id):
- 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 :doc:`Tutorial 3
-</intro/tutorial03>`. The only difference is the template name. We'll fix this
-redundancy later.
-
-Now, create a ``results.html`` template:
-
-.. code-block:: html+django
-
- <h1>{{ poll.question }}</h1>
-
- <ul>
- {% for choice in poll.choice_set.all %}
- <li>{{ choice.choice }} -- {{ choice.votes }} vote{{ choice.votes|pluralize }}</li>
- {% endfor %}
- </ul>
-
- <a href="/polls/{{ poll.id }}/">Vote again?</a>
-
-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.
-
-Use generic views: Less code is better
-======================================
-
-The ``detail()`` (from :doc:`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
-returning the rendered template. Because this is so common, Django provides a
-shortcut, called the "generic views" system.
-
-Generic views abstract common patterns to the point where you don't even need
-to write Python code to write an app.
-
-Let's convert our poll app to use the generic views system, so we can delete a
-bunch of our own code. We'll just have to take a few steps to make the
-conversion. We will:
-
- 1. Convert the URLconf.
-
- 2. Rename a few templates.
-
- 3. Delete some of the old, unneeded views.
-
- 4. Fix up URL handling for the new views.
-
-Read on for details.
-
-.. admonition:: Why the code-shuffle?
-
- Generally, when writing a Django app, you'll evaluate whether generic views
- are a good fit for your problem, and you'll use them from the beginning,
- rather than refactoring your code halfway through. But this tutorial
- intentionally has focused on writing the views "the hard way" until now, to
- focus on core concepts.
-
- 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
-tutorial so far::
-
- from django.conf.urls.defaults import *
-
- urlpatterns = patterns('polls.views',
- (r'^$', 'index'),
- (r'^(?P<poll_id>\d+)/$', 'detail'),
- (r'^(?P<poll_id>\d+)/results/$', 'results'),
- (r'^(?P<poll_id>\d+)/vote/$', 'vote'),
- )
-
-Change it like so::
-
- from django.conf.urls.defaults import *
- from polls.models import Poll
-
- info_dict = {
- 'queryset': Poll.objects.all(),
- }
-
- urlpatterns = patterns('',
- (r'^$', 'django.views.generic.list_detail.object_list', info_dict),
- (r'^(?P<object_id>\d+)/$', 'django.views.generic.list_detail.object_detail', info_dict),
- url(r'^(?P<object_id>\d+)/results/$', 'django.views.generic.list_detail.object_detail', dict(info_dict, template_name='polls/results.html'), 'poll_results'),
- (r'^(?P<poll_id>\d+)/vote/$', 'polls.views.vote'),
- )
-
-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 :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:: :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
- :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 :ref:`explains the lazy nature of QuerySet objects
- <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``.
-
-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 :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
-: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 :doc:`generic views documentation
-</topics/http/generic-views>`.
-
-Coming soon
-===========
-
-The tutorial ends here for the time being. Future installments of the tutorial
-will cover:
-
- * Advanced form processing
- * Using the RSS framework
- * Using the cache framework
- * Using the comments framework
- * Advanced admin features: Permissions
- * Advanced admin features: Custom JavaScript
-
-In the meantime, you might want to check out some pointers on :doc:`where to go
-from here </intro/whatsnext>`
diff --git a/parts/django/docs/intro/whatsnext.txt b/parts/django/docs/intro/whatsnext.txt
deleted file mode 100644
index 00c1654..0000000
--- a/parts/django/docs/intro/whatsnext.txt
+++ /dev/null
@@ -1,231 +0,0 @@
-=================
-What to read next
-=================
-
-So you've read all the :doc:`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 are 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 :doc:`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 :doc:`topic guides </topics/index>`, on the other hand, dive deep into
- individual parts of Django. There are complete guides to Django's
- :doc:`model system </topics/db/index>`, :doc:`template engine
- </topics/templates>`, :doc:`forms framework </topics/forms/index>`, and much
- more.
-
- This is probably where you'll want to spend 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 :doc:`how-to guides </howto/index>` that answer
- common "How do I ...?" questions. Here you'll find information about
- :doc:`generating PDFs with Django </howto/outputting-pdf>`, :doc:`writing
- custom template tags </howto/custom-template-tags>`, and more.
-
- Answers to really common questions can also be found in the :doc:`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 :doc:`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 :doc:`release notes </releases/index>`,
- :doc:`documentation of obsolete features </obsolete/index>`,
- :doc:`internals documentation </internals/index>` for those who want to add
- code to Django itself, and a :doc:`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://docs.djangoproject.com/en/dev/. 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 "max_length" in any
-Django document:
-
-.. code-block:: bash
-
- $ grep -r max_length /path/to/django/docs/
-
-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 Web site, 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``.
-
-.. note::
-
- Generation of the Django documentation will work with Sphinx version 0.6
- or newer, but we recommend going straight to Sphinx 1.0.2 or newer.
-
-__ 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 version X.Y", being X.Y the next release version (hence, the one
- being developed).
-
- * 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://docs.djangoproject.com/en/dev/