Трудности при извлечении данных из CSV и сопоставлении их с моделью продукта, пожалуйста, подскажите
Здравствуйте, я застрял с проектом Django Python, где я пытаюсь создать приложение, в которое можно загрузить файл csv, чтобы затем извлечь его значения для создания отчета о продажах pdf. Продукты могут быть добавлены через консоль администратора, и если эти продукты появляются (в нужном месте на данный момент, например, элемент 4 в каждом ряду проверяется) в csv файле, они извлекаются и добавляются в отчет (вычисление суммы, хранение даты каждой покупки).
Для полноты я добавлю всю функцию csv_upload_view, а затем упомяну конкретные части, с которыми у меня возникли трудности:
def csv_upload_view(request):
print('file is being uploaded')
if request.method == 'POST':
csv_file_name = request.FILES.get('file').name
csv_file = request.FILES.get('file')
obj, created = CSV.objects.get_or_create(file_name=csv_file)
#result = []
if created:
obj.csv_file = csv_file
obj.save()
with open(obj.file_name.path, 'r') as f:
reader = csv.reader(f)
reader.__next__()
for row in reader:
print(row,type(row))
data = " ".join(row)
data = data.split(";")
print(data, type(data))
# print(data[2])
#data = data.split(';')
#data.pop()
#print(data)
transaction_id = data[1]
product = data[2]
quantity = int(data[3])
customer = data[4]
date = parse_date(data[5])
print(transaction_id, product, quantity, customer, date)
try:
product_obj = Product.objects.get(name__iexact=product)
except Product.DoesNotExist:
product_obj = None
return HttpResponse()
Файл csv выглядит следующим образом:
POS,Transaction id,Product,Quantity,Customer,Date
1,E100,TV,1,Test Customer,2022-09-19
2,E100,Laptop,3,Test Customer,2022-09-20
3,E200,TV,1,Test Customer,2022-09-21
4,E300,Smartphone,2,Test Customer,2022-09-22
5,E300,Laptop,5,New Customer,2022-09-23
6,E300,TV,1,New Customer,2022-09-23
7,E400,TV,2,ABC,2022-09-24
8,E500,Smartwatch,4,ABC,2022-09-25
У меня 2 основные проблемы, первая заключается в том, что, следуя учебнику с кем-то, кто использует Mac (я на Windows, но и сохранение файла csv в формате Macintosh не помогло), код, который он использует, просто не работает для меня. Он буквально возвращает пустую строку:
with open(obj.csv_file.path, 'r') as f:
reader = csv.reader(f)
reader.__next__()
for row in reader:
data = "".join(row)
data = data.split(';')
data.pop()
Моим обходным решением здесь является написание следующего кода, который генерирует жало, разделенное ';':
for row in reader:
print(row,type(row))
data = " ".join(row)
data = data.split(";")
В рамках этой первой проблемы я в настоящее время не могу захватить элементы. Я думаю, что мне, вероятно, нужно преобразовать значения в список, но в этом есть проблема, которая и является моей
основной проблемой:
Идем дальше в коде
transaction_id = data[1]
product = data[2]
quantity = int(data[3])
customer = data[4]
date = parse_date(data[5])
print(transaction_id, product, quantity, customer, date)
try:
product_obj = Product.objects.get(name__iexact=product)
except Product.DoesNotExist:
product_obj = None
return HttpResponse()
Терминал выводит:
Quit the server with CONTROL-C.
[26/Sep/2022 19:15:25] "GET /reports/from-file/ HTTP/1.1" 200 11717
file is being uploaded
['1', 'E100', 'TV', '1', 'Test Customer', '9/19/2022'] <class 'list'>
1;E100;TV;1;Test;Customer;9/19/2022 <class 'str'>
; E 1 0 None
(…)
Оказывается, product_obj всегда имеет значение None, которое он также имел, когда я игрался с итерацией, где я иногда мог выпускать элементы, но никогда product_obj, который постоянно установлен в None. Буду очень признателен, если вы сможете взглянуть на это!
использование csv.reader
- нет необходимости соединять, а затем разделять обратный ряд и т.д.
with open(obj.csv_file.path, 'r') as f:
rdr = csv.reader(f)
next(rdr) # skip the header row
# alternative 1
for row in rdr:
pos, transaction_id, product, quantity, customer, transaction_date = row
# here work with product to check if exists
# alternative 2
for pos, transaction_id, product, quantity, customer, transaction_date in rdr:
# here work with product to check if exists
Использование csv.DictReader
:
with open(obj.csv_file.path, 'r') as f:
rdr = csv.DictReader(f)
for row in rdr:
product = row['Product'] # this will work even when column order/number has changed
# here work with product to check if exists
Теперь я вижу, что это ваш третий вопрос подряд по одной и той же проблеме. У вас есть несколько хороших рабочих кодов и несколько плохих советов. В любом случае, не похоже, что вы действительно пытаетесь понять приведенный вам код.