Django筆記 —— 表單(form)

  最近在學習Django,打算玩玩網頁後臺方面的東西,由於一直很好奇但卻沒怎麼接觸過。Django對我來講是一個全新的內容,思路想來也是全新的,或許並不能寫得很明白,因此你們就湊合着看吧~html

  本篇筆記(其實個人全部筆記都是),並不會過於詳細的講解。所以若是有你們看不明白的地方,歡迎在我正版博客下留言,有時間的時候我很願意來這裏與你們探討問題。(固然,不能是簡簡單單就能夠百度到的問題-.-)python

  我所選用的教材是《The Django Book 2.0》,本節是表單部分,對應書中第七章。linux

------------------------------------------------------------------------------------------------------------------------------------------------web

0、閱讀方法數據庫

  本節筆記,略去不少書中學習過程與講解,建議在看完原書此節後,做總結複習之用。django

  站點建立:django-admin.py startproject comebackubuntu

一、視圖中的HttpResponse瀏覽器

  首先給咱們的代碼加上一個視圖,網址是"http://127.0.0.1:8000/",網站內容就是一個Hello World。安全

  顯然,其在"/comeback/views.py"中的代碼內容是:bash

from django.http import HttpResponse

def hello(request):
    return HttpResponse("Hello World")

  其中,HttpResponse對象,即request變量,是有不少成員(屬性和方法)的。經過他們,你能夠知道不少信息,例如:正在加載這個頁面的用戶是誰,他用的是什麼瀏覽器。

  這裏列舉一些屬性:

成員 說明 舉例
request.path 除域名之外的請求路徑,以斜槓(即 /)開頭 」/hello/「
request.get_host() 主機名(例如:一般所說的域名) "127.0.0.1" or "www.example.com"
request.get_full_path() 請求路徑,可能包含查詢字符串 "/hello/?print=true"
request.is_secure() 若是經過https訪問,返回True;不然,返回False True or False

  還有一個屬性要重點說明,request.META,這是一個python字典,包含了全部本次HTTP請求的Header信息。這個信息是由用戶的瀏覽器所提交的:

成員 說明 備註
HTTP_REFERER 進站前連接網頁(若是有的話) 這是REFERRER的筆誤-.-|||
HTTP_USER_AGENT 用戶瀏覽器的user-agent字符串(若是有的話) 詳見這一篇博文
REMOTE_ADDR 客戶端IP 若是通過代理服務器,那麼是逗號分割的多個IP地址

  應當注意,既然是用戶瀏覽器提交的,這個信息也就不必定靠譜。所以,應當使用下列方式讀取其中內容:

    1. 使用 try / except 語句

def ua_display_good1(request):
    try:
        ua = request.META['HTTP_USER_AGENT']
    except KeyError:
        ua = 'unknown'
    return HttpResponse("Your browser is %s" % ua)

    2. 使用 python字典的 get()方法(推薦)

def ua_display_good2(request):
    ua = request.META.get('HTTP_USER_AGENT', 'unknown')
    return HttpResponse("Your browser is %s" % ua)

  書中建議,你寫一個函數,把request.META中全部數據打印出來看看,好比這樣

1 def display_meta(request):
2     values = request.META.items()
3     values.sort()
4     html = []
5     for k, v in values:
6         html.append('<tr><td>%s</td><td>%s</td></tr>' % (k, v))
7     return HttpResponse('<table>%s</table>' % '\n'.join(html))

  request.META的內容太多了,我把其內容作了初步的整理和翻譯,有興趣的同窗能夠到本節末尾附錄中看。

  固然,也能夠用模板實現,而非手動輸入代碼,這裏很少說。

  request中,還有兩個屬性,內含用戶所提交的信息:

成員 說明
request.GET HTML中的<form>標籤提交的 or URL中的查詢字符串(the query string)
request.POST HTML中的<form>標籤提交的

  這兩個都是類字典對象,即其實現了字典的全部成員,另外還有些字典沒有的成員。

2. 利用GET請求,查詢一本書籍

  要作的事情很簡單,作一個書籍查詢頁面,能夠輸入書名查書的信息。作法以下:

  1. 按照模型一節所講,建立書籍的數據庫。

  2. 在"/books/"下,建立幾個文件

    search_form.html

 1 <html>
 2 <head>
 3     <title>Search</title>
 4 </head>
 5 <body>
 6     {% if errors %}
 7         <ul>
 8             {% for error in errors %}
 9             <li>{{ error }}</li>
