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

如何实现从HTML表单接收CSV文件并转换为JSON后存入Django模型?

当然有靠谱的实现方案!我帮你拆解成几个可落地的步骤,都是Django项目里常用的实践,完全贴合你的需求:

整体实现流程

核心逻辑是:HTML表单上传CSV → 后端读取CSV并转换为字典列表(JSON的Python原生形式,比先转JSON字符串更高效) → 批量校验并写入Django模型。

1. 构建HTML上传表单

首先需要一个支持文件上传的表单,注意必须设置enctype="multipart/form-data",还要带上Django的CSRF令牌:

<!-- templates/upload.html -->
<form method="post" enctype="multipart/form-data">
    {% csrf_token %}
    <div>
        <label>选择CSV文件:</label>
        <input type="file" name="csv_file" accept=".csv" required>
    </div>
    <button type="submit" style="margin-top:10px;">上传并导入数据</button>
    {% if error %}
        <p style="color:red;">{{ error }}</p>
    {% endif %}
    {% if success %}
        <p style="color:green;">{{ success }}</p>
    {% endif %}
</form>

2. 后端处理CSV上传并转换为字典列表

这里提供两种实现方式,选你顺手的就行:

方式一:原生Python模块(无需额外依赖)

用Python内置的csv模块直接读取CSV,转成字典列表(直接可用于模型创建,无需额外JSON转换):

# views.py
import csv
from django.shortcuts import render
from django.db import transaction
from .models import YourModel  # 替换成你的实际模型

def upload_csv(request):
    if request.method == 'POST':
        csv_file = request.FILES.get('csv_file')
        # 校验文件格式
        if not csv_file.name.endswith('.csv'):
            return render(request, 'upload.html', {'error': '请上传正确的CSV格式文件'})
        
        # 读取CSV内容并转成字典列表
        try:
            # 解码文件内容并按行分割
            csv_content = csv_file.read().decode('utf-8').splitlines()
            # 用DictReader将第一行作为键,每行数据转成字典
            csv_reader = csv.DictReader(csv_content)
            data_list = list(csv_reader)
        except Exception as e:
            return render(request, 'upload.html', {'error': f'CSV解析失败:{str(e)}'})
        
        # 写入模型(见步骤3)
        try:
            with transaction.atomic():
                # 批量创建或循环创建,根据数据量选择
                for item in data_list:
                    # 注意:如果CSV列名和模型字段名不一致,需要手动映射
                    # 例如:YourModel.objects.create(name=item['商品名称'], price=item['售价'])
                    YourModel.objects.create(**item)
            return render(request, 'upload.html', {'success': '数据导入成功!'})
        except Exception as e:
            return render(request, 'upload.html', {'error': f'数据写入失败:{str(e)}'})
    
    # GET请求时返回表单页面
    return render(request, 'upload.html')

方式二:用Pandas简化操作(适合复杂CSV)

如果你的CSV有复杂格式(比如合并单元格、特殊编码),用Pandas会更省心,先安装依赖:pip install pandas

# views.py
import pandas as pd
from django.shortcuts import render
from django.db import transaction
from .models import YourModel

def upload_csv(request):
    if request.method == 'POST':
        csv_file = request.FILES.get('csv_file')
        if not csv_file.name.endswith('.csv'):
            return render(request, 'upload.html', {'error': '请上传CSV格式文件'})
        
        try:
            # 读取CSV并转成字典列表
            df = pd.read_csv(csv_file)
            data_list = df.to_dict('records')  # 每行转成一个字典
        except Exception as e:
            return render(request, 'upload.html', {'error': f'CSV解析失败:{str(e)}'})
        
        # 写入模型逻辑和上面一致
        try:
            with transaction.atomic():
                YourModel.objects.bulk_create([YourModel(**item) for item in data_list])
            return render(request, 'upload.html', {'success': '批量导入成功!'})
        except Exception as e:
            return render(request, 'upload.html', {'error': f'数据写入失败:{str(e)}'})
    
    return render(request, 'upload.html')

3. 关键优化建议

  • 事务保障:用transaction.atomic()包裹写入逻辑,确保要么全成功要么全失败,避免部分数据导入的混乱情况。
  • 数据校验:如果需要严格校验数据格式(比如价格必须是数字、日期格式正确),可以用Django的序列化器或表单来校验:
    from rest_framework import serializers
    from .models import YourModel
    
    class YourModelSerializer(serializers.ModelSerializer):
        class Meta:
            model = YourModel
            fields = '__all__'
    
    # 在写入时替换循环:
    for item in data_list:
        serializer = YourModelSerializer(data=item)
        serializer.is_valid(raise_exception=True)
        serializer.save()
    
  • 批量创建优化:如果数据量很大(比如上千条),用bulk_create比循环create快10倍以上,但注意bulk_create不会触发模型的save信号,如果你的模型有信号处理逻辑,需要手动处理。
  • 文件大小限制:在settings.py中设置DATA_UPLOAD_MAX_MEMORY_SIZE = 10*1024*1024(限制10MB),或者在view里直接判断csv_file.size。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 13:52:33