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

在Django中导入CSV文件时如何避免重复记录?

嘿,我看你已经搞定了CSV导入的基础功能,现在要解决重复记录的问题对吧?这在数据导入场景里太常见了,我给你几个实用的方案,都是Django项目里常用的思路:

方案1:用Django ORM自带的get_or_create()(最推荐)

这个方法是Django官方提供的去重神器——它会先根据你指定的唯一字段查询记录,存在就返回已有的对象,不存在就创建新的,完美避免重复。

修改后的代码如下:

def upload_csv(request):
    if request.method == 'POST' and request.FILES.get('csv_file'):
        csv_file = request.FILES['csv_file']
        # 直接读取上传的文件内容,无需保存到服务器(更高效)
        decoded_file = csv_file.read().decode('utf-8').splitlines()
        data = csv.reader(decoded_file)
        
        # 跳过表头行(比原判断更可靠)
        next(data)
        
        for row in data:
            # 以FP_Item作为唯一标识,避免重复
            obj, created = FP.objects.get_or_create(
                FP_Item=row[0],
                # 如果有其他需要初始化的字段,放在defaults里
                defaults={
                    # 示例:如果你的模型有FP_Name字段,对应CSV第二列
                    # 'FP_Name': row[1]
                }
            )
            # 可选:打印日志区分新创建/已存在的记录
            # if created:
            #     print(f"新增记录: {obj.FP_Item}")
            # else:
            #     print(f"跳过重复记录: {obj.FP_Item}")
        
        messages.success(request, "FP数据导入完成,已自动跳过重复记录")
        queryset_list = FP.objects.all()
        context = {'object_list': queryset_list}
        return render(request, 'your_template.html', context)
    # GET请求返回上传表单
    return render(request, 'upload_form.html')

关键说明:

  • get_or_create()返回一个元组:第一个是数据库对象,第二个是布尔值(True表示新创建,False表示已存在)
  • 直接读取上传文件:省去了用FileSystemStorage保存文件的步骤,小文件导入更高效;如果是超大CSV,再考虑保存到服务器
  • 用next(data)跳过表头:比原代码的row[0] != 'FP_Item'更可靠,避免表头格式变化导致的判断失效

方案2:需要更新已存在的记录?用update_or_create()

如果你的需求不是跳过重复,而是要用CSV里的最新数据更新已存在的记录,可以用update_or_create(),它会在记录存在时更新指定字段,不存在时创建新记录:

for row in data:
    obj, created = FP.objects.update_or_create(
        FP_Item=row[0],
        defaults={
            # 这里放需要更新的字段,比如CSV里的其他列
            'FP_Name': row[1],
            'FP_Price': row[2]
        }
    )

额外保障:数据库层面加唯一约束

为了双重保险,建议在你的FP模型里给FP_Item字段加上unique=True约束,这样数据库层面也会阻止重复数据插入:

class FP(models.Model):
    FP_Item = models.CharField(max_length=100, unique=True)  # 加唯一约束
    # 其他字段...

这样即使代码有疏漏,数据库也会抛出IntegrityError,避免脏数据进入。

内容的提问来源于stack exchange,提问作者İlkem Çetinkaya

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 07:50:49