10             {% endfor %}
11         </ul>
12     {% endif %}
13     <form action="" method="get">
14         <input type="text" name="q">
15         <input type="submit" value="Search">
16     </form>
17 </body>
18 </html>
View Code

    search_results.html 

 1 <p>You searched for: <strong>{{ query }}</strong></p>
 2 
 3 {% if books %}
 4     <p>Found {{ books|length }} book{{ books|pluralize }}.</p>
 5     <ul>
 6         {% for book in books %}
 7         <li>{{ book.title }}</li>
 8         {% endfor %}
 9     </ul>
10 {% else %}
11     <p>No books matched your search criteria.</p>
12 {% endif %}
View Code

    views.py

 1 from django.shortcuts import render_to_response
 2 from books.models import Book
 3 
 4 # Create your views here.
 5 
 6 def search(request):
 7     errors = []
 8     if 'q' in request.GET:
 9         q = request.GET['q']
10         if not q:
11             errors.append('Enter a search term.')
12         elif len(q)>20:
13             errors.append('Please enter at most 20 characters.')
14         else:
15             books = Book.objects.filter(title__icontains=q)
16             return render_to_response('search_results.html', {'books': books, 'query': q})
17     return render_to_response('search_form.html', {'errors': errors})
View Code

  3. 在url中的urlpatterns屬性內,加入以下一條  url(r'^search/$', views.search),  並對應寫出from...import語句

  4. 運行站點:python manage.py runserver

  5. 打開搜索頁面:http://127.0.0.1:8000/search/

3. 表單簡介

  在HTTP中,表單(form標籤),是用來提交數據的,其action屬性說明了其傳輸數據的方法:如何傳、如何接收。

  訪問網站時,表單能夠實現客戶端與服務器之間的通訊。例如咱們上面的查詢書籍,就用到了表單(其屬性中,action=get)。再好比說註冊與登錄,也是要用到表單的。但這裏因爲涉及到隱私問題,須要保證數據傳輸的安全性,所以其傳輸方法就應當使用post而非get。

  總之,對客戶端來講,表單就是用來向服務器提交數據的;而對服務器來講,表單就是你提供給客戶端的發送信息的渠道,你須要對用戶發送來的信息進行處理和響應,以達到頁面的交互。

3+. get與post方法簡介

  這裏作一些擴展——介紹一下表單的傳輸方法。

  表單,一共有四種數據傳輸方法(即action的值):get、post、put、delete,即查、改、增、刪。

  好比,上面查詢書籍的 search_form.html 代碼中,用的就是get方法。

  因爲put和delete均可以用post實現,所以每每只使用get和post兩種,甚至傳統的Web MVC框架基本上都只支持這兩種HTTP方法(-.-||)。這裏,暫不介紹put和delete方法。

  首先給出一段百度知道上對於get和post的簡介,原文做者是tawa08,原文在這裏

    1. get是從服務器上獲取數據,post是向服務器傳送數據。
    2. get是把參數數據隊列加到提交表單的action屬性所指的url中,值和表單內各個字段一一對應,在url中能夠看到。
        
post是經過http post機制,將表單內各個字段與其內容放置在html header內一塊兒傳送到action屬性所指的url地址。
        
用戶看不到這個過程。
    
3. 對於get方式,服務器端用Request.QueryString獲取變量的值,對於post方式,服務器端用Request.Form獲取提交的數據。
    
4. get傳送的數據量較小,不能大於2KB。post傳送的數據量較大,通常被默認爲不受限制。
        
但理論上,IIS4中最大量爲80KB,IIS5中爲100KB。
    
5. get安全性很是低,post安全性較高。可是執行效率卻比Post方法好。

    建議:
    
一、get方式的安全性較Post方式要差些,包含機密信息的話,建議用Post數據提交方式;
    
二、在作數據查詢時,建議用Get方式;而在作數據添加、修改或刪除時,建議用Post方式;

  若是但願對get和post進一步瞭解,那我這裏推薦一篇文章,雖然長但卻清晰並且很全:爲何大型網站都採用get方法,而非post方法

  至此,對於傳輸數據方法的介紹告一段落,我們言歸正傳。

