You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Django REST Framework创建JSON与CSV API遇问题求助

解决JSON API浏览器访问问题与CSV导出API实现方案

嘿,看来你在Django REST Framework里搞两个API遇到了点小麻烦——JSON API能被Ajax调用但浏览器直接访问出问题,CSV导出API也卡壳了。我来帮你一步步捋清楚:

一、先搞定JSON API的浏览器访问问题

你说Ajax能正常拿数据,但浏览器直接打开API地址不行,大概率是渲染器配置在搞鬼。ModelViewSet默认自带BrowsableAPIRenderer,浏览器访问时会优先返回那种带表单的可浏览HTML页面,而不是纯JSON。如果想让浏览器直接访问也返回JSON,你可以给视图集指定只保留JSON渲染器:

from rest_framework.renderers import JSONRenderer

class VideoViewSet(viewsets.ModelViewSet):
    queryset = DatamsVideos.objects.all()
    serializer_class = VideosSerializer
    # 强制只返回JSON格式,浏览器访问也会直接拿到JSON
    renderer_classes = [JSONRenderer]
    # 你的CSVParser可以保留,用来处理客户端发过来的CSV请求(如果有需要的话)
    parser_classes = (CSVParser,) + tuple(viewsets.ModelViewSet.parser_classes)

另外也可能是权限认证的锅——比如你的视图集加了权限类,浏览器访问时没带认证信息,导致返回403/401。开发阶段可以先临时把权限改成AllowAny排查下:

from rest_framework.permissions import AllowAny

class VideoViewSet(viewsets.ModelViewSet):
    # ... 其他配置不动
    permission_classes = [AllowAny]

还有别忘了检查路由配置,确保用DefaultRouter正确注册了视图集:

from rest_framework.routers import DefaultRouter
from .views import VideoViewSet

router = DefaultRouter()
router.register(r'videos', VideoViewSet)
urlpatterns = router.urls

二、实现CSV导出API

你已经加了CSVParser,但要注意——这个是用来解析客户端发给你的CSV请求的,而导出CSV需要的是给客户端返回CSV格式的响应,所以得用CSVRenderer,再给视图集加个自定义动作专门处理导出:

步骤1:修改视图集代码

from rest_framework.renderers import CSVRenderer, JSONRenderer
from rest_framework.decorators import action
from rest_framework.response import Response

class VideoViewSet(viewsets.ModelViewSet):
    queryset = DatamsVideos.objects.all()
    serializer_class = VideosSerializer
    # 同时支持JSON和CSV两种响应格式
    renderer_classes = [JSONRenderer, CSVRenderer]
    parser_classes = (CSVParser,) + tuple(viewsets.ModelViewSet.parser_classes)

    # 自定义导出CSV的动作,detail=False表示这是列表级别的动作
    @action(detail=False, methods=['get'], renderer_classes=[CSVRenderer])
    def export_csv(self, request):
        # 获取要导出的数据集
        queryset = self.get_queryset()
        # 如果需要过滤数据,可以从请求参数里拿条件,比如按状态过滤
        status = request.query_params.get('status')
        if status:
            queryset = queryset.filter(status=status)
        # 序列化数据
        serializer = self.get_serializer(queryset, many=True)
        # 构造响应,设置下载文件名
        response = Response(serializer.data)
        response['Content-Disposition'] = 'attachment; filename="videos.csv"'
        return response

步骤2:访问导出接口

用DefaultRouter的话,这个自定义动作会自动生成路由,直接访问/videos/export_csv/就能下载CSV文件了。

小提醒

如果你的序列化器里有嵌套字段(比如关联了其他模型),CSV是不支持嵌套结构的,得用SerializerMethodField把嵌套数据转成字符串,比如:

class VideosSerializer(serializers.ModelSerializer):
    category_name = serializers.SerializerMethodField()

    def get_category_name(self, obj):
        return obj.category.name  # 假设关联了Category模型

    class Meta:
        model = DatamsVideos
        fields = ['id', 'title', 'category_name', 'created_at']

三、报错排查小技巧

如果还是搞不定,试试这些方法:

  • 打开浏览器控制台,看网络请求的状态码和响应内容,比如是不是404、403或者500
  • 看Django的日志文件,服务器端的报错信息会写在里面,能帮你定位问题
  • 确保rest_framework已经加到INSTALLED_APPS里了

内容的提问来源于stack exchange,提问作者Omega

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:27:07