django - 如果 Django ImportExportModelAdmin 中不存在则创建对象

标签 django django-import-export

我有这两个模型:

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
        ...

我使用 djangoImportExportModelAdmin 进行批量导入和导出,但是当我尝试导入时,出现此错误:

enter image description here

我发现它会产生此错误,因为配置文件尚未创建。但是我需要做什么才能在 ImportExportModelAdmin 内实现 update_or_create

最佳答案

选项 1 是使用 before_import() 扫描数据集并批量创建配置文件(如果配置文件尚不存在)。

选项 2 是在导入Investment 行之前重写方法并创建配置文件。这仅对于新的投资对象是必需的。这假设“电子邮件”将唯一地标识个人资料,如果不是,您将需要对此进行调整。

请注意,firstnamelastname 可以在创建 Profile 对象之前设置。

class InvestmentResource(resources.ModelResource):
    firstname = fields.Field(attribute='profile__firstname', 
        widget=CharWidget(), column_name='firstname')

    lastname = fields.Field(attribute='profile__lastname', 
        widget=CharWidget(), column_name='lastname')

    email = fields.Field(attribute='email', 
        widget=ForeignKeyWidget(Profile, field='email'), 
        column_name='email')

    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 Profile.objects.filter(
                name=self.email
            ).exists()
        ):
            obj, created = Profile.objects.get_or_create(
                name=self.email
            )
            if created:
                logger.debug(f"no Profile in db with name='{self.email}' - created")
                instance.profile = obj

显然,配置文件创建将是导入的副作用,因此如果您不希望在导入失败时创建配置文件,则可能需要考虑使用事务。

关于django - 如果 Django ImportExportModelAdmin 中不存在则创建对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69428817/

相关文章:

python - django 导入_导出 |数据未从数据库导出

来自相关模型的 django 管理显示字段

python - Django 导入导出 - 无法使用 BinaryField 导入模型

django - 如何在 Django 中创建引用两个相关模型的注释

url查询中的Django自定义排序

python - 为什么在 MacOS 中启动 Django 服务器时出现错误?

python - 使用 Django 模型的 post_save 进行手动缓存失效 : do foreign keys trigger save()?

python - 使用 mod_wsgi 安装 Django

Django 导入导出 : only export

python - 如何使用 django-import-export 导出属性值