4. CSRF簡介

  因爲咱們要使用django中的form庫,並且要用到post,因此便須要了解CSRF。

  CSRF,Cross Site Request Forgery,跨站請求僞造,這是一種黑客攻擊方式,這裏不過多介紹。你只需知道,當你使用表單傳輸數據時,有可能會接觸這種攻擊方式。所以,咱們學習表單,最好知道這種攻擊方式的存在。對於想深刻了解的同窗,我推薦一篇博文:淺談CSRF攻擊方式

  從以前對get和post的介紹中,你們能夠了解到,在標準的用法中,get因爲毫無安全性可言,所以只應用做數據的查詢;而一旦涉及到數據的添加、修改、刪除時,則必定要採用post方式。那麼,只要網站設計的符合規範,針對get的CSRF攻擊便無從談起。

  所以,django則假設你們遵照這個標準,只在除了get以外那三種方法中才有針對CSRF的防護機制。

  綜上,在django中,若你接觸到form中的post,要麼就只使用get,要麼就關了CSRF防護機制,要麼就正確打開並使用CSRF防護機制,若不正確設置則沒法使用form庫。

  這裏給出官方的設置CSRF防護機制的步驟,若想進一步瞭解,參見官方文檔

    1. 在全部使用post方法的模板(html)中,作以下修改:

      把表單開頭的代碼  <form action="." method="post"> 

      改爲這樣  <form action="." method="post">{% csrf_token %} 

    2. 在全部上面修改過的模板對應的視圖(views.py)中,作以下修改:

      把原視圖代碼,好比這樣的

from django.shortcuts import render_to_response

def my_view(request):
    return render_to_response("a_template.html")

      改爲這樣

from django.core.context_processors import csrf
from django.shortcuts import render_to_response

def my_view(request):
    c = {}
    c.update(csrf(request))
    return render_to_response("a_template.html", c)

5. email設置

  咱們後面要發送郵件,所以還須要先設置好email相關的內容。

  先說一下後面具體要用django.form作什麼:咱們要作一個表單,效果以下圖:

  點擊Submit以後,網頁後臺會發送一封郵件。標題就是hello,內容是hi!,從郵箱A發送到郵箱B。這兩個郵箱都是咱們提早設置好的。

  咱們設想的場景就是:這是一個網站,網站的訪問者能夠經過這裏直接向網站的製做者發送郵件。

  這個過程,是須要用到郵箱A的SMTP服務的,這須要你的開通。好比我用的qq郵箱,開通方式就如教程所說。

  另外,這過程是django後臺作的,那你天然須要告訴django你的郵箱用戶名密碼,還有SMTP服務的主機和端口,這須要在settings.py中添加如下參數:

EMAIL_HOST = 'smtp.qq.com'
EMAIL_PORT = 25
EMAIL_HOST_USER = '820645278@qq.com'
EMAIL_HOST_PASSWORD = 'nicai'

  這樣一來,你即可以讓django從後臺幫你用你設置的這個郵箱(EMAIL_HOST_USER)發送郵件了。

  這個存兩個疑問,但願高手予以解答:

    1. 爲何把EMAIL_PORT參數屏蔽了,仍能夠正常運行?難道端口能夠自動找?

    2. 本例原意是郵箱A由訪問者輸入,但我這種設置方法則鎖定郵箱A必須是設置的這個郵箱,因而這個Email的輸入框形同虛設。

    好比我就像下面代碼中那樣實現,send_mail()中的變量f若不是820645278@qq.com,則會報錯:

      SMTPSenderRefused at /contact/ (501, 'mail from address must be same as authorization user', u'82064527@qq.com')

    若是我想達到訪問者能夠用任意郵箱訪問的效果,那麼我應當如何設置呢?

6. django中的form庫:django.form  

  瞭解了表單、django中的CSRF防護機制、email的設置,下面咱們終於能夠介紹django.form了。

  django是框架,那麼它的存在始終只有一個目的:讓你寫網站更加方便。django.form,就是一個可讓你快速寫出表單的庫。(不用form庫的寫法,原書中有,有興趣的能夠去看看,這裏不寫了)

  具體例子上面介紹email設置時已經說過,下面直接給出實現步驟:

    0. 把上面的email設置作好

    1. 建立"/contact/"目錄

    2. 在其中建立一個空的__init__.py,以及下列文件

      contact_form.html

 1 <html>
 2 <head>
 3     <title>Contact us</title>
 4 </head>
 5 <body>
 6     <h1>Contact us</h1>
 7 
 8     {% if form.errors %}
 9         <p style="color: red;">
