【问题标题】:Django REST Framework - can't override list in ListAPIViewDjango REST Framework - 无法覆盖 ListAPIView 中的列表
【发布时间】:2016-06-17 10:48:05
【问题描述】:

我正在使用 Django REST Framework 创建一个将生成 PDF 文档的端点。 PDF 文档将包含与特定Department 对应的信息。我有两个想要的功能——能够下载 PDF 文档,以及能够在浏览器中预览文档。

由于 PDF 文档会根据添加到应用程序的数据随时间变化,因此需要在请求时实时生成文档。作为第一步,当GET 请求命中以下端点时,我尝试在远程文件存储位置生成文档:

departments/<department_pk>/result/preview

由于我的端点应该只接受GET 请求,所以我使用的是ListAPIView。我正在尝试覆盖 list 方法,以便执行我的自定义文档生成逻辑,但看起来该方法从未被调用。如何将一些自定义文档生成逻辑插入到我的端点中,以便在端点被GET 请求命中时执行?

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)

【问题讨论】:

  • 在我看来你应该使用RetrieveAPIViewListAPIView 用于返回集合。 Retrieve... 用于获取一个实例。话虽如此,我不明白为什么无论如何都不会调用list
  • @louis 是的,对我来说也没有任何意义。我最初使用RetrieveAPIView,但后来切换到ListAPIView,因为我不确定是否需要在RetrieveAPIView 的URL 末尾添加pk,也许这就是它不起作用的原因。跨度>

标签: python django rest django-rest-framework


【解决方案1】:

用下面的代码替换列表方法,我认为它会工作

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)

更多参考参见覆盖方法“list”

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

【讨论】:

  • 嗯,不太清楚这与我给出的示例代码有何不同?减去缩进,这似乎是关闭的。我错过了什么吗?谢谢。
  • @orange1 您没有正确定义方法“list”。正确的定义是 " def list(self, request, *args, **kwargs): " 。你试过了吗 ?它会起作用的。
【解决方案2】:

在您的document_app/urls.py 中,您错误地将ResultDocumentDetailView 作为参数而不是视图集传递。

路由器while registering 接受ViewSet 而不是APIView

register() 方法有两个强制参数:

prefix - 用于这组路由的 URL 前缀。
viewset - viewset 类

另外,由于您只对retrieve 方法感兴趣,您可以只创建一个ResultDocumentRetrieveView 并将其对应的url 添加到您的urls.py,而无需创建ResultDocument 路由器。 (当你想同时处理listdetail 请求时,通常使用路由器。)

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())

【讨论】:

    猜你喜欢
    • 2016-05-07
    • 2013-05-21
    • 1970-01-01
    • 1970-01-01
    • 2015-09-25
    • 2021-04-29
    • 1970-01-01
    • 1970-01-01
    • 2017-11-23
    相关资源
    最近更新 更多