Django 中遇到的问题(1)TypeError: context must be a dict rather than Context.

来源:互联网 发布:snmp监控linux 编辑:程序博客网 时间:2024/05/16 23:52

1 . TypeError: context must be a dict rather than Context.

翻译:上下文必须是一个字段,而不是一个Context实例对象
Django版本 1.11
报错的代码来自views.py:

def current_datetime(request):     now = datetime.datetime.now()     t = get_template("ctime.html") ##get_template() 方法可以直接得到人Template 实例     ctx = Context({'now':now})     html = t.render(ctx) #render 传入 ctx 对象做为参数     return HttpResponse(html)

报错信息:
Traceback (most recent call last):
File “D:\python3.6\lib\site-packages\django\core\handlers\exception.py”, line 41, in inner
response = get_response(request)
File “D:\python3.6\lib\site-packages\django\core\handlers\base.py”, line 187, in _get_response
response = self.process_exception_by_middleware(e, request)
File “D:\python3.6\lib\site-packages\django\core\handlers\base.py”, line 185, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File “E:\python_workspace\sfweb\sfweb\books\views.py”, line 18, in current_datetime
html = t.render(ctx)
File “D:\python3.6\lib\site-packages\django\template\backends\django.py”, line 64, in render
context = make_context(context, request, autoescape=self.backend.engine.autoescape)
File “D:\python3.6\lib\site-packages\django\template\context.py”, line 287, in make_context
raise TypeError(‘context must be a dict rather than %s.’ % context.class.name)
TypeError: context must be a dict rather than Context.

错误原因:
代码来自django book 2.0 按理说,书说不应该出错 从stackoverflow 中知道,问题出在版本上
本书基于django 1.1 ,而本机安装最新django 1.11版本

点开D:\python3.6\lib\site-packages\django\template\backends\django.py
从django 1.11源码分析一下 :

class Template(object):    def __init__(self, template, backend):        self.template = template        self.backend = backend    @property    def origin(self):        return self.template.origin    def render(self, context=None, request=None):        context = make_context(context, request, autoescape=self.backend.engine.autoescape)        try:            return self.template.render(context)        except TemplateDoesNotExist as exc:            reraise(exc, self.backend)

context = make_context(context, request, autoescape=self.backend.engine.autoescape)中可以看出 ,render 方法传入的context 参数 做为了make_context()方法中,再看看 make_context()方法的源码:
注意:这里的Template 不是django.template.Template ,参数template 应该是django.template.Template 的实例

def make_context(context, request=None, **kwargs):    """    Create a suitable Context from a plain dict and optionally an HttpRequest.    """    if context is not None and not isinstance(context, dict):        raise TypeError('context must be a dict rather than %s.' % context.__class__.__name__)    if request is None:        context = Context(context, **kwargs)    else:        # The following pattern is required to ensure values from        # context override those from template context processors.        original_context = context        context = RequestContext(request, **kwargs)        if original_context:            context.push(original_context)    return context

从if context is not None and not isinstance(context, dict) 中我们可以判断 ,参数的context() 必须是一个字典类型(到这里,我们就可以确定Template.render()中的context 参数为什么必须是字典了) ,make_context() 返回的是一个Context 或者基子类 RequestContext 实例对象

再回到上面的 render() :返回Template.template.render(Context)
即回到了我们熟悉的 django.template.Template.render(Context)

正确的代码:

def current_datetime(request):     now = datetime.datetime.now()     t = get_template("ctime.html") ##get_template() 方法可以直接得到人Template 实例,但是这个不是django.template.Template实例     #ctx = Context({'now':now})     html = t.render({'now':now})     return HttpResponse(html)

前台正常!!!

阅读全文
5 0
原创粉丝点击