10             Please correct the error{{ form.errors|pluralize }} below.
11         </p>
12     {% endif %}
13 
14     {% csrf_token %}
15 
16     <form action="" method="post">{% csrf_token %}
17         <table>
18             {{ form.as_table }}
19         </table>
20         <input type="submit" value="Submit">
21     </form>
22 </body>
23 </html>
View Code

      forms.py

1 from django import forms
2 
3 class ContactForm(forms.Form):
4     subject = forms.CharField()
5     email = forms.EmailField(required=False)
6     message = forms.CharField()
View Code

      views.py

 1 from django.core.mail import send_mail
 2 from django.core.context_processors import csrf
 3 from django.shortcuts import render_to_response, RequestContext
 4 from contact.forms import ContactForm
 5 from django.http import HttpResponseRedirect
 6 
 7 def thanks(request):
 8     return render_to_response('thanks.html')
 9 
10 def contact(request):
11     c = {}
12     c.update(csrf(request))
13     if request.method == 'POST':
14         form = ContactForm(request.POST)
15         if form.is_valid():
16             cd = form.cleaned_data
17             f = cd.get('email', '820645278@qq.com')
18             if f == '': f = '820645278@qq.com'
19             send_mail(
20                 cd['subject'],
21                 cd['message'],
22                 f,
23                 ['icedream@sjtu.edu.cn'],
24             )
25             return HttpResponseRedirect('/contact/thanks/', {'method': request.method})
26     else:
27         form = ContactForm()
28     c['form'] = form
29     return render_to_response('contact_form.html', c, context_instance=RequestContext(request))
View Code

      thanks.html

1 <html>
2 <body>
3 Thanks!
4 </body>
5 </html>
View Code

    3. 在url的urlpatterns屬性內,加入以下兩條  url(r'^contact/$', contact),   url(r'^contact/thanks/$', thanks),  並對應寫出from...import語句

    4. 運行站點:python manage.py runserver

    5. 打開站點聯繫表單頁面:http://127.0.0.1:8000/contact/

    6. 若是成功,你應該能在郵箱B(即代碼中icedream@sjtu.edu.cn)中收到你用郵箱A(即代碼中820645278@qq.com)所發的郵件。

7. 總結:這一節都講了些什麼

  這一節首先介紹了以前一直在使用卻並不瞭解的HttpResponse對象,

  而後介紹了表單、GET和POST方法、CSRF攻擊方式、email設置,

  最後介紹了django中的表單(form)庫,以及如何使用它作出網站的表單。

------------------------------------------------------------------------------------------------------------------------------------------------

  至此,「表單」一章筆記完成,django基礎部分學習完畢。後面開始高級部分,下一章是「高級視圖與URL配置」。

 


 

附錄1+. HttpResponse.META內容

名稱 值(斷句方式僅供參考) 參考翻譯
CLUTTER_IM_MODULE xim CLUTTER輸入法模塊
COLORTERM gnome-terminal 終端配色 
COMPIZ_CONFIG_PROFILE ubuntu 特效配置資料 
CONTENT_LENGTH   內容長度 
CONTENT_TYPE text/plain 內容類型 
CSRF_COOKIE R6SCXazGfl9QGZ2YsCI3VniLFiYNeOUj CSRFcookie 
DBUS_SESSION_BUS_ADDRESS unix:abstract=/tmp/dbus-HALHk0izgV

數據總線會話

總線地址 

DEFAULTS_PATH /usr/share/gconf/ubuntu.default.path 默認路徑 
DESKTOP_SESSION ubuntu 桌面會話 
DISPLAY :0 展現 
DJANGO_SETTINGS_MODULE comeback.settings django設置模塊 
GATEWAY_INTERFACE CGI/1.1 網關接口 
GDMSESSION ubuntu GDM會話 
GDM_LANG zh_CN GDM語言 
GNOME_DESKTOP_SESSION_ID this-is-deprecated GNOME桌面會話ID 
GNOME_KEYRING_CONTROL /run/user/1000/keyring-SkW2gT GNOME鑰匙控制 
GNOME_KEYRING_PID 2176 GNOME鑰匙PID 
GPG_AGENT_INFO /run/user/1000/keyring-SkW2gT/gpg:0:1 GPG代理信息 
GTK_IM_MODULE fcitx GTK輸入法模塊 
GTK_MODULES

overlay-scrollbar:

unity-gtk-module

GTK模塊 
HOME /home/icedream 家 
HTTP_ACCEPT

text/html,

application/xhtml+xml,

