Django render报错context must be a dict rather than DataFrame
问题修复方案
核心错误点
render()函数第三个参数强制要求传入字典类型,字典的键为模板中可调用的变量名,值为传递给模板的实际数据,直接传入pandas DataFrame必然触发context must be a dict rather than DataFrame报错。- 变量名覆盖内置类型:代码中将读取的词典DataFrame命名为
dict,直接覆盖Python内置的字典构造类,这是你之前尝试手动转dict时持续触发异常的核心原因。 - 类视图写法不规范:类视图中的请求处理方法需要绑定对应请求类型(get/post),且第一个参数必须为
self,直接将类中方法单独挂载到路由会跳过类视图的调度逻辑,触发参数匹配错误。 - 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
相关产品推荐
相关产品推荐

