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

Django render报错context must be a dict rather than DataFrame

问题修复方案

核心错误点

  1. render()函数第三个参数强制要求传入字典类型,字典的键为模板中可调用的变量名,值为传递给模板的实际数据,直接传入pandas DataFrame必然触发context must be a dict rather than DataFrame报错。
  2. 变量名覆盖内置类型:代码中将读取的词典DataFrame命名为dict,直接覆盖Python内置的字典构造类,这是你之前尝试手动转dict时持续触发异常的核心原因。
  3. 类视图写法不规范:类视图中的请求处理方法需要绑定对应请求类型(get/post),且第一个参数必须为self,直接将类中方法单独挂载到路由会跳过类视图的调度逻辑,触发参数匹配错误。
  4. DataFrame初始化逻辑隐患:初始化结果DataFrame时用集合传入列名,集合本身无序,会导致后续拼接数据时出现列对齐错位问题。

修复后代码

views.py

from django.views import View
from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator
import pandas as pd
from konlpy.tag import Hannanum, Okt

# 全局加载词典和分词器,避免每次请求重复IO加载,提升响应速度
hannanum = Hannanum()
okt = Okt()
dialect_dict = pd.read_csv(
    "C:\\Users\\user\\jeju-dialect-translation\\jeju\\dialect\\dict2.csv",
    sep=",",
    encoding='cp949'
)

@method_decorator(csrf_exempt, name='dispatch')
class Postview(View):
    def get(self, request):
        # 处理GET访问,返回带输入表单的主页面
        return render(request, 'dialect/main.html')

    def post(self, request):
        content = request.POST.get('content', '').strip()
        if not content:
            return render(request, 'dialect/main.html', {'error': '请输入待翻译的方言内容'})

        nouns = hannanum.nouns(content)
        stem = okt.morphs(content, stem=True)

        single_char_tempt = []
        for morpheme in stem:
            if len(morpheme) == 1:
                single_char_tempt.append(morpheme)
        adjective = list(set(stem) - set(single_char_tempt))

        # 用列表固定列顺序初始化结果集,禁止用无序集合传columns参数
        results = pd.DataFrame(columns=['siteName', 'contents'])

        for noun in nouns:
            match_noun = dialect_dict[dialect_dict['siteName'] == noun][['siteName', 'contents']]
            results = pd.concat([results, match_noun], axis=0)

        for adj in adjective:
            match_adj = dialect_dict[dialect_dict['siteName'].str.match(adj, na=False)]
            results = pd.concat([results, match_adj], axis=0)

        # 去重后转成模板易遍历的记录列表格式,包装成标准context字典
        final_trans = results.drop_duplicates().to_dict('records')
        context = {
            'input_content': content,
            'translate_results': final_trans
        }

        # 直接返回主页面模板,实现提交后结果在原页面底部展示的效果,无需单独跳转结果页
        return render(request, 'dialect/main.html', context)

urls.py

不需要单独为success方法配置路由,所有请求统一走类视图调度即可:

from django.urls import path
from django.contrib import admin
from . import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('dialect/', views.Postview.as_view(), name='main_page'),
]

模板适配示例

在原表单页面(dialect/main.html)的原有表单代码下方,添加结果渲染区块即可实现底部展示效果:

<!-- 原有提交表单保持不动,提交地址指向主页面路由 -->
<form method="post" action="{% url 'main_page' %}">
    {% csrf_token %}
    <textarea name="content" placeholder="请输入济州岛方言内容">{{ input_content }}</textarea>
    <button type="submit">Submit</button>
</form>

<!-- 结果展示区 -->
{% if error %}
<p style="color: #ff4444; margin: 10px 0;">{{ error }}</p>
{% endif %}

{% if translate_results %}
<div style="margin-top: 20px; padding: 15px; border: 1px solid #eee;">
    <h3>翻译匹配结果</h3>
    <ul style="list-style: none; padding: 0;">
        {% for item in translate_results %}
        <li style="padding: 8px 0; border-bottom: 1px solid #f0f0f0;">
            <strong>{{ item.siteName }}</strong>:{{ item.contents }}
        </li>
        {% endfor %}
    </ul>
</div>
{% endif %}

注意:DataFrame.to_dict('records')会把结果转换成[{'siteName': '方言词', 'contents': '翻译释义'}, ...]的列表结构,是Django模板循环渲染最方便的格式,不要使用默认的to_dict()(会返回列名嵌套索引的多层字典结构,模板遍历逻辑复杂)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 22:18:56