Невозможность создания повторных ссылок через ассоциацию с внешним ключом в 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])
Вернуться на верх