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

如何使用Django QuerySet将JSON中的商品数据存入数据库

解决Django中bulk_create存入items_data的错误问题

问题场景

现有如下JSON数据,需要提取其中的items_data字段,通过Django QuerySet存入数据库:

{
    "items_data": [
        {"item": "Datalogger", "hsn": "123", "unit_name": "BAG", "unit_price": "100", "quantity": "4",
         "tax_code": "GST 18", "base_discount": "4", "discount_value": 16, "amount": 384, "state": "Maharashtra",
         "invoice_number": "TES-0822-97", "tax_no": "18", "tax_name": "GST", "base_Amount": 400, "CGST": 36, "SGST": 36}, 

        {"item": "Datalogger", "hsn": "123", "unit_name": "BAG", "unit_price": "100", "quantity": "4", 
         "tax_code": "GST 28", "base_discount": "4", "discount_value": 16, "amount": 384, "state": "Maharashtra",
         "invoice_number": "TES-0822-97", "tax_no": "28", "tax_name": "GST", "base_Amount": 400, "CGST": 56, "SGST": 56}
    ],
    "invoice_num": "TES-0822-97",
    "gst_data": [
        {"tax_no": "18", "totalGST": 72, "total_base_amount": 400, "cgst": 36, "sgst": 36},
        {"tax_no": "28", "totalGST": 112, "total_base_amount": 400, "cgst": 56, "sgst": 56}
    ]
}

原代码实现如下,运行时出现错误:

def get_invoice_items(request):
    json_body = json.loads(request.body)
    print(json_body)
    for data in json_body["items_data"]:
        print(data)
        items=Items_Details.objects.bulk_create(data)
        print(items)
    return JsonResponse({"message" : "Request Handled.."})

错误原因

  1. bulk_create()方法要求传入模型实例的列表,而非单个字典,原代码循环中直接传单个字典,不符合方法参数要求。
  2. 循环中逐个调用bulk_create完全浪费了批量插入的性能优势,反而不如直接使用create()方法。

正确实现代码

方式1:批量插入(推荐)

先将所有items_data转换为Items_Details模型实例,再一次性调用bulk_create完成批量插入,大幅提升效率:

import json
from django.http import JsonResponse
from .models import Items_Details  # 确保导入你的模型

def get_invoice_items(request):
    # 仅处理POST请求
    if request.method != 'POST':
        return JsonResponse({"message": "仅支持POST请求"}, status=400)
    
    try:
        json_body = json.loads(request.body)
        items_data = json_body.get("items_data", [])
        
        # 转换为模型实例列表
        item_instances = []
        for data in items_data:
            # 注意:JSON中的键名必须和Items_Details模型的字段名完全匹配
            # 如果模型字段是小写(如base_amount、cgst),需要先调整键名:
            # data["base_amount"] = data.pop("base_Amount")
            # data["cgst"] = data.pop("CGST")
            # data["sgst"] = data.pop("SGST")
            
            instance = Items_Details(**data)
            item_instances.append(instance)
        
        # 执行批量插入
        Items_Details.objects.bulk_create(item_instances)
        return JsonResponse({"message": "数据批量插入成功"}, status=201)
    
    except json.JSONDecodeError:
        return JsonResponse({"message": "JSON格式错误"}, status=400)
    except Exception as e:
        return JsonResponse({"message": f"插入失败:{str(e)}"}, status=500)

方式2:逐个插入(适合少量数据)

如果数据量较小,也可以用create()逐个插入:

import json
from django.http import JsonResponse
from .models import Items_Details

def get_invoice_items(request):
    if request.method != 'POST':
        return JsonResponse({"message": "仅支持POST请求"}, status=400)
    
    try:
        json_body = json.loads(request.body)
        items_data = json_body.get("items_data", [])
        
        for data in items_data:
            # 同样需要确保字段名匹配,必要时调整键名
            Items_Details.objects.create(**data)
        
        return JsonResponse({"message": "数据插入成功"}, status=201)
    
    except json.JSONDecodeError:
        return JsonResponse({"message": "JSON格式错误"}, status=400)
    except Exception as e:
        return JsonResponse({"message": f"插入失败:{str(e)}"}, status=500)

关键注意事项

  • 字段名匹配:JSON中的键名必须和Items_Details模型的字段名完全一致(包括大小写),如果不一致,需要提前转换键名。
  • 数据类型校验:检查JSON中的数据类型是否和模型字段类型匹配(比如unit_price如果模型是IntegerField,需要将字符串转为整数)。
  • 异常处理:添加JSON解析、数据库操作的异常捕获,返回明确的错误信息便于排查。
  • 批量插入优势:bulk_create会一次性执行SQL插入语句,比循环调用create减少数据库交互次数,适合大量数据插入场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 20:15:40