Невозможность создания повторных ссылок через ассоциацию с внешним ключом в django
Я совсем новичок в django и python нуждаюсь в вашем понимании
Я пытаюсь разобрать список csv файлов из каталога, сохраняя имя и количество строк в модели Files и содержимое csv в модели Work (связанной с Files)
У меня есть два запроса
В модели Files recs создаются, но в модели Work recs не создаются, ниже приведен мой код и сообщение об ошибке не выдается
Модели
class Files(models.Model):
filename = models.CharField(max_length=100)
work_count = models.IntegerField(default=0)
class Work(models.Model):
proprietary_id = models.IntegerField(default=0)
iswc = models.CharField(max_length=1000)
source = models.CharField(max_length=1000)
title = models.CharField(max_length=1000)
contributors = JSONField()
file = models.ForeignKey(Files,on_delete = models.CASCADE)
View
root_dir="D:/Django/siva/files"
for file in os.listdir(root_dir):
with open(f'{root_dir}/{file}','r') as csv_file:
csv_reader= csv.DictReader(csv_file,delimiter=',')
Files.objects.create(filename=file, work_count=len(list(csv_reader)))
for row in csv_reader:
file_obj=Files.objects.get(filename=file)
print(file_obj)
Work.objects.create(proprietary_id=row['proprietary_id'],iswc=row['iswc'],source=row['source'],title=row['title'],contributors=row['contributors'],file_=file_obj)
образец файла csv
title,contributors,iswc,source,proprietary_id
Shape of You,Edward Christopher Sheeran,T9204649558,sony,1
Je ne sais pas,Obispo Pascal Michel|Florence Lionel Jacques,T0046951705,sony,3
А также есть ли какой-нибудь конкретный метод для установки root_dir, чтобы мне не нужно было менять структуру файловых путей в разных ОС
Ваша проблема в том, что экземпляр DictReader
уже потребляется к тому времени, когда вы переходите к for row in csv_reader:
. Когда он преобразуется в список, чтобы получить длину, весь генератор потребляется и ничего не остается для цикла forloop.
Вы можете исправить это, просто преобразовав объект в список или кортеж сразу после его создания.
csv_reader = tuple(csv.DictReader(csv_file, delimiter=','))
Это вызовет еще одну ошибку, где file_=file_obj
на самом деле должно быть file=file_obj
, но это очень просто исправить.
Что касается вашей проблемы с путями: если вы установили Django достаточно недавно, вы должны быть в состоянии просто импортировать ваши настройки и получить доступ к settings.BASE_DIR
from django.conf import settings
settings.BASE_DIR
Это объект pathlib.Path и он должен быть очень полезен для вас. Он позволит вам получить доступ к вашим файлам гораздо более естественным способом.
Вот как я бы написал этот фрагмент кода.
root = settings.BASE_DIR / '../path/to/csv'
for path in root.iterdir():
with path.open('r') as source:
data = tuple(csv.DictReader(source, delimiter=','))
file_ = Files.objects.create(filename=path.name, work_count=len(data))
Work.objects.bulk_create([Work(file=file_, **kwargs) for kwargs in data])