请教 django 1.11 下渲染模板的各种方法的异同点

2017-06-01 10:12:56 +08:00
 garygay
大神们好,我用的是 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 一步到位的方法???非常感谢!!!!
4262 次点击
所在节点    Python
7 条回复
mapleray
2017-06-01 10:20:06 +08:00
你写的方法 1 和方法 2 都是很早时候的了吧,现在推荐的是直接类视图或者用 render.
像直接 local()这样不明确的用法,python 语言本身也不是推荐的吧
zhengxiaowai
2017-06-01 10:39:01 +08:00
大兄弟,这种是直接看几行源码就能明白的问题。

你的方法 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
garygay
2017-06-01 10:44:11 +08:00
@mapleray 兄弟,那么无论是 post 还是 get,都可以只用 render 吗,还有的您说的类视图是什么意思?
garygay
2017-06-01 10:45:28 +08:00
@zhengxiaowai 谢谢兄弟。
Revenant
2017-06-01 11:01:29 +08:00
无论是 post 还是 get,都属于 Request
和你用什么方式 Response 没有必然的联系吧
garygay
2017-06-01 11:21:06 +08:00
@Revenant 谢谢。明白了。
chuanqirenwu
2017-06-01 11:33:46 +08:00
render 是对 TemplateResponse 类的包装,TemplateResponse 是对 HttpRespnse 的包装。render 函数和直接构造 TemplateResponse 实例返回是一样的。但无论是 render,还是 TemplateResponse,最终返回的是 HttpRespnse 的实例。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/365118

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX