4

我在我的管理面板中使用Django-import-export模块。我导入了从我们的 ERM 系统中提取的 .csv 文件,该文件更新了 Django myapp 数据库中的记录。一切都像一个魅力,除了当一些记录从 ERM 中删除并且不存在于 .csv 数据转储中时,由于记录不存在,因此不会在 Django 数据库中进行更新。

我想在导入 .csv 文件时写一个子句,更改或删除(最好将记录名称更改为“已删除”)所有不存在于上述 .csv 文件中的记录。记录由“数字”列标识,该列是数据库中的主键。

我能找到的最接近的解决方案是在上传的文件中添加“删除”列并设置“1”,但这无济于事,因为这些记录首先不存在。

这是我的 admin.py 的样子:

from django.contrib import admin
from .models import Supplier, SiteServices
from import_export import resources, widgets, fields
from import_export.admin import ImportExportModelAdmin


# Register your models here.
class SupplierResource(resources.ModelResource):
    delete = fields.Field(widget=widgets.BooleanWidget())

    def for_delete(self, row, instance):
        return self.fields['delete'].clean(row)

    class Meta:
        model = Supplier
        import_id_fields = ['number']


class SupplierAdmin(ImportExportModelAdmin, admin.ModelAdmin):
    resource_class = SupplierResource

admin.site.register(Supplier, SupplierAdmin)
4

2 回答 2

1

这是我为此实现的一个已解决的示例。这与 bmihelac 建议的方法相同。

创建您自己的 ModelResource,它处理导入文件中的实例的保存,以及处理删除所有其他行的方法。

import import_export
class MyModelResource(import_export.resources.ModelResource):

    def after_import_instance(self, instance, new, **kwarg):
        """ For each row in the import file, add the pk to the list """
        self.imported_rows_pks.append(instance.pk)

    def after_import(self, dataset, result, using_transactions, dry_run, **kwargs):
        """  delete all rows not in the import data set. Then call the same method in the parent to still sequence the DB """
        self.Meta.model.objects.exclude(pk__in=self.imported_rows_pks).delete()
        import_export.resources.ModelResource.after_import(self, dataset, result, using_transactions, dry_run, **kwargs)

除了删除之外,您还可以这样说:

self.Meta.model.objects.exclude(pk__in=self.imported_rows_pks).update(deleted=True)

然后,像往常一样创建一个导入导出资源,但它基于扩展的 MyModelResource:

class SupplierResource(MyModelResource):
    imported_rows_pks = []

    class Meta:
        model = Supplier
        import_id_fields = ['number']
于 2017-10-23T15:37:17.540 回答
1

覆盖after_import_instance所有导入的 id 并将其保存在某个变量中,让我们调用它imported_ids。覆盖after_import和更新不在imported_ids.

查看文档中的所有钩子:

https://django-import-export.readthedocs.io/en/latest/api_resources.html#import_export.resources.Resource.after_import_row

于 2016-11-23T13:10:41.967 回答