application/xml;q=0.9,

image/webp,

*/*;q=0.8

HTTP接收 
HTTP_ACCEPT_ENCODING

gzip,

deflate,

sdch

HTTP接收編碼 
HTTP_ACCEPT_LANGUAGE

zh-CN,

zh;q=0.8,

en;q=0.6,

en-US;q=0.4,

en-GB;q=0.2

HTTP接收語言 
HTTP_CONNECTION keep-alive HTTP鏈接 
HTTP_COOKIE

sessionid=8ifnqpfwvuh0pm04kq24zz4djw3lx4fp;

csrftoken=R6SCXazGfl9QGZ2YsCI3VniLFiYNeOUj

HTTPcookie

會話id & CSRF令牌 

HTTP_HOST 127.0.0.1:8000 HTTP主機 
HTTP_USER_AGENT

Mozilla/5.0 (X11; Linux i686)

AppleWebKit/537.36 (KHTML, like Gecko)

Chrome/43.0.2357.134

Safari/537.36

HTTP用戶代理 
IM_CONFIG_PHASE 1 輸入法配置階段 
INFOPATH :/usr/local/texlive/2015/texmf-dist/doc/info 信息路徑 
INSTANCE Unity 實例 
JOB gnome-session 工做 
LANG zh_CN.UTF-8 語言 
LANGUAGE

zh_CN:

zh

語言 
LESSCLOSE /usr/bin/lesspipe %s %s LESS關閉 
LESSOPEN | /usr/bin/lesspipe %s LESS打開 
LOGNAME icedream 登錄用戶名 
LS_COLORS

rs=0:
di=01;34:
ln=01;36:
mh=00:
pi=40;33:
so=01;35:
do=01;35:
bd=40;33;01:
cd=40;33;01:
or=40;31;01:
su=37;41:
sg=30;43:
ca=30;41:
tw=30;42:
ow=34;42:
st=37;44:
ex=01;32:
*.tar=01;31:
*.tgz=01;31:
*.arc=01;31:
*.arj=01;31:
*.taz=01;31:
*.lha=01;31:
*.lz4=01;31:
*.lzh=01;31:
*.lzma=01;31:
*.tlz=01;31:
*.txz=01;31:
*.tzo=01;31:
*.t7z=01;31:
*.zip=01;31:
*.z=01;31:
*.Z=01;31:
*.dz=01;31:
*.gz=01;31:
*.lrz=01;31:
*.lz=01;31:
*.lzo=01;31:
*.xz=01;31:
*.bz2=01;31:
*.bz=01;31:
*.tbz=01;31:
*.tbz2=01;31:
*.tz=01;31:
*.deb=01;31:
*.rpm=01;31:
*.jar=01;31:
*.war=01;31:
*.ear=01;31:
*.sar=01;31:
*.rar=01;31:
*.alz=01;31:
*.ace=01;31:
*.zoo=01;31:
*.cpio=01;31:
*.7z=01;31:
*.rz=01;31:
*.cab=01;31:
*.jpg=01;35:
*.jpeg=01;35:
*.gif=01;35:
*.bmp=01;35:
*.pbm=01;35:
*.pgm=01;35:
*.ppm=01;35:
*.tga=01;35:
*.xbm=01;35:
*.xpm=01;35:
*.tif=01;35:
*.tiff=01;35:
*.png=01;35:
*.svg=01;35:
*.svgz=01;35:
*.mng=01;35:
*.pcx=01;35:
*.mov=01;35:
*.mpg=01;35:
*.mpeg=01;35:
*.m2v=01;35:
*.mkv=01;35:
*.webm=01;35:
*.ogm=01;35:
*.mp4=01;35:
*.m4v=01;35:
*.mp4v=01;35:
*.vob=01;35:
*.qt=01;35:
*.nuv=01;35:
*.wmv=01;35:
*.asf=01;35:
*.rm=01;35:
*.rmvb=01;35:
*.flc=01;35:
*.avi=01;35:
*.fli=01;35:
*.flv=01;35:
*.gl=01;35:
*.dl=01;35:
*.xcf=01;35:
*.xwd=01;35:
*.yuv=01;35:
*.cgm=01;35:
*.emf=01;35:
*.axv=01;35:
*.anx=01;35:
*.ogv=01;35:
*.ogx=01;35:
*.aac=00;36:
*.au=00;36:
*.flac=00;36:
*.m4a=00;36:
*.mid=00;36:
*.midi=00;36:
*.mka=00;36:
*.mp3=00;36:
*.mpc=00;36:
*.ogg=00;36:
*.ra=00;36:
*.wav=00;36:
*.axa=00;36:
*.oga=00;36:
*.spx=00;36:
*.xspf=00;36:

LS顏色 
MANDATORY_PATH /usr/share/gconf/ubuntu.mandatory.path MANDATORY(託管)路徑 
MANPATH :/usr/local/texlive/2015/texmf-dist/doc/man MAN路徑 
OLDPWD /home/icedream 舊的工做目錄 
PATH

/usr/local/sbin:

/usr/local/bin:

/usr/sbin:

/usr/bin:

/sbin:

/bin:

/usr/games:

/usr/local/games:

/usr/local/texlive/2015/bin/i386-linux

路徑 
PATH_INFO /cookie/ 路徑信息 
PWD /home/icedream/workspace/django/comeback 當前目錄 
QT4_IM_MODULE fcitx QT4輸入法模塊 
QT_IM_MODULE fcitx QT輸入法模塊 
QT_QPA_PLATFORMTHEME appmenu-qt5 QT_QPA平臺主題 
QUERY_STRING   查詢字符串 
REMOTE_ADDR 127.0.0.1 遠程地址 
REMOTE_HOST   遠程主機 
REQUEST_METHOD GET 請求方法 
RUN_MAIN true 運行MAIN 
SCRIPT_NAME   腳本名稱 
SERVER_NAME localhost 服務器名稱 
SERVER_PORT 8000 服務器端口 
SERVER_PROTOCOL HTTP/1.1 服務器協議 
SERVER_SOFTWARE WSGIServer/0.1 Python/2.7.8 服務器軟件 
SESSIONTYPE gnome-session 會話類型 
SHELL /bin/bash 命令行 
SHLVL 1 命令行層次 
SSH_AUTH_SOCK /run/user/1000/keyring-SkW2gT/ssh SSH_AUTH_SOCK 
TERM xterm TERM 
TEXTDOMAIN im-config 文本域 
TEXTDOMAINDIR /usr/share/locale/ 文本域目錄 
TZ UTC 時區 
UPSTART_EVENTS started starting UPSTART事件 
UPSTART_INSTANCE   UPSTART距離 
UPSTART_JOB unity-settings-daemon UPSTART做業 
UPSTART_SESSION unix:abstract=/com/ubuntu/upstart-session/1000/2178 UPSTART會話 
USER icedream 用戶 
VTE_VERSION 3603 VTE版本 
WINDOWID 69206028 窗口ID 
XAUTHORITY /home/icedream/.Xauthority X權威 
XDG_CONFIG_DIRS

/etc/xdg/xdg-ubuntu:

/usr/share/upstart/xdg:

/etc/xdg

XDG配置路徑 
XDG_CURRENT_DESKTOP Unity XDG當前桌面
XDG_DATA_DIRS

/usr/share/ubuntu:

/usr/share/gnome:

/usr/local/share/:

/usr/share/

XDG數據路徑 
XDG_GREETER_DATA_DIR /var/lib/lightdm-data/icedream XDG_GREETER數據路徑 
XDG_RUNTIME_DIR /run/user/1000 XDG運行時路徑 
XDG_SEAT seat0 XDG椅子 
XDG_SEAT_PATH /org/freedesktop/DisplayManager/Seat0 XDG椅子路徑 
XDG_SESSION_DESKTOP ubuntu XDG會話桌面 
XDG_SESSION_ID c2 XDG會話ID 
XDG_SESSION_PATH /org/freedesktop/DisplayManager/Session0 XDG會話路徑 
XDG_SESSION_TYPE x11 XDG會話類型 
XDG_VTNR 7 XDG_VTNR 
XMODIFIERS @im=fcitx XMODIFIERS 
_ /usr/bin/python
wsgi.errors ', mode 'w' at 0xb74d20d0> WSGI錯誤 
wsgi.file_wrapper wsgiref.util.FileWrapper WSGI文件包裝 
wsgi.input <socket._fileobject object="" at="" 0xb5a726ec=""> WSGI輸入 
wsgi.multiprocess False WSGI多進程 
wsgi.multithread True WSGI多線程 
wsgi.run_once False WSGI運行一次 
wsgi.url_scheme http WSGI網址類型 
wsgi.version (1, 0) WSGI版本 
相關文章
相關標籤/搜索