Django import-export foregin key
Я пытаюсь импортировать данные с внешним ключом, следуя руководству из библиотеки импорта-экспорта Django (виджет внешнего ключа). Но я получаю следующую ошибку, я пытался добавить дополнительный столбец с заголовком id, но все равно получаю ту же ошибку.
Errors
Line number: 1 - 'id'
None, 46, 19, LSD
Traceback (most recent call last):
File "/var/www/vfsc-env/lib/python3.6/site-packages/import_export/resources.py", line 635, in import_row
instance, new = self.get_or_init_instance(instance_loader, row)
File "/var/www/vfsc-env/lib/python3.6/site-packages/import_export/resources.py", line 330, in get_or_init_instance
instance = self.get_instance(instance_loader, row)
File "/var/www/vfsc-env/lib/python3.6/site-packages/import_export/resources.py", line 318, in get_instance
self.fields[f] for f in self.get_import_id_fields()
File "/var/www/vfsc-env/lib/python3.6/site-packages/import_export/resources.py", line 318, in <listcomp>
self.fields[f] for f in self.get_import_id_fields()
KeyError: 'id'
Вот что я сделал.
class Clockin_Users(models.Model):
id = models.AutoField(db_column='ID', primary_key=True) # Field name made lowercase.
userid = models.IntegerField(db_column='UserID', unique=True) # Field name made lowercase.
username = models.CharField(db_column='UserName', max_length=20, blank=True,
facecount = models.IntegerField(db_column='FaceCount', blank=True, null=True) # Field name made lowercase.
userid9 = models.CharField(db_column='UserID9', max_length=10, blank=True, null=True) # Field name made lowercase.
depid = models.IntegerField(db_column='DepID', blank=True, null=True) # Field name made lowercase.
empno = models.CharField(db_column='EMPNO', max_length=50, blank=True, null=True) # Field name made lowercase.
def __str__(self):
return self.name
class Clockin_Department(models.Model):
clockinusers = models.ForeignKey(Clockin_Users, on_delete=models.CASCADE)
depid = models.AutoField(db_column='DepID', primary_key=True) # Field name made lowercase.
departmentname = models.CharField(db_column='DepartmentName', max_length=100, blank=True,
null=True) # Field name made lowercase
def __str__(self):
return self.departmentname
class ClockinDepartmentResource(resources.ModelResource):
clockinusers = fields.Field(column_name='clockinusers', attribute='clockinusers',
widget=ForeignKeyWidget(Clockin_Users))
class Meta:
fields = 'clockinusers'
class ClockinDepartmentAdmin(ImportExportModelAdmin):
list_display = ('clockinusers', 'depid', 'departmentname')
recource_class = ClockinDepartmentResource
admin.site.register(Clockin_Department, ClockinDepartmentAdmin)
Этот вопрос возникает довольно часто, поэтому я постараюсь дать исчерпывающий ответ, который может помочь другим в будущем.
При импорте файла с помощью django-import-export
файл будет обрабатываться строка за строкой. Для каждой строки процесс импорта будет проверять, соответствует ли эта строка существующему экземпляру хранилища или должен быть создан новый экземпляр.
Для того чтобы проверить, существует ли уже данный экземпляр, django-import-export
необходимо использовать поле (или комбинацию полей) в импортируемой строке. Идея заключается в том, что поле (или поля) будет однозначно идентифицировать единственный экземпляр импортируемого типа модели.
Здесь на помощь приходит мета-атрибут import_id_fields
. Вы можете использовать это объявление, чтобы указать, какое поле (или поля) должно использоваться для уникальной идентификации строки. Если вы не объявите import_id_fields
, то будет использоваться объявление по умолчанию, в котором есть только одно поле: 'id'.
Теперь мы видим источник вашей ошибки - процесс импорта пытается использовать поле по умолчанию 'id', но в вашей строке нет соответствующего поля.
Чтобы исправить это, вам нужно либо включить поле 'id' в ваше поле csv, либо, если это невозможно, выбрать какое-то другое поле (или поля), которое будет однозначно идентифицировать строку.
В любом случае, убедитесь, что вы объявили это поле (или поля) в атрибуте fields
, например:
class BookResource(resources.ModelResource):
class Meta:
model = Book
import_id_fields = ('id',)
fields = ('id', 'name', 'author', 'price',)
Обратите внимание, что если у вас несколько строк, которые идентифицируются import_id_fields
, то это неверно, так как должно возвращаться либо 0, либо 1 строка. В этом случае вы получите ошибку MultipleObjectsReturned
.