- August 25, 2011
- sphinx autodoc introspection docs documentation
- 5 (after 5 ratings)
In my sphinx documentation I really wanted a nice clean list of the fields on my Django models. The most obvious way of doing this is to add ":param blah:" tags to the docstring, but this takes a long time to implement and violates DRY principles when you already have lots of nice help text in the model definition. Another way is to use "#:" comments on attributes, but this approach suffers from the same issues as the previous method with the additional problem of Sphinx crapping out on file and custom fields.
So anyway, this is my solution. It uses the Sphinx docstring processing callback to intercept any objects that inherit from django.models.Model and creates a nice param list of all the fields on that model. Param descriptions come from the field's help text or verbose name if no help text is defined.
To use this, just add it to the end of your source/conf.py, filling out the project path as appropriate. You may be able to skip the Django environment setup lines if you're adding this to a Sphinx doc that already has Django models set up.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
THIS_DIR = os.path.dirname(__file__) PROJECT_DIR = os.path.join(THIS_DIR, 'relative/path/to/your/project/') sys.path.append(PROJECT_DIR) import inspect import settings from django.core.management import setup_environ from django.utils.html import strip_tags from django.utils,encoding import force_unicode setup_environ(settings) def process_docstring(app, what, name, obj, options, lines): # This causes import errors if left outside the function from django.db import models # Only look at objects that inherit from Django's base model class if inspect.isclass(obj) and issubclass(obj, models.Model): # Grab the field list from the meta class fields = obj._meta._fields() for field in fields: # Decode and strip any html out of the field's help text help_text = strip_tags(force_unicode(field.help_text)) # Decode and capitalize the verbose name, for use if there isn't # any help text verbose_name = force_unicode(field.verbose_name).capitalize() if help_text: # Add the model field to the end of the docstring as a param # using the help text as the description lines.append(u':param %s: %s' % (field.attname, help_text)) else: # Add the model field to the end of the docstring as a param # using the verbose name as the description lines.append(u':param %s: %s' % (field.attname, verbose_name)) # Add the field's type to the docstring lines.append(u':type %s: %s' % (field.attname, type(field).__name__)) # Return the extended docstring return lines def setup(app): # Register the docstring processor with sphinx app.connect('autodoc-process-docstring', process_docstring)