zoukankan      html  css  js  c++  java
  • Django笔记 —— 表单(form)

      最近在学习Django,打算玩玩网页后台方面的东西,因为一直很好奇但却没怎么接触过。Django对我来说是一个全新的内容,思路想来也是全新的,或许并不能写得很明白,所以大家就凑合着看吧~

      本篇笔记(其实我的所有笔记都是),并不会过于详细的讲解。因此如果有大家看不明白的地方,欢迎在我正版博客下留言,有时间的时候我很愿意来这里与大家探讨问题。(当然,不能是简简单单就可以百度到的问题-.-)

      我所选用的教材是《The Django Book 2.0》,本节是表单部分,对应书中第七章。

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

    0、阅读方法

      本节笔记,略去很多书中学习过程与讲解,建议在看完原书此节后,作总结复习之用。

      站点创建:django-admin.py startproject comeback

    1、视图中的HttpResponse

      首先给我们的代码加上一个视图,网址是"http://127.0.0.1:8000/",网站内容就是一个Hello World。

      显然,其在"/comeback/views.py"中的代码内容是:

    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>' % '
    '.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方法好。

        建议:
        
    1、get方式的安全性较Post方式要差些,包含机密信息的话,建议用Post数据提交方式;
        
    2、在做数据查询时,建议用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版本 

  • 相关阅读:
    java 运算
    java String
    java的数据类型
    Python: str() 和 repr() 的区别
    Linux命令:which
    Linux命令:locate
    Linux命令:ifconfig
    Linux命令:whereis
    Linux命令:rz 和 sz
    Linux命令:scp
  • 原文地址:https://www.cnblogs.com/icedream61/p/4655761.html
Copyright © 2011-2022 走看看