Re: [問題] Django {% csrf_token %}

看板Python作者 (djshen)時間8年前 (2017/08/04 22:25), 編輯推噓5(5014)
留言19則, 6人參與, 最新討論串2/2 (看更多)
先來看看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://www.ptt.cc/bbs/Python/M.1501856704.A.1BC.html

08/04 22:42, , 1F
推推
08/04 22:42, 1F

08/04 22:47, , 2F
欸其實上面那個也有傳 request, 也有呼叫 make_context
08/04 22:47, 2F

08/04 22:47, , 3F
真正的重點在上下兩個 template.render 是不一樣的
08/04 22:47, 3F

08/04 22:48, , 4F
make_context的request是從Template.render裡面傳過來
08/04 22:48, 4F

08/04 22:49, , 5F
所以這樣解釋原 po 應該會覺得怪, 但我也不知道該怎麼講
08/04 22:49, 5F

08/04 22:49, , 6F
然後原本程式其實改 template.template.render(context)
08/04 22:49, 6F

08/04 22:50, , 7F
就會過了我覺得要 trace 的話應該要解釋一下 XDDD
08/04 22:50, 7F

08/04 22:50, , 8F
html = template.render(request_context)這邊沒傳request
08/04 22:50, 8F

08/04 22:50, , 9F
我覺得新手應該不需要了解那麼深啦..
08/04 22:50, 9F

08/04 22:51, , 10F
沒傳request造成傳給make_context的request也是None
08/04 22:51, 10F

08/04 22:54, , 11F
是這樣沒錯啦, 不過原書亂挖坑我覺得講一半就不太好, 要
08/04 22:54, 11F

08/04 22:55, , 12F
嘛就不要講要嘛就整個脈絡要搞清楚; 這整件事最讓我無法
08/04 22:55, 12F

08/04 22:55, , 13F
理解的是這書竟然在第八頁講這個主題, 到底在搞什麼鬼
08/04 22:55, 13F

08/04 22:59, , 14F
其實django的tutorial對新手就很夠用了
08/04 22:59, 14F

08/04 23:06, , 15F
看起來是1.10改的 https://goo.gl/MtJ3Z2
08/04 23:06, 15F

08/04 23:08, , 16F
之前會檢查type
08/04 23:08, 16F

08/06 01:58, , 17F
推 這篇超實用
08/06 01:58, 17F

08/06 02:45, , 18F
08/06 02:45, 18F

10/17 16:20, , 19F
10/17 16:20, 19F
文章代碼(AID): #1PX8F06y (Python)
討論串 (同標題文章)
文章代碼(AID): #1PX8F06y (Python)