Django REST Upload CSV возвращает ответ со всеми сообщениями

#python #django #csv

#python #django #csv

Вопрос:

У меня есть CMS для блогов, которая отлично работает, но я хочу иметь возможность загружать CSV с несколькими тестовыми сообщениями, а затем добавлять их в базу данных все сразу. Прямо сейчас я могу загрузить CSV и выполнить итерацию по строкам, но поскольку мои функции POST возвращают ответ, он завершается после одной итерации. Как я могу заставить его перебирать все строки, а затем возвращать список созданных сообщений в блоге?

Вот мой код, который работает для создания по одному за раз:

 class PostsImportAPIView(generics.ListCreateAPIView):
    serializer_class    = DashboardPostSerializer
    permission_classes  = [IsOwner]
    pagination_class    = BlogPostPagination

    def get_queryset(self, *args, **kwargs):
        return BlogPost.objects.all()

    def post(self, request, *args, **kwargs):
        if request.FILES:
            data = request.data
        else:
            data = request.data.copy()

        csv_file = TextIOWrapper(data['csv'].file, encoding='ascii', errors='replace')
        import_csv = csv.reader(csv_file)
        next(import_csv)
        counter = 0
        for line in import_csv:
            if line:
                data['title'] = line[0]
                data['body'] = line[1]
                date_field  = line[2].split(' ')
                data['created_at']  = datetime.datetime.strptime(date_field[0], '%Y-%m-%d %H:%M:%S.%f')
                data['published'] = line[3]

                serializer  = DashboardPostImportSerializer(data=data, context={'request': request})
                if serializer.is_valid(raise_exception=True):
                    serializer.save()
                    return Response(serializer.data, status=status.HTTP_201_CREATED)
                return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
  

Это работает лучше для одного за раз, но то, что я хотел бы сделать, это увеличить мой счетчик для каждой завершенной строки, а затем вернуть набор запросов сообщений, которые соответствуют длине счетчика. Но поскольку возврат моего ответа прерывает цикл, я не уверен, что следующий шаг будет лучшим.

Комментарии:

1. Решение состоит в том, чтобы вывести ответ из цикла — выполнить итерацию по всем строкам, отслеживая сбои, и как только вы закончите цикл, верните ответ

Ответ №1:

Благодаря kiwibg, это рабочий код. Он выполняет итерацию по csv и создает все сообщения, хотя окончательный сериализатор возвращает только последнее созданное сообщение. Но для намеченных целей этого достаточно.

 class PostsImportAPIView(generics.ListCreateAPIView):
    serializer_class    = DashboardPostSerializer
    permission_classes  = [IsOwner]
    pagination_class    = BlogPostPagination

    def get_queryset(self, *args, **kwargs):
        return BlogPost.objects.all()

    def post(self, request, *args, **kwargs):
        if request.FILES:
            data = request.data
        else:
            data = request.data.copy()

        csv_file = TextIOWrapper(data['csv'].file, encoding='ascii', errors='replace')
        import_csv = csv.reader(csv_file)
        next(import_csv)
        counter = 0
        for line in import_csv:
            if line:
                data['title'] = line[0]
                data['body'] = line[1]
                date_field  = line[2].split(' ')
                data['created_at']  = datetime.datetime.strptime(date_field[0], '%Y-%m-%d %H:%M:%S.%f')
                data['published'] = line[3]

                serializer  = DashboardPostImportSerializer(data=data, context={'request': request})
                if serializer.is_valid(raise_exception=True):
                    counter  = 1
                    serializer.save()

        if serializer.is_valid(raise_exception=True):
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)