orange1
orange1

Reputation: 2939

Django REST Framework - can't override list in ListAPIView

I am using Django REST Framework to create an endpoint that will produce a PDF document. The PDF document will have information that corresponds to a particular Department. I have two desired functionalities -- to be able to download a PDF document, and to be able to preview the document within the browser.

Since the PDF document changes over time based on data that is added to the app, the document needs to be generated in real time when it is requested. As a first step, I'm trying to have the document be generated in a remote file storage location when the following endpoint is hit by a GET request:

departments/<department_pk>/result/preview

Since my endpoint should only take GET requests, I am using a ListAPIView. I'm trying to override the list method so that my custom document generation logic is executed, but it looks like the method is never called. How can I have some custom document generation logic be inserted into my endpoint, so that it is executed when the endpoint is hit by a GET request?

api/urls.py

url(r'^departments/(?P<department_pk>[0-9]+)/result/preview',
    include(result_document_urls.result_document_preview_router.urls,

document_app/urls.py

result_document_preview_router = routers.DefaultRouter()

result_document_preview_router.register(r'^', ResultDocumentDetailView.as_view(),
    base_name='Department')

document_app/views.py

class ResultDocumentDetailView(generics.ListAPIView):

    queryset = Department.objects.all()
    lookup_field = 'department_pk'
    lookup_url_kwarg = 'department_pk'

    def list(self, request, department_pk):
        queryset = self.get_queryset()
        import ipdb; ipdb.set_trace() # this break point is never hit
        department = get_object_or_404(queryset, department_pk=department_pk)
        ...generate document logic...
        return Response(status=status.HTTP_200_OK)

Upvotes: 2

Views: 5782

Answers (2)

Rahul Gupta
Rahul Gupta

Reputation: 47846

In your document_app/urls.py, you are incorrectly passing ResultDocumentDetailView as an argument instead of a viewset.

Router while registering accepts a ViewSet instead of an APIView.

There are two mandatory arguments to the register() method:

prefix - The URL prefix to use for this set of routes.
viewset - The viewset class.

Also, since you are only interested in the retrieve method, you can just create a ResultDocumentRetrieveView and add its corresponding url to your urls.py without the need of creating a ResultDocument router. (Routers are generally used when you want to handle both list and detail requests.)

class ResultDocumentRetrieveView(generics.RetrieveAPIView):

    queryset = Department.objects.all()
    lookup_field = 'department_pk'
    lookup_url_kwarg = 'department_pk'

    def retrieve(self, request, department_pk):
        department = self.get_object()
        ...generate document logic...    
        return Response(status=status.HTTP_200_OK)

urls.py

url(r'^departments/(?P<department_pk>[0-9]+)/result/preview', ResultDocumentRetrieveView.as_view())

Upvotes: 1

anjaneyulubatta505
anjaneyulubatta505

Reputation: 11685

replace list method with below code, I think it will work

class ResultDocumentDetailView(generics.ListAPIView):

    queryset = Department.objects.all()
    lookup_field = 'department_pk'
    lookup_url_kwarg = 'department_pk'

    def list(self, request, *args, **kwargs):
        queryset = self.get_queryset()
        import ipdb; ipdb.set_trace() # this break point is never hit
        department = get_object_or_404(
            queryset, department_pk=kwargs.get('department_pk')
        )

        ...generate document logic...

        return Response(status=status.HTTP_200_OK)

for more reference see the overrinding method "list"

https://github.com/tomchristie/django-rest-framework/blob/master/rest_framework/mixins.py#L35

Upvotes: 2

Related Questions