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