Django实现CSV内存上传转JSON发API并存储返回ID的方案咨询
实现方案
1. 调整模型定义
你只需要存储API返回的请求ID,不需要落地存储CSV完整内容,所以可以替换原有Profile模型为请求记录模型,如果你仍需要保留Profile模型做其他用途,也可以额外新增以下模型:
from django.db import models class ApiRequestRecord(models.Model): request_id = models.CharField(max_length=255, unique=True, verbose_name="API返回的请求ID") create_time = models.DateTimeField(auto_now_add=True, verbose_name="上传时间") def __str__(self): return f"请求ID:{self.request_id},提交时间:{self.create_time}"
记得修改完模型后执行python manage.py makemigrations和python manage.py migrate更新数据库结构。
2. 修改视图逻辑
首先修复你原视图的缩进错误,原有代码中CSV读取逻辑在函数体外,运行会直接报错。修改后的视图会直接读取CSV内容转成目标JSON格式,发送请求到指定API后存储返回的ID。
先安装HTTP请求依赖:pip install requests
修改后的视图代码如下:
import csv, io import requests from django.shortcuts import render from django.contrib import messages from .models import ApiRequestRecord def profile_upload(request): template = "profile_upload.html" # 如果你需要保留展示原有Profile数据的逻辑可以保留以下代码 # data = Profile.objects.all() prompt = { 'order': 'CSV列顺序要求:name, email, address, phone, profile', # 'profiles': data } if request.method == "GET": return render(request, template, prompt) # 校验文件格式 csv_file = request.FILES['file'] if not csv_file.name.endswith('.csv'): messages.error(request, '请上传CSV格式的文件') return render(request, template, prompt) # 读取CSV内容转目标JSON格式 data_set = csv_file.read().decode('UTF-8') io_string = io.StringIO(data_set) # 用DictReader直接按表头映射字段,不需要按索引取值 csv_reader = csv.DictReader(io_string, delimiter=',', quotechar='"') people_records = [] for row in csv_reader: people_records.append({ "name": row['name'], "email": row['email'], "address": row['address'], "phone": row['phone'], "profile": row['profile'] }) post_data = {"peopleRecords": people_records} # 如果你需要保留每次上传清空Profile表的逻辑,这里可以加 # Profile.objects.all().delete() # 发送请求到目标API try: # 替换为你实际对接的API地址,需要鉴权的话自行添加headers参数 api_response = requests.post( url="YOUR_TARGET_API_URL", json=post_data, timeout=30 ) api_response.raise_for_status() # 假设API返回的JSON结构中id字段为请求ID,根据实际返回结构修改取值逻辑 request_id = api_response.json()['id'] # 存储请求ID ApiRequestRecord.objects.create(request_id=request_id) messages.success(request, f"提交成功,请求ID为:{request_id},可使用该ID查询后续结果") except Exception as e: messages.error(request, f"提交失败:{str(e)}") context = prompt return render(request, template, context)
3. 可选调整模板
如果需要保留展示历史请求ID的逻辑,可以在模板中添加对应展示代码,也可以保持原有模板不变,现有模板已经支持展示操作成功/失败的提示信息。
注意事项
- 请将代码中的
YOUR_TARGET_API_URL替换为你实际要对接的API地址 - 如果对接的API需要鉴权(比如token、签名等),请在
requests.post的headers参数中添加对应的鉴权信息 - 可以根据业务需要调整异常捕获逻辑,处理API请求超时、返回错误的场景,给用户更明确的提示
内容的提问来源于stack exchange,提问作者Steve
相关产品推荐
相关产品推荐

