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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 05:07:51