使用xhtml2pdf转HTML表格为PDF时遇404错误求助
解决Django REST Framework生成PDF时的404错误
嘿,我帮你分析下这个404问题的原因,以及怎么修复:
问题根源
你的代码里有几个关键问题导致了404错误:
- 路由注册错误:
router.register(r'^pdf', GeneratePdf)里的^是多余的,DefaultRouter会自动处理URL的起始匹配,加了这个符号会让路由规则变成^/pdf/,导致无法正确匹配请求URL。 - 视图方法重写错误:
ReadOnlyModelViewSet已经封装了list(获取列表)和retrieve(获取单个资源)两个GET动作,直接重写get方法会破坏框架原有的路由映射逻辑,导致请求找不到对应的处理函数。 - 参数传递错误:
get方法的参数里的queryset是无效的,视图方法不会直接接收queryset作为参数,应该通过self.get_queryset()来获取数据库查询集。
修复方案
下面给你两种可行的修复方式,你可以根据需求选择:
方案一:改用APIView(推荐,适合单一PDF生成功能)
如果你的视图只需要生成PDF这一个功能,没必要用ReadOnlyModelViewSet,直接用APIView更简洁:
views.py
from django.http import HttpResponse from rest_framework.views import APIView from .models import DirectoryTb from .serializers import DirectoryTbSerializer # 假设这是你定义的PDF生成函数 def render_to_pdf(template_name, context): # 你的PDF生成逻辑(比如用xhtml2pdf的逻辑) pass class GeneratePdf(APIView): def get(self, request, *args, **kwargs): # 获取数据库数据 queryset = DirectoryTb.objects.all() # 序列化数据传给模板 serializer = DirectoryTbSerializer(queryset, many=True) # 生成PDF pdf = render_to_pdf('directory.html', {'data': serializer.data}) # 返回PDF响应 return HttpResponse(pdf, content_type='application/pdf')
urls.py
from django.urls import path from .views import GeneratePdf urlpatterns = [ path('pdf/', GeneratePdf.as_view(), name='generate-pdf'), ]
现在访问/pdf/就能正常获取PDF了。
方案二:保留ReadOnlyModelViewSet,自定义action
如果你需要保留ReadOnlyModelViewSet的其他功能(比如列表、详情接口),可以通过自定义action来添加PDF生成功能:
views.py
from django.http import HttpResponse from rest_framework import viewsets from rest_framework.decorators import action from .models import DirectoryTb from .serializers import DirectoryTbSerializer def render_to_pdf(template_name, context): # 你的PDF生成逻辑 pass class GeneratePdf(viewsets.ReadOnlyModelViewSet): queryset = DirectoryTb.objects.all() serializer_class = DirectoryTbSerializer # 自定义一个无详情的action(detail=False表示不需要pk参数) @action(detail=False, methods=['get']) def generate(self, request): queryset = self.get_queryset() serializer = self.get_serializer(queryset, many=True) pdf = render_to_pdf('directory.html', {'data': serializer.data}) return HttpResponse(pdf, content_type='application/pdf')
urls.py
from rest_framework.routers import DefaultRouter from .views import GeneratePdf router = DefaultRouter() # 去掉多余的^符号 router.register(r'pdf', GeneratePdf) urlpatterns = router.urls
此时访问/pdf/generate/就能获取生成的PDF了,同时原有的/pdf/(列表)和/pdf/<pk>/(详情)接口依然可用。
额外注意点
- 确保你的
render_to_pdf函数正确接收上下文数据,模板directory.html能正确渲染这些数据。 - 测试时可以先打印
serializer.data确认数据是否正确获取,排除数据为空的问题。
内容的提问来源于stack exchange,提问作者Eak321
相关产品推荐
相关产品推荐

