Home Ask Login Register

Developers Planet

Your answer is one click away!

delavnog February 2016

Mix View and ViewSet in a browsable api_root

I have a browsable API:

restaurant_router = DefaultRouter()
restaurant_router.register(r'rooms', RoomsViewSet)
restaurant_router.register(r'printers', PrintersViewSet)
restaurant_router.register(r'shifts', ShiftsViewSet)

urlpatterns = patterns('',
    url(r'^$', api_root),
    url(r'^restaurant/', include(restaurant_router.urls)),

In the api_root I can link to the named route:

def api_root(request, format=None):
    return Response({
        'restaurant': reverse('api_restaurants_restaurant', request=request, format=format),

Or I can use the browsable API generated by the DefaultRouter, as explained in the documentation:

The DefaultRouter class we're using also automatically creates the API root view for us, so we can now delete the api_root method from our views module.

What do I do if I want to mix ViewSets and normal Views, and show everything in the same API root? The DefaultRouter is only listing the ViewSets it controls.


Jkk.jonah February 2016

Doesn't look like there's a simple way to do that using the DefaultRouter, you'd have to build your own router. If it's any consolation the DefaultRouter's logic for generating the APIRoot view is fairly simple and you could probably easily roll your own, similar router based on the DefaultRouter class (e.g. Modify the ApiRoot class implementation to fetch additional URLs to include, you can do this any number of ways e.g. pass them into your Router's constructor):


Yevgeniy Shchemelev February 2016

You can define your views as ViewSets with only one method. So you can register it in router and it will be in one space with ViewSets.


knite February 2016

From http://www.django-rest-framework.org/api-guide/viewsets/:

A ViewSet class is simply a type of class-based View, that does not provide any method handlers such as .get() or .post(), and instead provides actions such as .list() and .create()

Which means we can extend your ViewSets:

def other_rooms_view(request):
    return Response(...)

class RoomsViewSet(ViewSet):

    def list(self, request):
        return other_rooms_view(request)

restaurant_router = DefaultRouter()
restaurant_router.register(r'rooms', RoomsViewSet)

Post Status

Asked in February 2016
Viewed 3,678 times
Voted 6
Answered 3 times


Leave an answer

Quote of the day: live life