How the Django documentation works

... and how to contribute.

Django’s documentation uses the Sphinx documentation system, which in turn is based on docutils. The basic idea is that lightly-formatted plain-text documentation is transformed into HTML, PDF, and any other output format.

To actually build the documentation locally, you’ll currently need to install Sphinx – easy_install Sphinx should do the trick.


Building the Django documentation requires Sphinx 1.0.2 or newer. Sphinx also requires the Pygments library for syntax highlighting; building the Django documentation requires Pygments 1.1 or newer (a new-enough version should automatically be installed along with Sphinx).

Then, building the HTML is easy; just make html from the docs directory.

To get started contributing, you’ll want to read the reStructuredText Primer. After that, you’ll want to read about the Sphinx-specific markup that’s used to manage metadata, indexing, and cross-references.

The main thing to keep in mind as you write and edit docs is that the more semantic markup you can add the better. So:

Add ``django.contrib.auth`` to your ``INSTALLED_APPS``...

Isn't nearly as helpful as:

Add :mod:`django.contrib.auth` to your :setting:`INSTALLED_APPS`...

This is because Sphinx will generate proper links for the latter, which greatly helps readers. There's basically no limit to the amount of useful markup you can add.

Django-specific markup

Besides the Sphinx built-in markup, Django's docs defines some extra description units:

  • Settings:

    .. setting:: INSTALLED_APPS

    To link to a setting, use :setting:`INSTALLED_APPS`.

  • Template tags:

    .. templatetag:: regroup

    To link, use :ttag:`regroup`.

  • Template filters:

    .. templatefilter:: linebreaksbr

    To link, use :tfilter:`linebreaksbr`.

  • Field lookups (i.e. Foo.objects.filter(bar__exact=whatever)):

    .. fieldlookup:: exact

    To link, use :lookup:`exact`.

  • django-admin commands:

    .. django-admin:: syncdb

    To link, use :djadmin:`syncdb`.

  • django-admin command-line options:

    .. django-admin-option:: --traceback

    To link, use :djadminopt:`--traceback`.

An example

For a quick example of how it all fits together, consider this hypothetical example:

  • First, the ref/settings.txt document could have an overall layout like this:

    .. _available-settings:
    Available settings
    .. _deprecated-settings:
    Deprecated settings
  • Next, the topics/settings.txt document could contain something like this:

    You can access a :ref:`listing of all available settings
    <available-settings>`. For a list of deprecated settings see
    You can find both in the :doc:`settings reference document </ref/settings>`.

    We use the Sphinx doc cross reference element when we want to link to another document as a whole and the ref element when we want to link to an arbitrary location in a document.

  • Next, notice how the settings are annotated:

    .. setting:: ADMIN_FOR
    Default: ``()`` (Empty tuple)
    Used for admin-site settings modules, this should be a tuple of settings
    modules (in the format ``''``) for which this site is an
    The admin site uses this in its automatically-introspected
    documentation of models, views and template tags.

    This marks up the following header as the "canonical" target for the setting ADMIN_FOR This means any time I talk about ADMIN_FOR, I can reference it using :setting:`ADMIN_FOR`.

That's basically how everything fits together.


The work is mostly done, but here's what's left, in rough order of priority.

  • Most of the various index.txt documents have very short or even non-existent intro text. Each of those documents needs a good short intro the content below that point.

  • The glossary is very perfunctory. It needs to be filled out.

  • Add more metadata targets: there's lots of places that look like:


    ... these should be:

    .. method:: File.close()

    That is, use metadata instead of titles.

  • Add more links -- nearly everything that's an inline code literal right now can probably be turned into a xref.

    See the file in _ext -- it's a shell script to help do this work.

    This will probably be a continuing, never-ending project.

  • Add info field lists where appropriate.

  • Add .. code-block:: <lang> to literal blocks so that they get highlighted.


Some hints for making things look/read better:

  • Whenever possible, use links. So, use :setting:`ADMIN_FOR` instead of ``ADMIN_FOR``.

  • Some directives (.. setting::, for one) are prefix-style directives; they go before the unit they're describing. These are known as "crossref" directives. Others (.. class::, e.g.) generate their own markup; these should go inside the section they're describing. These are called "description units".

    You can tell which are which by looking at in _ext/; it registers roles as one of the other.

  • When referring to classes/functions/modules, etc., you'll want to use the fully-qualified name of the target (:class:`django.contrib.contenttypes.models.ContentType`).

    Since this doesn't look all that awesome in the output -- it shows the entire path to the object -- you can prefix the target with a ~ (that's a tilde) to get just the "last bit" of that path. So :class:`~django.contrib.contenttypes.models.ContentType` will just display a link with the title "ContentType".