V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
garygay
V2EX  ›  Python

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

  •  
  •   garygay · 2017-06-01 10:12:56 +08:00 · 4400 次点击
    这是一个创建于 2735 天前的主题,其中的信息可能已经有所发展或是发生改变。
    大神们好,我用的是 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 一步到位的方法???非常感谢!!!!
    7 条回复    2017-06-01 11:33:46 +08:00
    mapleray
        1
    mapleray  
       2017-06-01 10:20:06 +08:00   ❤️ 1
    你写的方法 1 和方法 2 都是很早时候的了吧,现在推荐的是直接类视图或者用 render.
    像直接 local()这样不明确的用法,python 语言本身也不是推荐的吧
    zhengxiaowai
        2
    zhengxiaowai  
       2017-06-01 10:39:01 +08:00   ❤️ 2
    大兄弟,这种是直接看几行源码就能明白的问题。

    你的方法 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
        3
    garygay  
    OP
       2017-06-01 10:44:11 +08:00
    @mapleray 兄弟,那么无论是 post 还是 get,都可以只用 render 吗,还有的您说的类视图是什么意思?
    garygay
        4
    garygay  
    OP
       2017-06-01 10:45:28 +08:00
    @zhengxiaowai 谢谢兄弟。
    Revenant
        5
    Revenant  
       2017-06-01 11:01:29 +08:00
    无论是 post 还是 get,都属于 Request
    和你用什么方式 Response 没有必然的联系吧
    garygay
        6
    garygay  
    OP
       2017-06-01 11:21:06 +08:00
    @Revenant 谢谢。明白了。
    chuanqirenwu
        7
    chuanqirenwu  
       2017-06-01 11:33:46 +08:00   ❤️ 1
    render 是对 TemplateResponse 类的包装,TemplateResponse 是对 HttpRespnse 的包装。render 函数和直接构造 TemplateResponse 实例返回是一样的。但无论是 render,还是 TemplateResponse,最终返回的是 HttpRespnse 的实例。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1066 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 22:07 · PVG 06:07 · LAX 14:07 · JFK 17:07
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.