Django 1.11.17 TypeError:'上下文必须是字典而不是上下文',除了它是字典
Posted
技术标签:
【中文标题】Django 1.11.17 TypeError:\'上下文必须是字典而不是上下文\',除了它是字典【英文标题】:Django 1.11.17 TypeError: 'context must be a dict rather than Context', except IT IS A DICTDjango 1.11.17 TypeError:'上下文必须是字典而不是上下文',除了它是字典 【发布时间】:2019-05-08 11:39:37 【问题描述】:我最近从 Django 1.9 切换到 1.11.17,有一件事让我很困扰。有这个错误说
TypeError at /somepath
context must be a dict rather than Context
抛出它的那一行是:
return render(request=request, template_name="mytemplate.html", context="form": form, "update": updateType)
关于 SO 有很多答案,人们使用 RequestContext 或 Context 而不是 dict 来表示 context
并且切换到 dict 可以解决他们的问题。但不适合我。在这里,我很确定我的context
实际上是一个字典。如果我将其更改为:
return render(request=request, template_name="mytemplate.html", context=)
错误消失了,但显然稍后会导致另一个错误。你们知道我在这里做错了什么吗?
编辑: 我的进口:
from django.shortcuts import render, render_to_response
from django.template.context import RequestContext, Context
我尝试过 bot render
和 render_to_response
具有类似的效果。也使用 Context 或 RequestContext 给出了类似的错误。
EDIT2:更多代码供参考
from django.http import (
HttpResponseRedirect,
HttpResponseBadRequest,
)
from django.shortcuts import render, render_to_response
from django.template import RequestContext, Context
from django.utils.html import escape
# some more imports, but from local files, not django
def update_my_template(request):
user = request.user
# preform some checks for user
...
if request.method == "GET":
updateType = request.GET.get("id")
if updateType:
form = None
if updateType == "something":
form = SomeForm(user)
if updateType == "something else":
form = DifferentForm()
if form is None:
return HttpResponseRedirect("/somepage")
# This was the code that worked in 1.9
rctx = RequestContext(
request, "form": form, "update": updateType
)
return render_to_response("mytemplate.html", rctx)
# some different cases, but the error is thrown already
...
这些都不起作用:
dictctx = "form": form, "update": updateType
return render(request=request, template_name="mytemplate.html", dictctx)
.
ctx = Context("form": form, "update": updateType)
return render(request=request, template_name="mytemplate.html", ctx)
.
ctx = Context("form": form, "update": updateType)
return render(request=request, template_name="mytemplate.html", ctx.flatten())
.
rctx = RequestContext(request, "form": form, "update": updateType)
return render_to_response("mytemplate.html", rctx.flatten())
【问题讨论】:
只是为了确保我的假设是正确的,您可以编辑您的问题并添加您对Context
和render
的导入吗?
当然,一秒钟
如果您将from django.template.context
更改为from django.template
,我下面的代码是否有效?
不幸的是,from django.template.context
或 from django.template
似乎没有任何区别
【参考方案1】:
render
的逻辑有所不同,具体取决于您传递给render
的内容:
def render(self, context):
"Display stage -- can be called many times"
with context.render_context.push_state(self):
if context.template is None:
with context.bind_template(self):
context.template_name = self.name
return self._render(context)
else:
return self._render(context)
看起来您可以将参数 template_name
更改为 name
但您的对象没有 context.render_context
值,这就是为什么创建和使用实例会更好的原因Context
https://docs.djangoproject.com/en/1.11/_modules/django/template/base/#Template.render
文档显示传递了 Context
的实际实例,因此我建议您在代码中这样做,而不仅仅是传递字典:
>>> from django.template import Context, Template
>>> template = Template("My name is my_name .")
>>> context = Context("my_name": "Adrian")
>>> template.render(context)
"My name is Adrian."
>>> context = Context("my_name": "Dolores")
>>> template.render(context)
所以修复代码的最简单方法是这样的:
from django.template import Context
...
return render(request=request, template_name="mytemplate.html", context=Context("form": form, "update": updateType))
【讨论】:
我试过这个没有效果: ctx = Context("form": form, "update": updateType) return render(request=request, template_name="mytemplate.html", context =ctx) 你见过this 吗?它基本上是说在将任何RequestContext
对象传递给渲染之前调用.flatten()
是的,在问我之前已经尝试过其他答案:(同样的错误
我想这一定是一些超级愚蠢的错误,因为我已经尝试了所有可能性,而且我的代码看起来与其他 SO 答案中发布的代码相同。
您能否编辑您的答案并从该文件中添加尽可能多的代码?我唯一能想到的是,它可能是文件中的其他内容【参考方案2】:
始终在参数中传递变量/值。但你同时给予两者。试试这个,...
返回渲染(request=request, template_name="mytemplate.html", "form": 表单, "update": updateType)
或者
context="form": form, "update": updateType 返回 渲染(request=request, template_name="mytemplate.html",context)
【讨论】:
我看不出您的第一个解决方案与我的解决方案有什么区别。另外我已经尝试过第二个,没有区别:/ @Devligue 在我的第一个解决方案中,我只是传递了元组,而在我的第二个解决方案中,我只是传递了元组类型的变量,但不幸的是你同时传递了这两个。这是一个逻辑错误 但是你确实看到你在关键字参数之后传递了位置参数?这段代码甚至不能在 python 中运行,它立即抛出错误【参考方案3】:好的,经过更多挖掘(在“未解决”问题中)我找到了this gem。是的,这就是我的问题的解决方案。基本上我的mytemplate.html
中有form|bootstrap
行,这是造成这种情况的原因。
更好的是,将 django-bootstrap-form
更新到 3.4 版让我可以保留 form|bootstrap
并摆脱错误。
【讨论】:
以上是关于Django 1.11.17 TypeError:'上下文必须是字典而不是上下文',除了它是字典的主要内容,如果未能解决你的问题,请参考以下文章
django:TypeError:'tuple'对象不可调用
Django TypeError - TypeError: issubclass() arg 1 必须是一个类
Django:“TypeError:[] 不是 JSON 可序列化的”为啥?
Django 预览,TypeError:'str' 对象不可调用