Django中无法获取上传JSON文件数据及D3.js可视化异常问题
问题解决:JSON文件上传可视化及Admin模型报错
一、Admin页面JSONFile模型报错修复
1. 原因
JSONFile模型的user字段为必填外键,但通过Admin添加记录时未自动关联当前登录用户;同时原视图仅读取文件内容,未将上传记录保存到数据库,导致Admin无数据或保存时缺失user字段报错。
2. 解决方案
(1)修改Admin配置自动填充用户
在admin.py中注册JSONFile模型并自定义保存逻辑:
from django.contrib import admin from .models import JSONFile @admin.register(JSONFile) class JSONFileAdmin(admin.ModelAdmin): list_display = ('id', 'user', 'files', 'uploaded_at') def save_model(self, request, obj, form, change): # 新增记录时自动设置当前用户 if not obj.pk: obj.user = request.user super().save_model(request, obj, form, change)
(2)修复视图保存逻辑
修改views.py,将上传文件保存到数据库并关联当前用户:
import json from django.shortcuts import render from .forms import JSONFileUploadForm def home(request): if request.method == 'POST': form = JSONFileUploadForm(request.POST, request.FILES) if form.is_valid(): # 创建模型对象并关联用户 json_file = form.save(commit=False) json_file.user = request.user json_file.save() # 读取已保存的文件内容 with json_file.files.open('r') as f: json_data = json.load(f) json_str = json.dumps(json_data) return render(request, 'visualization.html', {'json_str': json_str}) else: form = JSONFileUploadForm() return render(request, 'home.html', {'form': form})
二、visualization.html无法展示内容修复
1. 原因
仅定义了jsonData变量但未编写D3可视化绘制逻辑;同时JSON字符串传递可能存在引号转义问题。
2. 解决方案
修改visualization.html,添加D3绘制代码并优化JSON传递方式:
<h2>Data Visualization</h2> <div id="visualization"></div> <script src="https://d3js.org/d3.v7.min.js"></script> <script> // 使用escapejs确保JSON字符串转义正确 var jsonData = JSON.parse('{{ json_str|escapejs }}'); // 示例:绘制柱状图(根据你的实际数据结构调整) const width = 600; const height = 400; const margin = {top: 20, right: 30, bottom: 40, left: 90}; const svg = d3.select("#visualization") .append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("g") .attr("transform", `translate(${margin.left},${margin.top})`); // 假设jsonData为[{name: "类别1", value: 20}, ...]格式 const xScale = d3.scaleLinear() .domain([0, d3.max(jsonData, d => d.value)]) .range([0, width]); const yScale = d3.scaleBand() .domain(jsonData.map(d => d.name)) .range([0, height]) .padding(0.1); // 添加X轴 svg.append("g") .attr("transform", `translate(0,${height})`) .call(d3.axisBottom(xScale)); // 添加Y轴 svg.append("g") .call(d3.axisLeft(yScale)); // 绘制柱子 svg.selectAll("rect") .data(jsonData) .enter() .append("rect") .attr("x", 0) .attr("y", d => yScale(d.name)) .attr("width", d => xScale(d.value)) .attr("height", yScale.bandwidth()) .attr("fill", "#4285F4"); </script>
3. 额外检查
确保项目settings.py已正确配置media路径:
MEDIA_ROOT = BASE_DIR / 'media' MEDIA_URL = '/media/'
并在urls.py中添加media路由:
from django.conf import settings from django.conf.urls.static import static urlpatterns = [ # 你的其他路由配置 ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
内容的提问来源于stack exchange,提问作者Shreyash mishra
相关产品推荐
相关产品推荐

