我在管理员面板中使用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)
答案 0 :(得分:1)
覆盖after_import_instance
并将所有导入的ID保存在某个变量中,我们将其称为imported_ids
。覆盖after_import
并更新不在imported_ids
。
查看文档中的所有钩子:
答案 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']