Docstring inheritance in Django REST framework

Tags: django

Django REST framework has a nice html-based interface that, for every one of your REST views, renders the docstring as an explanation at the top of the page.

Those views, they’re class based views, at least the ones I use. I’m making views that ought to be base views for other Django app’s API. We have a bunch of django apps for various data sources that can present their data in more or less the same way.

So… I’ve put a decent docstring, explaining the API, in my base views. Only… they didn’t show up in the interface for the subclasses. Apparently docstrings aren’t inherited by subclasses! So I asked a question on stack overflow and promptly got an answer.

What I ended up doing was modifying .get_description(), the method Django REST framework uses to grab and render the docstring:

import inspect  # Fancy standardlibrary Python internal inspection tool.

import docutils
from django.contrib.admindocs.utils import trim_docstring
from django.utils.safestring import mark_safe

....

class MyBaseAPIView(...):

    def get_description(self, html=False):
        description = self.__doc__  # Our docstring.
        if description is None:
            # Try and grab it from our parents.
            try:
                description = next(
                    cls.__doc__ for cls in inspect.getmro(type(self))
                    if cls.__doc__ is not None)
            except StopIteration:
                pass

        description = trim_docstring(description)
        if html:
            # Render with restructured text instead of markdown.
            parts = docutils.core.publish_parts(description,
                                                writer_name='html')
            return mark_safe(parts['fragment'])
        return description

This method is a customization of Django REST framework’s. There are two changes:

  • Our parent’s docstring is used if we don’t have one ourselves. This makes it easy to use a base class with proper documentation on which items to expect. The documentation is propagated to every API that uses the base class.

  • The docstring is parsed with restructuredtext syntax instead of markdown (markdown is preferred by Django REST framework).

Hurray for class based views! Because it is an object oriented structure, it is easy to overwrite parts of functionality. And easy to provide methods to actually do so (like the .get_description() I modified).

Photo & Video Sharing by SmugMug
 
vanrees.org logo

Reinout van Rees

My name is Reinout van Rees and I program in Python, I live in the Netherlands, I cycle recumbent bikes and I have a model railway.

Weblog feeds

Most of my website content is in my weblog. You can keep up to date by subscribing to the automatic feeds (for instance with Google reader):