Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use as a method in a ViewSet #32

Closed
donatogr opened this issue Oct 26, 2017 · 4 comments
Closed

Use as a method in a ViewSet #32

donatogr opened this issue Oct 26, 2017 · 4 comments

Comments

@donatogr
Copy link

Is it possibile to extend a standard DRF ViewSet with a method implementing a DRP PandasView?

@johanvdw
Copy link

johanvdw commented May 2, 2018

I'm also interested in this - or just a way to route extra actions when having a pandasviewset.
http://www.django-rest-framework.org/api-guide/routers/#routing-for-extra-actions

Eg what I'd like to do:

/api/buildings
/api/buildings/1/doors --> give a csv with all doors for a specific building

If I use a ModelViewSet (standard) this will work (returning json) when using

@action(detail=True)
def doors(self, request, pk):

inside the viewset. If I change the viewset to a PandasViewset, it seems these actions no longer work.

@johanvdw
Copy link

johanvdw commented May 2, 2018

Answering myself :

You can achieve this by using nested routing, with the drf-nested-routing package.

Register a nested router:

# urls.py
from rest_framework_nested import routers
building_router = routers.NestedSimpleRouter(building, 'building', lookup='building')
building_router.register('doors', views.DoorsViewset, base_name='building-doors')

And add a view:

class DoorsViewset(PandasViewSet):
    def get_queryset(self):
        print (self.kwargs)
        queryset = Doors.objects.filter(cable_id=self.kwargs['building_pk'])
        return queryset
    serializer_class = DoorsSerializer

@sheppard
Copy link
Member

Since most of the work happens in the serializer and renderers, you can also do this without PandasView/PandasViewSet. One option would be to override get_renderers() and explicitly set list_serializer_class, something like this:

class DoorSerializer(ModelSerializer):
    class Meta:
        list_serializer_class = PandasSerializer

class BuildingViewSet(ModelViewSet):
    def get_renderers(self):
        if self.action == 'doors':
             return [PandasCSVRenderer(), ...]
        else:
            return super().get_renderers()

    @action(detail=True)
    def doors(self, request, pk):
        queryset = Doors.objects.filter(...)
        return DoorSerializer(queryset, many=True).data

@sheppard
Copy link
Member

I added some more information to the README.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants