Есть задача проанализировать файл csv и создать экземпляры в базе данных на основе полученных данных. На бэкэнде - DRF, а на передней - React. Особенность c в том, что обработка файла не совсем скрыта. Лог c выглядит следующим образом: есть кнопка для загрузки файла. Файл загружается и проверяется, но в базе данных ничего не создается сразу. Появится окно со списком сохраненных данных (например, таблицы), и в этом окне есть новая кнопка для подтверждения, нажав на которую база данных уже запрошена.
Что я только что сделал: 1. Создал класс для загрузки файла (кнопка «Загрузить»)
class FileUploadView(APIView):
parser_classes = ( MultiPartParser, FormParser)
renderer_classes = [JSONRenderer]
def put(self, request, format=None):
if 'file' not in request.data:
raise ParseError("Empty content")
f = request.data['file']
filename = f.name
if filename.endswith('.csv'):
file = default_storage.save(filename, f)
r = csv_file_parser(file)
status = 204
else:
status = 406
r = "File format error"
return Response(r, status=status)
В классе вызывается функция csv_file_parser , результатом которой является json, содержащая все сохраненные данные, например:
{
"1": {
"Vendor": "Firstvendortestname",
"Country": "USA",
...
...
"Modules": "Module1",
" NDA date": "2019-12-24"
},
"2": {
"Vendor": "Secondvendortestname",
"Country": "Canada",
...
...
"Modules": "Module1",
" NDA date": "2019-12-24"
}
}
Эти данные будут использоваться для предварительного просмотра полей, из которых будут создаваться модели в базе, путем нажатия кнопки Подтвердить .
csv_file_parser function
def csv_file_parser(file):
result_dict = {}
with open(file) as csvfile:
reader = csv.DictReader(csvfile)
line_count = 1
for rows in reader:
for key, value in rows.items():
if not value:
raise ParseError('Missing value in file. Check the {} line'.format(line_count))
result_dict[line_count] = rows
line_count += 1
return result_dict
Когда нажата кнопка «Подтвердить», React передает эти данные в качестве аргумента классу, который работает с базой данных, используя метод POST. С реализацией этого класса у меня возникли трудности. Как правильно обработать полученные данные и записать их в базу данных?
class CsvToDatabase(APIView):
def post(self, request, format=None):
data = request.data
for vendor in data:
Vendors(
vendor_name=vendor['Vendor'],
country=vendor['Country']
).save()
return Response({'received data': request.data})
Этот код выдает ошибку
TypeError at /api/v1/vendors/from_csv_create/
string indices must be integers
Печать request.data output
<QueryDict: {'{\n "1": {\n "Vendor": "Firstvendortestname",\n "Country": "USA",\n "Primary Contact Name": "Jack Jhonson",\n "Primary Contact Email": "jack@gmail.com",\n "Secondary Contact Name": "Jack2 Jhonson",\n "Secondary Contact Email": "jack2@gmail.com",\n "Modules": "Module1, Module2",\n " NDA date": "2019-12-24"\n },\n "2": {\n "Vendor": "Secondvendortestname",\n "Country": "Canada",\n "Primary Contact Name": "Sandra Bullock",\n "Primary Contact Email": "sandra@gmail.com",\n "Secondary Contact Name": "Sandra Bullock",\n "Secondary Contact Email": "sandra@gmail.com",\n "Modules": "Module1, Module2",\n " NDA date": "2019-12-24"\n }\n}': ['']}>
Может быть, я использую неправильный формат данных?
И в целом у меня есть ощущение, что я делаю работу неправильно. Я не использую сериализаторы, они мне нужны здесь?