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:
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).