作者djshen (djshen)
看板Python
标题Re: [问题] Django {% csrf_token %}
时间Fri Aug 4 22:25:01 2017
先来看看csrf_token做了什麽事
django.template.defaulttags.csrf_token
#1
http://imgur.com/zF9wpKH
django.template.defaulttags.CsrfTokenNode.render
#2
http://imgur.com/wFTXzR1
注意这边的context.get('csrf_token')
也就是说context里面要有'csrf_token'
csrf_token template tag才会有东西
那context里面的csrf_token从何而来?
如果你有稍微看过settings.py的话
应该会在TEMPLATES里面发现context_processors
这些context processor会自动加东西在context
所以csrf_token应该也是利用context processor加进去的
然後你认真翻了一下source code发现
在django.template.context_processors有个csrf
#3
http://imgur.com/o64Vp1n
这边他确实产生了csrf_token
但是settings.py里面却没有这个context processor
於是你更认真翻source code
发现django.template.context定义了
_builtin_context_processors = ('django.template.context_processors.csrf',)
#4
http://imgur.com/lQhUVv3
而这个东西被用在django.template.engine.Engine.template_context_processors
#5
http://imgur.com/LbcOIq1
到这边我们了解csrf context processor是自动加进去的
而上面这些和你的问题有什麽关系?
※ 引述《left (881 forever)》之铭言:
: template = get_template('posting.html')
django.template.loader.get_template
#6
http://imgur.com/mixZLEu
他会return django.template.backends.django.DjangoTemplates.get_template()
也就是django.template.backends.django.Template
#7
http://imgur.com/KOFVrUx
这边跳了几步 不过不影响
: request_context = RequestContext(request)
: request_context.push(locals())
: html = template.render(request_context)
这边call上图的Template.render
然後是django.template.context.make_context
#8
http://imgur.com/jql8ohU
注意传进去的参数 request=None
使得回传的是django.template.context.Context
而不是RequestContext
差别在於#7执行到self.template.render(context)
跳到django.template.base.Template.render
#9
http://imgur.com/tqg1vbf
context.bind_template(self)
比较一下Context和RequestContext的bind_template
Context:
#10
http://imgur.com/M8T1kn4
RequestContext:
#11
http://imgur.com/KysHULW
有没有看到一个熟悉的东西 template.engine.template_context_processors
刚才我们知道这里面有csrf context processor
所以当传入django.template.base.Template.render的context是Context的时候
就不会有csrf_token
: return HttpResponse(html)
: 也就是改成
: return render(request, ‘posting.html’,locals())
那我们来看这边做了什麽
django.shortcuts.render
call django.template.loader.render_to_string
#12
http://imgur.com/rgUnbMu
django.template.loader.get_template
拿到django.template.backends.django.Template
和上面一样
但这边有把request传给render
造成make_context有拿到request所以回传RequestContext
剩下的上面都讲过了
: 结果错误讯息就不见了
: 我想要问各位大大,书上的写法有错吗?
: 如果有,要怎麽用RequestContext以及template.render()改到对?
: 如果没有,我是死在哪边? xd
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 114.32.8.146
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/Python/M.1501856704.A.1BC.html
1F:推 Sunal: 推推 08/04 22:42
2F:→ uranusjr: 欸其实上面那个也有传 request, 也有呼叫 make_context 08/04 22:47
3F:→ uranusjr: 真正的重点在上下两个 template.render 是不一样的 08/04 22:47
4F:→ djshen: make_context的request是从Template.render里面传过来 08/04 22:48
5F:→ uranusjr: 所以这样解释原 po 应该会觉得怪, 但我也不知道该怎麽讲 08/04 22:49
6F:→ uranusjr: 然後原本程式其实改 template.template.render(context) 08/04 22:49
7F:→ uranusjr: 就会过了我觉得要 trace 的话应该要解释一下 XDDD 08/04 22:50
8F:→ djshen: html = template.render(request_context)这边没传request 08/04 22:50
9F:→ djshen: 我觉得新手应该不需要了解那麽深啦.. 08/04 22:50
10F:→ djshen: 没传request造成传给make_context的request也是None 08/04 22:51
11F:→ uranusjr: 是这样没错啦, 不过原书乱挖坑我觉得讲一半就不太好, 要 08/04 22:54
12F:→ uranusjr: 嘛就不要讲要嘛就整个脉络要搞清楚; 这整件事最让我无法 08/04 22:55
13F:→ uranusjr: 理解的是这书竟然在第八页讲这个主题, 到底在搞什麽鬼 08/04 22:55
14F:推 Sunal: 其实django的tutorial对新手就很够用了 08/04 22:59
16F:→ djshen: 之前会检查type 08/04 23:08
17F:推 Yshuan: 推 这篇超实用 08/06 01:58
18F:推 karta0910489: 推 08/06 02:45
19F:推 Aquatics: 推 10/17 16:20