Создайте объект, если он не существует в Django ImportExportModelAdmin
У меня есть эти две модели:
Profile_model.py
class Profile(models.Model):
firstname = models.CharField(max_length=200, blank=False)
lastname = models.CharField(max_length=200, blank=False)
email = models.CharField(max_length=200, unique=True, blank=False)
...
Investment_model.py
class Investment(models.Model):
invested = models.DecimalField(max_digits=9, decimal_places=2, blank=True, null=True)
profile = models.ForeignKey(Profile, on_delete=models.CASCADE)
...
и у меня есть этот администратор:
Investment_admin.py
class InvestmentResource(resources.ModelResource):
...
firstname = fields.Field(attribute='profile',
widget=ForeignKeyWidget(Profile, field='firstname'),
column_name='firstname')
lastname = fields.Field(attribute='profile',
widget=ForeignKeyWidget(Profile, field='lastname'),
column_name='lastname')
email = fields.Field(attribute='email',
widget=ForeignKeyWidget(Profile, field='email'),
column_name='email')
class Meta:
model = Investment
fields = (
'firstname',
'lastname',
'email',
'invested',)
export_order = fields
class InvestmentAdmin(ImportExportModelAdmin, admin.ModelAdmin):
...
resource_class = InvestmentResource
...
Я использую django
'ImportExportModelAdmin
для массового импорта и экспорта, но когда я пытаюсь импортировать, я получаю эту ошибку:
Я понимаю, что он выдает эту ошибку, потому что профиль еще не создан. Но что мне нужно сделать, чтобы реализовать update_or_create
внутри ImportExportModelAdmin
?
Вариант 1 - использовать before_import()
для сканирования набора данных и пакетного создания профилей, если они еще не существуют.
Вариант 2 - переопределить методы и создать профили непосредственно перед импортом строки Investment
. Это необходимо только для новых объектов Investment
. Здесь предполагается, что 'email' будет однозначно идентифицировать профиль, если это не так, вам нужно будет скорректировать это.
class InvestmentResource(resources.ModelResource):
def before_import_row(self, row, row_number=None, **kwargs):
self.email = row["email"]
def after_import_instance(self, instance, new, row_number=None, **kwargs):
"""
Create any missing Profile entries prior to importing rows.
"""
if (
new
and not models.Profile.objects.filter(
email=self.email
).exists()
):
_, created = models.Profile.objects.get_or_create(
email=email
)
if created:
logger.debug(f"no Profile in db with email='{self.email}' - created")
Очевидно, что создание профиля будет побочным эффектом импорта, поэтому вам может понадобиться рассмотреть возможность использования транзакций, если вы не хотите, чтобы профили создавались в случае неудачи импорта.