看板 Python 關於我們 聯絡資訊
先來看看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
Sunal: 推推 08/04 22:42
uranusjr: 欸其實上面那個也有傳 request, 也有呼叫 make_context 08/04 22:47
uranusjr: 真正的重點在上下兩個 template.render 是不一樣的 08/04 22:47
djshen: make_context的request是從Template.render裡面傳過來 08/04 22:48
uranusjr: 所以這樣解釋原 po 應該會覺得怪, 但我也不知道該怎麼講 08/04 22:49
uranusjr: 然後原本程式其實改 template.template.render(context) 08/04 22:49
uranusjr: 就會過了我覺得要 trace 的話應該要解釋一下 XDDD 08/04 22:50
djshen: html = template.render(request_context)這邊沒傳request 08/04 22:50
djshen: 我覺得新手應該不需要了解那麼深啦.. 08/04 22:50
djshen: 沒傳request造成傳給make_context的request也是None 08/04 22:51
uranusjr: 是這樣沒錯啦, 不過原書亂挖坑我覺得講一半就不太好, 要 08/04 22:54
uranusjr: 嘛就不要講要嘛就整個脈絡要搞清楚; 這整件事最讓我無法 08/04 22:55
uranusjr: 理解的是這書竟然在第八頁講這個主題, 到底在搞什麼鬼 08/04 22:55
Sunal: 其實django的tutorial對新手就很夠用了 08/04 22:59
djshen: 看起來是1.10改的 https://goo.gl/MtJ3Z2 08/04 23:06
djshen: 之前會檢查type 08/04 23:08
Yshuan: 推 這篇超實用 08/06 01:58
karta0910489: 推 08/06 02:45
Aquatics: 推 10/17 16:20