summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorJason Pellerin <jpellerin@gmail.com>2006-09-04 02:20:26 +0000
committerJason Pellerin <jpellerin@gmail.com>2006-09-04 02:20:26 +0000
commitb17f250907351923f39f8a50b87a35b26d2ca307 (patch)
treebd0202dea501c6678a0b56b8e108194aab78468d /docs
parent5a58772a1ee470e2890d3c716ce4918555100a55 (diff)
[multi-db] Merge trunk to [3661]
git-svn-id: http://code.djangoproject.com/svn/django/branches/multiple-db-support@3712 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'docs')
-rw-r--r--docs/add_ons.txt9
-rw-r--r--docs/contributing.txt13
-rw-r--r--docs/django-admin.txt29
-rw-r--r--docs/faq.txt6
-rw-r--r--docs/settings.txt24
-rw-r--r--docs/sitemaps.txt320
-rw-r--r--docs/sites.txt11
-rw-r--r--docs/templates_python.txt19
-rw-r--r--docs/testing.txt303
9 files changed, 726 insertions, 8 deletions
diff --git a/docs/add_ons.txt b/docs/add_ons.txt
index 6507f3b139..a0377700d7 100644
--- a/docs/add_ons.txt
+++ b/docs/add_ons.txt
@@ -153,6 +153,15 @@ See the `sites documentation`_.
.. _sites documentation: http://www.djangoproject.com/documentation/sites/
+sitemaps
+========
+
+A framework for generating Google sitemap XML files.
+
+See the `sitemaps documentation`_.
+
+.. _sitemaps documentation: http://www.djangoproject.com/documentation/sitemaps/
+
syndication
===========
diff --git a/docs/contributing.txt b/docs/contributing.txt
index 9d116cac10..3d101c3241 100644
--- a/docs/contributing.txt
+++ b/docs/contributing.txt
@@ -168,6 +168,19 @@ Please follow these coding standards when writing code for inclusion in Django:
{{foo}}
+ * In Django views, the first parameter in a view function should be called
+ ``request``.
+
+ Do this::
+
+ def my_view(request, foo):
+ # ...
+
+ Don't do this::
+
+ def my_view(req, foo):
+ # ...
+
* Please don't put your name in the code. While we appreciate all
contributions to Django, our policy is not to publish individual
developer names in code -- for instance, at the top of Python modules.
diff --git a/docs/django-admin.txt b/docs/django-admin.txt
index eb7b2dccd6..672200c5e7 100644
--- a/docs/django-admin.txt
+++ b/docs/django-admin.txt
@@ -292,6 +292,13 @@ this command to install the default apps.
If you're installing the ``django.contrib.auth`` application, ``syncdb`` will
give you the option of creating a superuser immediately.
+test
+----
+
+Discover and run tests for all installed models. See `Testing Django applications`_ for more information.
+
+.. _testing django applications: ../testing/
+
validate
--------
@@ -338,6 +345,17 @@ setting the Python path for you.
Displays a help message that includes a terse list of all available actions and
options.
+--noinput
+---------
+
+Inform django-admin that the user should NOT be prompted for any input. Useful if
+the django-admin script will be executed as an unattended, automated script.
+
+--noreload
+----------
+
+Disable the use of the auto-reloader when running the development server.
+
--version
---------
@@ -348,6 +366,17 @@ Example output::
0.9.1
0.9.1 (SVN)
+--verbosity
+-----------
+
+Example usage::
+
+ django-admin.py syncdb --verbosity=2
+
+Verbosity determines the amount of notification and debug information that
+will be printed to the console. '0' is no output, '1' is normal output,
+and `2` is verbose output.
+
Extra niceties
==============
diff --git a/docs/faq.txt b/docs/faq.txt
index d39e203c76..204c69244d 100644
--- a/docs/faq.txt
+++ b/docs/faq.txt
@@ -103,10 +103,10 @@ Lawrence, Kansas, USA.
On IRC, Simon goes by ``SimonW``.
`Wilson Miner`_
- Wilson's design-fu makes us all look like rock stars. By day, he's an
+ Wilson's design-fu makes us all look like rock stars. By day, he's an
interactive designer for `Apple`. Don't ask him what he's working on, or
he'll have to kill you. He lives in San Francisco.
-
+
On IRC, Wilson goes by ``wilsonian``.
.. _`World Online`: http://code.djangoproject.com/wiki/WorldOnline
@@ -641,7 +641,7 @@ How can I get started contributing code to Django?
Thanks for asking! We've written an entire document devoted to this question.
It's titled `Contributing to Django`_.
-.. _Contributing do Django: http://www.djangoproject.com/documentation/contributing/
+.. _Contributing to Django: http://www.djangoproject.com/documentation/contributing/
I submitted a bug fix in the ticket system several weeks ago. Why are you ignoring my patch?
--------------------------------------------------------------------------------------------
diff --git a/docs/settings.txt b/docs/settings.txt
index d9df111155..b927b62ca7 100644
--- a/docs/settings.txt
+++ b/docs/settings.txt
@@ -754,6 +754,30 @@ misspelled) variables. See `How invalid variables are handled`_.
.. _How invalid variables are handled: http://www.djangoproject.com/documentation/templates_python/#how-invalid-variables-are-handled
+TEST_RUNNER
+-----------
+
+**New in Django development version**
+
+Default: ``'django.test.simple.run_tests'``
+
+The name of the method to use for starting the test suite. See
+`Testing Django Applications`_.
+
+.. _Testing Django Applications: ../testing/
+
+TEST_DATABASE_NAME
+------------------
+
+**New in Django development version**
+
+Default: ``None``
+
+The name of database to use when running the test suite. If a value of
+``None`` is specified, the test database will use the name ``'test_' + settings.DATABASE_NAME``. See `Testing Django Applications`_.
+
+.. _Testing Django Applications: ../testing/
+
TIME_FORMAT
-----------
diff --git a/docs/sitemaps.txt b/docs/sitemaps.txt
new file mode 100644
index 0000000000..fec65572f2
--- /dev/null
+++ b/docs/sitemaps.txt
@@ -0,0 +1,320 @@
+=====================
+The sitemap framework
+=====================
+
+**New in Django development version**.
+
+Django comes with a high-level sitemap-generating framework that makes
+creating `Google Sitemap`_ XML files easy.
+
+.. _Google Sitemap: http://www.google.com/webmasters/sitemaps/docs/en/protocol.html
+
+Overview
+========
+
+A sitemap is an XML file on your Web site that tells search-engine indexers how
+frequently your pages change and how "important" certain pages are in relation
+to other pages on your site. This information helps search engines index your
+site.
+
+The Django sitemap framework automates the creation of this XML file by letting
+you express this information in Python code.
+
+It works much like Django's `syndication framework`_. To create a sitemap, just
+write a ``Sitemap`` class and point to it in your URLconf_.
+
+.. _syndication framework: http://www.djangoproject.com/documentation/syndication/
+.. _URLconf: http://www.djangoproject.com/documentation/url_dispatch/
+
+Installation
+============
+
+To install the sitemap app, follow these steps:
+
+ 1. Add ``'django.contrib.sitemaps'`` to your INSTALLED_APPS_ setting.
+ 2. Make sure ``'django.template.loaders.app_directories.load_template_source'``
+ is in your TEMPLATE_LOADERS_ setting. It's in there by default, so
+ you'll only need to change this if you've changed that setting.
+ 3. Make sure you've installed the `sites framework`_.
+
+(Note: The sitemap application doesn't install any database tables. The only
+reason it needs to go into ``INSTALLED_APPS`` is so that the
+``load_template_source`` template loader can find the default templates.)
+
+.. _INSTALLED_APPS: http://www.djangoproject.com/documentation/settings/#installed-apps
+.. _TEMPLATE_LOADERS: http://www.djangoproject.com/documentation/settings/#template-loaders
+.. _sites framework: http://www.djangoproject.com/documentation/sites/
+
+Initialization
+==============
+
+To activate sitemap generation on your Django site, add this line to your
+URLconf_:
+
+ (r'^sitemap.xml$', 'django.contrib.sitemaps.views.sitemap', {'sitemaps': sitemaps})
+
+This tells Django to build a sitemap when a client accesses ``/sitemap.xml``.
+
+The name of the sitemap file is not important, but the location is. Google will
+only index links in your sitemap for the current URL level and below. For
+instance, if ``sitemap.xml`` lives in your root directory, it may reference any
+URL in your site. However, if your sitemap lives at ``/content/sitemap.xml``,
+it may only reference URLs that begin with ``/content/``.
+
+The sitemap view takes an extra, required argument: ``{'sitemaps': sitemaps}``.
+``sitemaps`` should be a dictionary that maps a short section label (e.g.,
+``blog`` or ``news``) to its ``Sitemap`` class (e.g., ``BlogSitemap`` or
+``NewsSitemap``). It may also map to an *instance* of a ``Sitemap`` class
+(e.g., ``BlogSitemap(some_var)``).
+
+.. _URLconf: http://www.djangoproject.com/documentation/url_dispatch/
+
+Sitemap classes
+===============
+
+A ``Sitemap`` class is a simple Python class that represents a "section" of
+entries in your sitemap. For example, one ``Sitemap`` class could represent all
+the entries of your weblog, while another could represent all of the events in
+your events calendar.
+
+In the simplest case, all these sections get lumped together into one
+``sitemap.xml``, but it's also possible to use the framework to generate a
+sitemap index that references individual sitemap files, one per section. (See
+`Creating a sitemap index`_ below.)
+
+``Sitemap`` classes must subclass ``django.contrib.sitemaps.Sitemap``. They can
+live anywhere in your codebase.
+
+A simple example
+================
+
+Let's assume you have a blog system, with an ``Entry`` model, and you want your
+sitemap to include all the links to your individual blog entries. Here's how
+your sitemap class might look::
+
+ from django.contrib.sitemaps import Sitemap
+ from mysite.blog.models import Entry
+
+ class BlogSitemap(Sitemap):
+ changefreq = "never"
+ priority = 0.5
+
+ def items(self):
+ return Entry.objects.filter(is_draft=False)
+
+ def lastmod(self, obj):
+ return obj.pub_date
+
+Note:
+
+ * ``changefreq`` and ``priority`` are class attributes corresponding to
+ ``<changefreq>`` and ``<priority>`` elements, respectively. They can be
+ made callable as functions, as ``lastmod`` was in the example.
+ * ``items()`` is simply a method that returns a list of objects. The objects
+ returned will get passed to any callable methods corresponding to a
+ sitemap property (``location``, ``lastmod``, ``changefreq``, and
+ ``priority``).
+ * ``lastmod`` should return a Python ``datetime`` object.
+ * There is no ``location`` method in this example, but you can provide it
+ in order to specify the URL for your object. By default, ``location()``
+ calls ``get_absolute_url()`` on each object and returns the result.
+
+Sitemap class reference
+=======================
+
+A ``Sitemap`` class can define the following methods/attributes:
+
+``items``
+---------
+
+**Required.** A method that returns a list of objects. The framework doesn't
+care what *type* of objects they are; all that matters is that these objects
+get passed to the ``location()``, ``lastmod()``, ``changefreq()`` and
+``priority()`` methods.
+
+``location``
+------------
+
+**Optional.** Either a method or attribute.
+
+If it's a method, it should return the absolute URL for a given object as
+returned by ``items()``.
+
+If it's an attribute, its value should be a string representing an absolute URL
+to use for *every* object returned by ``items()``.
+
+In both cases, "absolute URL" means a URL that doesn't include the protocol or
+domain. Examples:
+
+ * Good: ``'/foo/bar/'``
+ * Bad: ``'example.com/foo/bar/'``
+ * Bad: ``'http://example.com/foo/bar/'``
+
+If ``location`` isn't provided, the framework will call the
+``get_absolute_url()`` method on each object as returned by ``items()``.
+
+``lastmod``
+-----------
+
+**Optional.** Either a method or attribute.
+
+If it's a method, it should take one argument -- an object as returned by
+``items()`` -- and return that object's last-modified date/time, as a Python
+``datetime.datetime`` object.
+
+If it's an attribute, its value should be a Python ``datetime.datetime`` object
+representing the last-modified date/time for *every* object returned by
+``items()``.
+
+``changefreq``
+--------------
+
+**Optional.** Either a method or attribute.
+
+If it's a method, it should take one argument -- an object as returned by
+``items()`` -- and return that object's change frequency, as a Python string.
+
+If it's an attribute, its value should be a string representing the change
+frequency of *every* object returned by ``items()``.
+
+Possible values for ``changefreq``, whether you use a method or attribute, are:
+
+ * ``'always'``
+ * ``'hourly'``
+ * ``'daily'``
+ * ``'weekly'``
+ * ``'monthly'``
+ * ``'yearly'``
+ * ``'never'``
+
+``priority``
+------------
+
+**Optional.** Either a method or attribute.
+
+If it's a method, it should take one argument -- an object as returned by
+``items()`` -- and return that object's priority, as either a string or float.
+
+If it's an attribute, its value should be either a string or float representing
+the priority of *every* object returned by ``items()``.
+
+Example values for ``priority``: ``0.4``, ``1.0``. The default priority of a
+page is ``0.5``. See Google's documentation for more documentation.
+
+.. _Google's documentation: http://www.google.com/webmasters/sitemaps/docs/en/protocol.html
+
+Shortcuts
+=========
+
+The sitemap framework provides a couple convenience classes for common cases:
+
+``FlatPageSitemap``
+-------------------
+
+The ``django.contrib.sitemaps.FlatPageSitemap`` class looks at all flatpages_
+defined for the current ``SITE_ID`` (see the `sites documentation`_) and
+creates an entry in the sitemap. These entries include only the ``location``
+attribute -- not ``lastmod``, ``changefreq`` or ``priority``.
+
+.. _flatpages: http://www.djangoproject.com/documentation/flatpages/
+.. _sites documentation: http://www.djangoproject.com/documentation/sites/
+
+``GenericSitemap``
+------------------
+
+The ``GenericSitemap`` class works with any `generic views`_ you already have.
+To use it, create an instance, passing in the same ``info_dict`` you pass to
+the generic views. The only requirement is that the dictionary have a
+``queryset`` entry. It may also have a ``date_field`` entry that specifies a
+date field for objects retrieved from the ``queryset``. This will be used for
+the ``lastmod`` attribute in the generated sitemap. You may also pass
+``priority`` and ``changefreq`` keyword arguments to the ``GenericSitemap``
+constructor to specify these attributes for all URLs.
+
+.. _generic views: http://www.djangoproject.com/documentation/generic_views/
+
+Example
+-------
+
+Here's an example of a URLconf_ using both::
+
+ from django.conf.urls.defaults import *
+ from django.contrib.sitemaps import FlatPageSitemap, GenericSitemap
+ from mysite.blog.models import Entry
+
+ info_dict = {
+ 'queryset': Entry.objects.all(),
+ 'date_field': 'pub_date',
+ }
+
+ sitemaps = {
+ 'flatpages': FlatPageSitemap,
+ 'blog': GenericSitemap(info_dict, priority=0.6),
+ }
+
+ urlpatterns = patterns('',
+ # some generic view using info_dict
+ # ...
+
+ # the sitemap
+ (r'^sitemap.xml$', 'django.contrib.sitemaps.views.sitemap', {'sitemaps': sitemaps})
+ )
+
+.. _URLconf: http://www.djangoproject.com/documentation/url_dispatch/
+
+Creating a sitemap index
+========================
+
+The sitemap framework also has the ability to create a sitemap index that
+references individual sitemap files, one per each section defined in your
+``sitemaps`` dictionary. The only differences in usage are:
+
+ * You use two views in your URLconf: ``django.contrib.sitemaps.views.index``
+ and ``django.contrib.sitemaps.views.sitemap``.
+ * The ``django.contrib.sitemaps.views.sitemap`` view should take a
+ ``section`` keyword argument.
+
+Here is what the relevant URLconf lines would look like for the example above::
+
+ (r'^sitemap.xml$', 'django.contrib.sitemaps.views.index', {'sitemaps': sitemaps})
+ (r'^sitemap-(?P<section>.+).xml$', 'django.contrib.sitemaps.views.sitemap', {'sitemaps': sitemaps})
+
+This will automatically generate a ``sitemap.xml`` file that references
+both ``sitemap-flatpages.xml`` and ``sitemap-blog.xml``. The ``Sitemap``
+classes and the ``sitemaps`` dict don't change at all.
+
+Pinging Google
+==============
+
+You may want to "ping" Google when your sitemap changes, to let it know to
+reindex your site. The framework provides a function to do just that:
+``django.contrib.sitemaps.ping_google()``.
+
+``ping_google()`` takes an optional argument, ``sitemap_url``, which should be
+the absolute URL of your site's sitemap (e.g., ``'/sitemap.xml'``). If this
+argument isn't provided, ``ping_google()`` will attempt to figure out your
+sitemap by performing a reverse looking in your URLconf.
+
+``ping_google()`` raises the exception
+``django.contrib.sitemaps.SitemapNotFound`` if it cannot determine your sitemap
+URL.
+
+One useful way to call ``ping_google()`` is from a model's ``save()`` method::
+
+ from django.contrib.sitemaps import ping_google
+
+ class Entry(models.Model):
+ # ...
+ def save(self):
+ super(Entry, self).save()
+ try:
+ ping_google()
+ except Exception:
+ # Bare 'except' because we could get a variety
+ # of HTTP-related exceptions.
+ pass
+
+A more efficient solution, however, would be to call ``ping_google()`` from a
+cron script, or some other scheduled task. The function makes an HTTP request
+to Google's servers, so you may not want to introduce that network overhead
+each time you call ``save()``.
diff --git a/docs/sites.txt b/docs/sites.txt
index cca9f14f31..8c5f1fc64b 100644
--- a/docs/sites.txt
+++ b/docs/sites.txt
@@ -266,7 +266,18 @@ this::
If you attempt to use ``CurrentSiteManager`` and pass a field name that doesn't
exist, Django will raise a ``ValueError``.
+Finally, note that you'll probably want to keep a normal (non-site-specific)
+``Manager`` on your model, even if you use ``CurrentSiteManager``. As explained
+in the `manager documentation`_, if you define a manager manually, then Django
+won't create the automatic ``objects = models.Manager()`` manager for you.
+Also, note that certain parts of Django -- namely, the Django admin site and
+generic views -- use whichever manager is defined *first* in the model, so if
+you want your admin site to have access to all objects (not just site-specific
+ones), put ``objects = models.Manager()`` in your model, before you define
+``CurrentSiteManager``.
+
.. _manager: http://www.djangoproject.com/documentation/model_api/#managers
+.. _manager documentation: http://www.djangoproject.com/documentation/model_api/#managers
How Django uses the sites framework
===================================
diff --git a/docs/templates_python.txt b/docs/templates_python.txt
index 62069ffd6a..aa7fa901b0 100644
--- a/docs/templates_python.txt
+++ b/docs/templates_python.txt
@@ -300,13 +300,22 @@ If ``TEMPLATE_CONTEXT_PROCESSORS`` contains this processor, every
* ``user`` -- An ``auth.User`` instance representing the currently
logged-in user (or an ``AnonymousUser`` instance, if the client isn't
logged in). See the `user authentication docs`.
- * ``messages`` -- A list of ``auth.Message`` objects for the currently
- logged-in user.
- * ``perms`` -- An instance of ``django.core.context_processors.PermWrapper``,
- representing the permissions that the currently logged-in user has. See
- the `permissions docs`_.
+
+ * ``messages`` -- A list of messages (as strings) for the currently
+ logged-in user. Behind the scenes, this calls
+ ``request.user.get_and_delete_messages()`` for every request. That method
+ collects the user's messages and deletes them from the database.
+
+ Note that messages are set with ``user.add_message()``. See the
+ `message docs`_ for more.
+
+ * ``perms`` -- An instance of
+ ``django.core.context_processors.PermWrapper``, representing the
+ permissions that the currently logged-in user has. See the `permissions
+ docs`_.
.. _user authentication docs: http://www.djangoproject.com/documentation/authentication/#users
+.. _message docs: http://www.djangoproject.com/documentation/authentication/#messages
.. _permissions docs: http://www.djangoproject.com/documentation/authentication/#permissions
django.core.context_processors.debug
diff --git a/docs/testing.txt b/docs/testing.txt
new file mode 100644
index 0000000000..98ed1e8aec
--- /dev/null
+++ b/docs/testing.txt
@@ -0,0 +1,303 @@
+===========================
+Testing Django applications
+===========================
+
+**New in Django development version**.
+
+Automated testing is an extremely useful weapon in the bug-killing arsenal
+of the modern developer. When initially writing code, a test suite can be
+used to validate that code behaves as expected. When refactoring or
+modifying code, tests serve as a guide to ensure that behavior hasn't
+changed unexpectedly as a result of the refactor.
+
+Testing an web application is a complex task, as there are many
+components of a web application that must be validated and tested. To
+help you test your application, Django provides a test execution
+framework, and range of utilities that can be used to stimulate and
+inspect various facets of a web application.
+
+ This testing framework is currently under development, and may change
+ slightly before the next official Django release.
+
+ (That's *no* excuse not to write tests, though!)
+
+Writing tests
+=============
+
+Tests in Django come in two forms: doctests and unit tests.
+
+Writing doctests
+----------------
+
+Doctests use Python's standard doctest_ module, which searches for tests in
+your docstrings. Django's test runner looks for doctests in your ``models.py``
+file, and executes any that it finds. Django will also search for a file
+called ``tests.py`` in the application directory (i.e., the directory that
+holds ``models.py``). If a ``tests.py`` is found, it will also be searched
+for doctests.
+
+.. admonition:: What's a **docstring**?
+
+ A good explanation of docstrings (and some guidlines for using them
+ effectively) can be found in :PEP:`257`:
+
+ A docstring is a string literal that occurs as the first statement in
+ a module, function, class, or method definition. Such a docstring
+ becomes the ``__doc__`` special attribute of that object.
+
+ Since tests often make great documentation, doctest lets you put your
+ tests directly in your docstrings.
+
+You can put doctest strings on any object in your ``models.py``, but it's
+common practice to put application-level doctests in the module docstring, and
+model-level doctests in the docstring for each model.
+
+For example::
+
+ from django.db import model
+
+ class Animal(models.Model):
+ """
+ An animal that knows how to make noise
+
+ # Create some animals
+ >>> lion = Animal.objects.create(name="lion", sound="roar")
+ >>> cat = Animal.objects.create(name="cat", sound="meow")
+
+ # Make 'em speak
+ >>> lion.speak()
+ 'The lion says "roar"'
+ >>> cat.speak()
+ 'The cat says "meow"'
+ """
+
+ name = models.CharField(maxlength=20)
+ sound = models.CharField(maxlength=20)
+
+ def speak(self):
+ return 'The %s says "%s"' % (self.name, self.sound)
+
+When you `run your tests`_, the test utility will find this docstring, notice
+that portions of it look like an interactive Python session, and execute those
+lines while checking that the results match.
+
+For more details about how doctest works, see the `standard library
+documentation for doctest`_
+
+.. _doctest: http://docs.python.org/lib/module-doctest.html
+.. _standard library documentation for doctest: doctest_
+
+Writing unittests
+-----------------
+
+Like doctests, Django's unit tests use a standard library module: unittest_.
+As with doctests, Django's test runner looks for any unit test cases defined
+in ``models.py``, or in a ``tests.py`` file in your application directory.
+
+An equivalent unittest test case for the above example would look like::
+
+ import unittest
+ from myapp.models import Animal
+
+ class AnimalTestCase(unittest.TestCase):
+
+ def setUp(self):
+ self.lion = Animal.objects.create(name="lion", sound="roar")
+ self.cat = Animal.objects.create(name="cat", sound="meow")
+
+ def testSpeaking(self):
+ self.assertEquals(self.lion.speak(), 'The lion says "roar"')
+ self.assertEquals(self.cat.speak(), 'The cat says "meow"')
+
+When you `run your tests`_, the test utility will find all the test cases
+(that is, subclasses of ``unittest.TestCase``) in ``tests.py``, automatically
+build a test suite out of those test cases, and run that suite.
+
+For more details about ``unittest``, see the `standard library unittest
+documentation`_.
+
+.. _unittest: http://docs.python.org/lib/module-unittest.html
+.. _standard library unittest documentation: unittest_
+.. _run your tests: `Running tests`_
+
+Which should I use?
+-------------------
+
+Choosing a test framework is often contentious, so Django simply supports
+both of the standard Python test frameworks. Choosing one is up to each
+developer's personal tastes; each is supported equally. Since each test
+system has different benefits, the best approach is probably to use both
+together, picking the test system to match the type of tests you need to
+write.
+
+For developers new to testing, however, this choice can seem
+confusing, so here are a few key differences to help you decide weather
+doctests or unit tests are right for you.
+
+If you've been using Python for a while, ``doctest`` will probably feel more
+"pythonic". It's designed to make writing tests as easy as possible, so
+there's no overhead of writing classes or methods; you simply put tests in
+docstrings. This gives the added advantage of given your modules automatic
+documentation -- well-written doctests can kill both the documentation and the
+testing bird with a single stone.
+
+For developers just getting started with testing, using doctests will probably
+get you started faster.
+
+The ``unittest`` framework will probably feel very familiar to developers
+coming from Java. Since ``unittest`` is inspired by Java's JUnit, if
+you've used testing frameworks in other languages that similarly were
+inspired by JUnit, ``unittest`` should also feel pretty familiar.
+
+Since ``unittest`` is organized around classes and methods, if you need
+to write a bunch of tests that all share similar code, you can easily use
+subclass to abstract common tasks; this makes test code shorter and cleaner.
+There's also support for explicit setup and/or cleanup routines, which give
+you a high level of control over the environment your test cases run in.
+
+Again, remember that you can use both systems side-by-side (even in the same
+app). In the end, most projects will eventually end up using both; each shines
+in different circumstances.
+
+Testing utilities
+=================
+
+Test Client
+-----------
+
+A dummy browser; instruments the template generation process...
+
+Fixtures
+--------
+
+Feature still to come...
+
+
+Running tests
+=============
+
+Run your tests using your project's ``manage.py`` utility::
+
+ $ ./manage.py test
+
+If you only want to run tests for a particular application, add the
+application name to the command line. For example, if your
+``INSTALLED_APPS`` contains ``myproject.polls`` and ``myproject.animals``,
+but you only want to run the animals unit tests, run::
+
+ $ ./manage.py test animals
+
+When you run your tests, you'll see a bunch of text flow by as the test
+database is created and models are initialized. This test database is
+created from scratch every time you run your tests.
+
+By default, the test database gets its name by prepending ``test_`` to
+the database name specified by the ``DATABASE_NAME`` setting; all other
+database settings will the same as they would be for the project normally.
+If you wish to use a name other than the default for the test database,
+you can use the ``TEST_DATABASE_NAME`` setting to provide a name.
+
+Once the test database has been established, Django will run your tests.
+If everything goes well, at the end you'll see::
+
+ ----------------------------------------------------------------------
+ Ran 22 tests in 0.221s
+
+ OK
+
+If there are test failures, however, you'll see full details about what tests
+failed::
+
+ ======================================================================
+ FAIL: Doctest: ellington.core.throttle.models
+ ----------------------------------------------------------------------
+ Traceback (most recent call last):
+ File "/dev/django/test/doctest.py", line 2153, in runTest
+ raise self.failureException(self.format_failure(new.getvalue()))
+ AssertionError: Failed doctest test for myapp.models
+ File "/dev/myapp/models.py", line 0, in models
+
+ ----------------------------------------------------------------------
+ File "/dev/myapp/models.py", line 14, in myapp.models
+ Failed example:
+ throttle.check("actor A", "action one", limit=2, hours=1)
+ Expected:
+ True
+ Got:
+ False
+
+ ----------------------------------------------------------------------
+ Ran 2 tests in 0.048s
+
+ FAILED (failures=1)
+
+When the tests have all been executed, the test database is destroyed.
+
+Using a different testing framework
+===================================
+
+Doctest and Unittest are not the only Python testing frameworks. While
+Django doesn't provide explicit support these alternative frameworks,
+it does provide a mechanism to allow you to invoke tests constructed for
+an alternative framework as if they were normal Django tests.
+
+When you run ``./manage.py test``, Django looks at the ``TEST_RUNNER``
+setting to determine what to do. By default, ``TEST_RUNNER`` points to ``django.test.simple.run_tests``. This method defines the default Django
+testing behaviour. This behaviour involves:
+
+#. Creating the test database
+#. Running ``syncdb`` to install models and initial data into the test database
+#. Looking for Unit Tests and Doctests in ``models.py`` and ``tests.py`` file for each installed application
+#. Running the Unit Tests and Doctests that are found
+#. Destroying the test database.
+
+If you define your own test runner method and point ``TEST_RUNNER``
+at that method, Django will execute your test runner whenever you run
+``./manage.py test``. In this way, it is possible to use any test
+framework that can be executed from Python code.
+
+Defining a test runner
+----------------------
+By convention, a test runner should be called ``run_tests``; however, you
+can call it anything you want. The only requirement is that it accept two
+arguments:
+
+``run_tests(module_list, verbosity=1)``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The module list is the list of Python modules that contain the models to be
+tested. This is the same format returned by ``django.db.models.get_apps()``
+
+Verbosity determines the amount of notification and debug information that
+will be printed to the console; '0' is no output, '1' is normal output,
+and `2` is verbose output.
+
+Testing utilities
+-----------------
+
+To assist in the creation of your own test runner, Django provides
+a number of utility methods in the ``django.test.utils`` module.
+
+``create_test_db(verbosity=1, autoclobber=False)``:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Creates a new test database, and run ``syncdb`` against it.
+
+``verbosity`` has the same behaviour as in the test runner.
+
+``Autoclobber`` describes the behavior that will occur if a database with
+the same name as the test database is discovered. If ``autoclobber`` is False,
+the user will be asked to approve destroying the existing database. ``sys.exit``
+is called if the user does not approve. If autoclobber is ``True``, the database
+will be destroyed without consulting the user.
+
+``create_test_db()`` has the side effect of modifying
+``settings.DATABASE_NAME`` to match the name of the test database.
+
+``destroy_test_db(old_database_name, verbosity=1)``:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Destroys the database with the name ``settings.DATABASE_NAME`` matching,
+and restores the value of ``settings.DATABASE_NAME`` to the provided name.
+
+``verbosity`` has the same behaviour as in the test runner.