9

How can I add a ListCreateAPIView to the router urls?

Normally I do like:

router = routers.DefaultRouter()
router.register(r'busses', BusViewSet)

but now I have:

class CarList(generics.ListCreateAPIView): ...

I added it to the urlpatterns for now:

urlpatterns = patterns('', 
url(r'^carts/', CarList.as_view(model=Car), name='cars'),

and I would like to add this Cars-view (which is working as intended if I call the url manually!) to the router, so it's in the overview page!

So: It works as it is, but I have to manually enter the url, it's not in the overview-page of the API.

1 Answers1

6

The reason is why a ViewSet classes work with a router is a GenericViewSet which has a ViewSetMixin in a bases.
ViewSetMixin override as_view() method so that it takes an actions keyword that performs the binding of HTTP methods to actions on the Resource and router can build a map for action-method.
You can solve it by simple adding that mixin in a class bases:

from rest_framework.viewsets import ViewSetMixin

class CarList(ViewSetMixin, generics.ListCreateAPIView)
    ....

But it is not clear solution because ListCreateAPIView and ModelViewSet it is just an empty classes with a bunch of mixins in a bases. So you always can build you own ViewSet with a methods you need.
For example, here the code of ListCreateAPIView:

class ListCreateAPIView(mixins.ListModelMixin,
                    mixins.CreateModelMixin,
                    GenericAPIView):

    def get(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        return self.create(request, *args, **kwargs)

And here the ModelViewSet:

class ModelViewSet(mixins.CreateModelMixin,
               mixins.RetrieveModelMixin,
               mixins.UpdateModelMixin,
               mixins.DestroyModelMixin,
               mixins.ListModelMixin,
               GenericViewSet):

    pass

Notice a same mixins ListModelMixin and CreateModelMixin there is only difference in GenericViewSet and GenericAPIView.
GenericAPIView use method names and call an actions inside them. GenericViewSet instead use actions and map them to methods.
Here the ViewSet with methods you need:

class ListCreateViewSet(mixins.ListModelMixin,
                    mixins.CreateModelMixin,
                    GenericViewSet):   

    queryset_class = ..
    serializer_class = ..

Now it will work with a router and you can override list and create methods if you need a special behavior.

Ivan Semochkin
  • 8,649
  • 3
  • 43
  • 75