首页 > 解决方案 > django rest框架创建json和csv api

问题描述

我正在尝试创建 2 个 api。1使用ajax数据表访问json,另一个创建导出csv按钮。

我设法使用ajax创建并从中获取数据的json api,但是当我尝试在浏览器中访问api和另一个添加csv api时遇到问题..我将向您展示我的部分脚本和我得到的错误。

视图.py

class VideoViewSet(viewsets.ModelViewSet):
    queryset = DatamsVideos.objects.all()
    serializer_class = VideosSerializer

    parser_classes = (CSVParser,) + tuple(api_settings.DEFAULT_PARSER_CLASSES)
    renderer_classes = (CSVRenderer,) + tuple(api_settings.DEFAULT_RENDERER_CLASSES)

    def list(self, request, **kwargs):
        try:
            vs = query_vs_by_args(**request.query_params)
            serializer = VideosSerializer(vs['items'], many=True)
            result = dict()
            result['data'] = serializer.data
            result['draw'] = vs['draw']
            result['recordsTotal'] = vs['total']
            result['recordsFiltered'] = vs['count']
            return Response(result, status=status.HTTP_200_OK, template_name=None, content_type=None)

        except Exception as e:
            return Response(e, status=status.HTTP_404_NOT_FOUND, template_name=None, content_type=None)

    def get_renderer_context(self):
        context = super(VideoViewSet, self).get_renderer_context()
        context['header'] = (
            self.request.GET['fields'].split(',')
            if 'fields' in self.request.GET else None)
        return context

    @action(methods=['GET'], detail=False)
    def bulk_upload(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data, many=True)
        serializer.is_valid(raise_exception=True)
        serializer.save()

        return Response(serializer.data, status=status.HTTP_303_SEE_OTHER, headers={'Location': reverse('videos-api')})

网址.py

from rest_framework.routers import DefaultRouter

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

urlpatterns = [
    url(r'^$', index, name='main'),
    url(r'^api/', include(router.urls)),
]

这是我的models.py的一部分

def query_vs_by_args(**kwargs):
    draw = int(kwargs.get('draw', None)[0])
    length = int(kwargs.get('length', None)[0])
    start = int(kwargs.get('start', None)[0])
    search_value = kwargs.get('search[value]', None)[0]
    order_column = kwargs.get('order[0][column]', None)[0]
    order = kwargs.get('order[0][dir]', None)[0]

    order_column = ORDER_VS_COLUMN_CHOICES[order_column]
    # django orm '-' -> desc
    if order == 'desc':
        order_column = '-' + order_column

    queryset = DatamsVideos.objects.all()
    total = queryset.count()

    if search_value:
        queryset = queryset.filter(Q(link__icontains=search_value) |
                                   Q(title__icontains=search_value) |
                                   Q(views__icontains=search_value) |      Q(date_added__icontains=search_value))                                         

    count = queryset.count()
    queryset = queryset.order_by(order_column)[start:start + length]
    return {
        'items': queryset,
        'count': count,
        'total': total,
        'draw': draw
    }

我遇到的问题之一是来自views.py的函数列表

vs = query_vs_by_args(**request.query_params)
serializer = VideosSerializer(vs['items'], many=True)

我仍然设法使用ajax从中获取数据,但是当我尝试访问浏览器/main/api/videos/上的api时,它给了我这个错误:

   HTTP 404 Not Found
Allow: GET, POST, HEAD, OPTIONS
Content-Type: text/csv ;utf-8
Vary: Accept

""
'NoneType' object has no attribute '__getitem__'

当我尝试访问/main/api/videos/?format=json

TypeError("'NoneType' object has no attribute '__getitem__'",) is not JSON serializable

当我尝试从/main/api/videos/?format=csv获取 csv时,它告诉我找不到文件

我可能遗漏了一些细节,如果您想了解更多信息,不能告诉我。

先感谢您

更新 现在我才意识到,如果我评论函数列表,api 的工作正常..但是我的 ajax 不再工作了,因为我没有构建 json 的 4 个必要的东西

    result['data'] = serializer.data
    result['draw'] = ch['draw']
    result['recordsTotal'] = ch['total']
    result['recordsFiltered'] = ch['count']

标签: djangopython-2.7django-rest-framework

解决方案


通过分离类,我设法解决了 csv 和 api 问题。

class VideoCSVExportView(viewsets.ModelViewSet):
    queryset = DatamsPornhubVideos.objects.all()
    serializer_class = VideosSerializer

    renderer_classes = (CSVRenderer,) + tuple(api_settings.DEFAULT_RENDERER_CLASSES)

在我为 csv 创建这个新类之后,我把它放在了不同的路线上。

csv_router = DefaultRouter()
csv_router.register(r'videos', VideoCSVExportView)

...
    url(r'^csv/', include(csv_router.urls)),
..

推荐阅读