如何使用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.."})
错误原因
bulk_create()方法要求传入模型实例的列表,而非单个字典,原代码循环中直接传单个字典,不符合方法参数要求。- 循环中逐个调用
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
相关产品推荐
相关产品推荐

