Pergunta

In django RestFramework, is there any "official" way to generate the documentation for the "Api Root" ?

After looking at the RestFramework's source code, I've found a work around by subclassing the DefaultRouter:

from rest_framework import routers

class MyRouter(routers.DefaultRouter):
    def get_api_root_view(self):
        api_root_view = super(MyRouter, self).get_api_root_view()
        ApiRootClass = api_root_view.cls

        class MyAPIRoot(ApiRootClass):
            """My API Root documentation"""
            pass

        return MyAPIRoot.as_view()

router = MyRouter()

Is there a cleaner or better way ?

Foi útil?

Solução 3

I'm new to this but I found you can use a SimpleRouter instead of a DefaultRouter to specify your own APIRoot.

in urls.py in your api module

from django.conf.urls import patterns, url, include
from rest_framework.routers import SimpleRouter
router = SimpleRouter()

urlpatterns = patterns('api.views',
    url(r'^$', views.APIRoot.as_view()),
    url(r'', include(router.urls)),
)

Then specify the documentation in the class comment

from rest_framework import generics

class APIRoot(generics.GenericAPIView):
    """
    My API documentation
    """

Outras dicas

I found a solution through experimentation.

I prefer it to the other solutions in this thread as it requires less code and allows you to customise the API title, as well as the documentation for the API root.

from rest_framework import routers

class ThisWillBeTheApiTitleView(routers.APIRootView):
    """
    This appears where the docstring goes!
    """
    pass


class DocumentedRouter(routers.DefaultRouter):
    APIRootView = ThisWillBeTheApiTitleView


router = DocumentedRouter()
router.register(r'items', ItemsViewSet)

This renders as below:

Demonstration

If anyone wants an inline style

   router = DefaultRouter()

   router.get_api_root_view().cls.__name__ = "Root API name"
   router.get_api_root_view().cls.__doc__ = "Your Description"

It's kind of difficult to override the APIRoot class. The most simple way to achieve what you want is probably to modify the __doc__ attribute of the APIRootClass at runtime in your urls.py:

class Router(routers.DefaultRouter):
    def get_api_root_view(self, api_urls=None):
        root_view = super(Router, self).get_api_root_view(api_urls=api_urls)
        root_view.cls.__doc__ = "Place your documentation here"
        return root_view

router = Router()
router.register(...)

urlpatterns = [
    url(r'^', include(router.urls)),
]

Thanks to frost-nzcr4's comment above, I found a nice way to do this:


from rest_framework import routers
from django.utils.safestring import mark_safe


class MyAPIRootView(routers.APIRootView):
    """
    Controls appearance of the API root view
    """

    def get_view_name(self) -> str:
        return "My API"

    def get_view_description(self, html=False) -> str:
        text = "My REST API"
        if html:
            return mark_safe(f"<p>{text}</p>")
        else:
            return text


class MyRouter(routers.DefaultRouter):
    APIRootView = MyAPIRootView

Then use this router in your urls.py:

router = MyRouter()
@api_view(['GET'])
def api_root(request, format=None):
    return Response({
        'users': reverse('user-list', request=request, format=format),
        'snippets': reverse('snippet-list', request=request, format=format)
    })
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top