Reputation: 2939
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
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
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