Python中Django 1.11下渲染模板的各种方法的异同点

大神们好,我用的是 django1.11 版,看了官方最新教程,推荐用以下这种方法:

在实际运用中,加载模板、传递参数,返回 HttpResponse 对象是一整套再常用不过的操作了,为了节省力气,Django 提供了一个快捷方式:render 函数,一步到位!看如下代码:

def index(request):
latest_question_list = Question.objects.order_by(’-pub_date’)[:5]
context = {‘latest_question_list’: latest_question_list}
return render(request, ‘polls/index.html’, context)
render()函数的第一个位置参数是请求对象(就是 view 函数的第一个参数),第二个位置参数是模板,还可以有一个可选的第三参数—一个字典,包含需要传递给模板的数据。最后 render 函数返回一个经过字典数据渲染过的模板封装而成的 HttpResponse 对象。

那么问题来了,请问无论是 post 还是 get,都是用这种方法渲染模板吗?我看了其他一些资料有很多不同的方法,例如:
方法 1:
template = get_template(‘mysite/index.html’)
html = template.render(locals())
return HttpResponse(html)

方法 2,如果是 post 方法,则用下面:
template = get_template(‘posting.html’)
request_context = RequestContext(request)
request_context.push(local())
html = template.render(request_context)
return HttpResponse(html)

请问官方推荐的,和方法 1-2 有什么不同?而 get 和 post 方法的模板渲染代码是否不同?是否都可以统一用官方的 render 一步到位的方法???非常感谢!!!!
Python中Django 1.11下渲染模板的各种方法的异同点


8 回复

你写的方法 1 和方法 2 都是很早时候的了吧,现在推荐的是直接类视图或者用 render.
像直接 local()这样不明确的用法,python 语言本身也不是推荐的吧


在Django 1.11中,渲染模板主要有三种方法:render_to_string()render()和直接使用Template对象。它们的核心区别在于使用场景和返回值。

1. render_to_string(template_name, context=None, request=None) 这是最基础的方法,直接返回渲染后的HTML字符串。通常用于需要获取字符串结果后再进行其他处理的场景,比如生成邮件内容或API响应。

from django.template.loader import render_to_string

html_string = render_to_string('my_template.html', {'foo': 'bar'})

2. render(request, template_name, context=None) 这是视图函数中最常用的快捷方式。它内部调用了render_to_string(),但会直接返回一个完整的HttpResponse对象,非常方便。

from django.shortcuts import render

def my_view(request):
    return render(request, 'my_template.html', {'foo': 'bar'})

3. 直接使用Template对象 这是最底层、最灵活的方式。你需要手动加载模板、创建上下文,然后渲染。适用于需要多次渲染同一个模板或进行复杂上下文处理的场景。

from django.template import Template, Context
from django.template.loader import get_template

# 方法A:使用Template类
template = Template('Hello, {{ name }}!')
context = Context({'name': 'World'})
result = template.render(context)

# 方法B:使用get_template加载器(更常用)
template = get_template('my_template.html')
context = {'foo': 'bar'}
result = template.render(context, request) # 可以传入request

核心异同总结:

  • 抽象层级Template对象最底层,render_to_string居中,render最高(专为视图设计)。
  • 返回值render返回HttpResponse;另外两个返回字符串。
  • 主要用途
    • render:标准视图返回。
    • render_to_string:获取模板字符串用于非HTTP场景。
    • Template对象:需要精细控制或性能优化的高级场景。

一句话建议:写普通视图直接用render(),需要模板字符串就用render_to_string(),别手撸Template除非你真需要。

大兄弟,这种是直接看几行源码就能明白的问题。

你的方法 1 和 方法 2 本质的差别在于是否需要在 context 中添加 request。所以你只要明白 django 中这个 request 和
locals() 是什么意思,就知道这两个的区别了。

- locals(): 这是一个 Python 局部命名空间,存在局部变量。
- django 的 request: 这个是 Django Request 的一个实例,主要存储着一些 HTTP 相关一些基本信息。

至于用不用 request 取决你模板中时候要使用,不使用不传也是可以的。

----

其实放出的这两个函数的源码,你就可以看出来和你方法 1 和 方法 2 有什么异同了。

#: django.shortcuts.render
def render(request, template_name, context=None, content_type=None, status=None, using=None):
content = loader.render_to_string(template_name, context, request, using=using)
return HttpResponse(content, content_type, status)

loader 是 django template 的一个代理。
render_to_string 本质就是把 template 转换成字符串。

#: loader.render_to_string
def render_to_string(template_name, context=None, request=None, using=None):
if isinstance(template_name, (list, tuple)):
template = select_template(template_name, using=using)
else:
template = get_template(template_name, using=using)
return template.render(context, request)

明显看出来,你对框架整体架构不是很清楚。
我觉得我的《 Bottle 源码分析》对你会有帮助: https://hexiangyu.me/posts/18

兄弟,那么无论是 post 还是 get,都可以只用 render 吗,还有的您说的类视图是什么意思?

谢谢兄弟。

无论是 post 还是 get,都属于 Request
和你用什么方式 Response 没有必然的联系吧

谢谢。明白了。

render 是对 TemplateResponse 类的包装,TemplateResponse 是对 HttpRespnse 的包装。render 函数和直接构造 TemplateResponse 实例返回是一样的。但无论是 render,还是 TemplateResponse,最终返回的是 HttpRespnse 的实例。

回到顶部