You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django Import-export:如何检测导入SKU是否存在以更新而非新建产品

用Django Import-export实现SKU存在则更新、不存在则新建的逻辑

要实现这个需求,核心是让django-import-export工具通过SKU字段匹配数据库中的已有记录,以此判断执行更新还是新建操作。只需修改ProductResource类的配置即可,具体实现如下:

修改后的完整代码

# admin.py
from django.contrib import admin
from .models import Product
from import_export import resources
from import_export.admin import ImportExportModelAdmin

class ProductResource(resources.ModelResource):
    class Meta:
        model = Product
        # 核心配置:指定SKU作为导入时的唯一匹配标识
        import_id_fields = ('sku',)
        # 可选:跳过无变更的记录,提升导入效率
        skip_unchanged = True
        # 可选:在导入报告中显示被跳过的记录
        report_skipped = True
        # 可选:自定义导入/导出的字段列表,不设置则默认所有字段
        # fields = ('sku', 'name', 'manufacturer', 'cost', 'price', 'short_description')

class ProductAdmin(ImportExportModelAdmin, admin.ModelAdmin):
    search_fields = ['name','sku','parent','family']
    list_display = ('id','sku','manufacturer','name','short_description','cost','price','price2','parent','family','nla',)
    list_filter = ('manufacturer',)
    resource_class = ProductResource

admin.site.register(Product, ProductAdmin)

关键配置说明

  • import_id_fields = ('sku',):这是实现逻辑的核心。导入时,工具会用每行数据的SKU字段去数据库查询已有Product记录:
    • 查询到匹配记录:更新该行的其他字段值
    • 未查询到匹配记录:创建新的Product记录
  • skip_unchanged = True:可选优化项,当导入行与数据库已有记录完全一致时,跳过更新操作,减少不必要的数据库交互
  • report_skipped = True:可选配置,开启后导入完成的报告中会显示因无变更被跳过的记录,便于后续排查

自定义复杂逻辑(可选)

如果需要更精细的控制(比如仅更新特定字段、添加自定义校验),可以重写资源类的方法:

class ProductResource(resources.ModelResource):
    class Meta:
        model = Product
        import_id_fields = ('sku',)

    def before_import_row(self, row, **kwargs):
        # 导入行前的自定义校验,比如检查SKU是否为空
        sku = row.get('sku')
        if not sku:
            raise ValueError("SKU字段不能为空")

    def save_instance(self, instance, using_transactions=True, dry_run=False, **kwargs):
        # 自定义保存逻辑:更新时仅修改成本和价格字段
        if instance.pk:  # 存在主键说明是已有记录(更新操作)
            existing = Product.objects.get(pk=instance.pk)
            existing.cost = instance.cost
            existing.price = instance.price
            existing.save()
        else:  # 无主键说明是新建记录
            instance.save()

内容的提问来源于stack exchange,提问作者user16170624

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 20:35:39