Django-import-export更改/删除上传文件中缺少的数据

时间:2016-11-22 13:28:01

标签: django django-import-export

我在管理员面板中使用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)

2 个答案:

答案 0 :(得分: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

答案 1 :(得分: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']