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

Django Admin上传Jupyter Notebook转HTML遇MultiValueDictKeyError求助

解决Django上传Jupyter Notebook时的MultiValueDictKeyError问题

我来帮你拆解问题并给出针对性方案——你遇到的MultiValueDictKeyError本质是request.FILES里找不到'notebook'这个键。结合你描述的「在Django Admin上传.json格式的Jupyter Notebook,转换为HTML后传递到模板」的需求,分两种场景处理:


场景1:你想通过前端页面上传文件(对应你当前写的视图逻辑)

如果你的目标是让普通用户通过前端表单上传Notebook,那需要修正以下几点:

1. 完善视图逻辑,避免抛出KeyError

直接用request.FILES['notebook']会在没有上传文件时直接报错,咱们改用get方法做兜底,同时判断请求方法:

# blog/views.py
from django.shortcuts import render
from django.http import HttpResponseBadRequest

def upload_file(request):
    if request.method == 'POST':
        # 用get方法安全获取文件,避免KeyError
        notebook_file = request.FILES.get('notebook')
        if not notebook_file:
            return HttpResponseBadRequest("请选择要上传的Notebook文件")
        # 执行你的转换逻辑
        notebook_html = converter(notebook_file)
        return render(request, 'test.html', context={'html': notebook_html})
    # GET请求时返回上传表单页面
    return render(request, 'upload_form.html')

2. 编写正确的上传表单模板

表单必须设置enctype="multipart/form-data"才能正确传递文件,创建templates/upload_form.html:

<form method="POST" enctype="multipart/form-data">
    {% csrf_token %}
    <input type="file" name="notebook" accept=".json">
    <button type="submit">上传并转换</button>
</form>

场景2:你想在Django Admin后台上传时自动转换(更符合你描述的需求)

如果你的核心需求是管理员在后台上传Notebook后自动转HTML,那应该在Admin层处理转换逻辑,而不是前端视图:

1. 给模型新增字段存储转换后的HTML

先修改模型,添加一个字段来保存转换好的HTML内容:

# blog/models.py
from django.db import models

class FileUploader(models.Model):
    title = models.CharField(max_length=200)
    notebook = models.FileField(upload_to='notebooks/')
    notebook_html = models.TextField(blank=True, null=True)  # 存储转换后的HTML

    def __str__(self):
        return self.title

2. 重写Admin的save_model方法处理转换

在Admin中重写save_model方法,在保存实例时自动执行转换:

# blog/admin.py
from django.contrib import admin
from .models import FileUploader

class FileUploaderAdmin(admin.ModelAdmin):
    def save_model(self, request, obj, form, change):
        # 当新增文件或文件被修改时执行转换
        if obj.notebook:
            # 读取上传的.json文件
            with obj.notebook.open('r') as f:
                notebook_content = f.read()
            # 调用你的转换函数(这里假设converter可以处理文件对象或内容)
            notebook_html = converter(obj.notebook)
            obj.notebook_html = notebook_html
        # 调用父类方法完成保存
        super().save_model(request, obj, form, change)

admin.site.register(FileUploader, FileUploaderAdmin)

3. 编写视图展示转换后的HTML

现在可以写一个视图,根据实例的主键获取转换好的HTML并传递给模板:

# blog/views.py
from django.shortcuts import render, get_object_or_404
from .models import FileUploader

def notebook_page(request, pk):
    # 用get_object_or_404避免找不到实例的错误
    upload_instance = get_object_or_404(FileUploader, pk=pk)
    return render(request, 'test.html', context={'html': upload_instance.notebook_html})

4. 更新URL配置

# blog/urls.py
from django.urls import path
from . import views

urlpatterns = [
    path('notebook/<int:pk>/', views.notebook_page, name='notebook_page'),
]

补充:转换函数的示例实现

如果还没写converter函数,可以用nbconvert库来处理Jupyter Notebook的转换:

from nbconvert import HTMLExporter
import nbformat

def converter(notebook_file):
    # 读取上传的Notebook文件
    nb = nbformat.read(notebook_file, as_version=4)
    # 转换为HTML格式
    exporter = HTMLExporter()
    html_content, _ = exporter.from_notebook_node(nb)
    return html_content

另外注意:模型里的upload_to='./notebooks/'可以简化为'notebooks/',Django会自动处理媒体文件的存储路径。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 21:07:57