Skip to content

Instantly share code, notes, and snippets.

@wengole
Forked from ferrouswheel/conf.py
Last active October 13, 2015 13:31
Show Gist options
  • Save wengole/ce4a0d35b63abb64b965 to your computer and use it in GitHub Desktop.
Save wengole/ce4a0d35b63abb64b965 to your computer and use it in GitHub Desktop.
Sphinx add-on to annotate Django models based on fields and their help_text.Based on https://djangosnippets.org/snippets/2533/ - but adds ForeignKey resolution, and ensure field.rel.to is an actual model instead of a string.
import sys, os
local_path = lambda path: os.path.join(os.path.dirname(__file__), path)
os.environ['DJANGO_SETTINGS_MODULE'] = 'PROJECTNAME.settings'
sys.path.append(local_path('..'))
... # Rest of conf.py goes here
def setup(app):
from django_sphinx import process_docstring
# Register the docstring processor with sphinx
app.connect('autodoc-process-docstring', process_docstring)
import inspect
from django.utils.html import strip_tags
from django.utils.encoding import force_text
def process_docstring(app, what, name, obj, options, lines):
# This causes import errors if left outside the function
from django.db import models
# Make sure we have loaded models, otherwise related fields may end up
# as strings
models.get_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 = [x[0] for x in obj._meta.get_concrete_fields_with_model()]
for field in fields:
# Decode and strip any html out of the field's help text
help_text = strip_tags(force_text(field.help_text))
# Decode and capitalize the verbose name, for use if there isn't
# any help text
verbose_name = force_text(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
if isinstance(field, models.ForeignKey):
to = field.rel.to
lines.append(u':type %s: %s to :class:`~%s.%s`' % (
field.attname, type(field).__name__, to.__module__,
to.__name__))
else:
lines.append(
u':type %s: %s' % (field.attname, type(field).__name__))
# Return the extended docstring
return lines
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment