WSGIRequest对象
1、Django在接收到http请求之后,会根据http请求携带的参数以及报文信息创建一个WSGIRequest对象,并且作为视图函数第一个参数传给视图函数。也就是我们经常看到的request参数。在这个对象上我们可以找到客户端上传上来的所有信息。这个对象的完整路径是django.core.handlers.wsgi.WSGIRequest
2、WSGIRequest对象对象是继承于HttpRequest对象的
3、我们在定义视图函数时,视图函数的第一个参数必须是request,也就是这里所说的WSGIRequest对象:它包含了客户端上传上来的所有信息
4、另外,视图函数中通过render()方法来渲染模板时,第一个参数也必须是request,其也是跟视图函数第一个参数一样,是一个WSGIRequest对象
例1:
⑴编辑视图
⑵查看源码
注:
1、从WSGIRequest对象的源码可以看出:WSGIRequest对象是继承于HttpRequest对象的
2、因此WSGIRequest对象只是在HttpRequest对象上封装了更多的一些方法和属性,但是它们两者最重要的相同点就是:都包含了客户端上传上来的所有信息
3、Django在接收到http请求之后,会根据http请求携带的参数以及报文信息创建一个WSGIRequest对象,并且作为视图函数第一个参数传给视图函数
⑴WSGIRequest对象并不是浏览器发送给Django的,而是Django根据客户端或者浏览器发送过来的数据创建的一个对象
⑵Django根据客户端或浏览器发送过来的数据创建的是WSGIRequest对象,而不是HttpRequest对象,只是WSGIRequest对象是继承于HttpRequest对象的(在一定程度上可以说两者是一样的)
WSGIRequest对象封装了什么
1、可以打开一个网页,例如京东。我们F12,打开检查,看右边的内容,就是我们浏览器在请求服务器时会传输的一些信息了。这些信息在django中都会被django的WSGIRequest对象存储
2、客户端或浏览器传递给服务器的这些信息都会封装到WSGIRequest对象中,因此我们可以通过WSGIRequest对象特定的方法或属性来获得对象中的信息(在视图函数中获得)
例2:
例2_1:
注:从上面实际的请求中可以看出
1、客户端在向服务器请求时,会发送很多信息(请求头、请求体等信息:包括URL传递的参数或表单传递的参数)。这些信息再被Django服务器接收后,Django会将它们创建为一个WSGIRequest对象
2、因此,WSGIRequest对象也就是我们经常看到的request参数:在这个对象上我们可以找到客户端上传上来的所有信息
3、进一步,在Django服务器中(视图函数中),我们可以通过WSGIRequest对象特定的方法或属性来获得对象中的具体信息
WSGIRequest对象常用属性和方法
WSGIRequest对象常用属性
WSGIRequest对象上大部分的属性都是只读的。因为这些属性是从客户端上传上来的,没必要做任何的修改。以下将对一些常用的属性进行讲解
属性名 | 说明 |
path | 请求服务器的完整“路径”,但不包含域名和参数。比如http://www.baidu.com/xxx/yyy?a=1&b=2,那么path就是/xxx/yyy |
method | 代表当前请求的http方法。比如是GET还是POST |
GET | 一个django.http.request.QueryDict对象。操作起来类似于字典。这个属性中包含了所有以?xxx=xxx的方式上传上来的参数 (以查询字符串的方式传递的参数) |
POST | 也是一个django.http.request.QueryDict对象。这个属性中包含了所有以POST方式上传上来的参数 |
FILES | 也是一个django.http.request.QueryDict对象。这个属性中包含了所有上传的文件 |
COOKIES | 一个标准的Python字典,包含所有的cookie,键值对都是字符串类型 |
session | 一个类似于字典的对象。用来操作服务器的session |
META | 包含所有HTTP头部(header)信息的字典。可用的头部信息取决于客户端和服务器 |
scheme | 字符串类型,表示请求的协议种类,'http'或'https' |
encoding | 字符串类型,表示提交的数据的编码方式。 这个属性是可写的,可以通过修改它来改变表单数据的编码 |
例3:path
⑴编辑视图:查询字符串URL
⑵编辑视图:动态URL
注:
1、WSGIRequest对象的path属性用于获取请求URL中的参数(path)部分,不会获取URL后面的参数部分
2、一般的URL有两种形式:查询字符串形式的URL和动态URL
⑴查询字符串形式的URL:URL中类似于?a=1&b=2的部分,这部分只是用于传递参数,跟路由系统中定义的URL匹配规则无关,不会用于URL匹配(在URL路由中也不需要定义,也不属于URL参数部分)
⑵动态URL:这种URL部分是需要在URL路由中定义的,定义方式是使用尖括号"<name>",它是属于URL参数(path)部分的,在请求时需要进行URL匹配
⑶查询字符串参数和动态URL参数在视图函数中获取的方式也不一致(查询字符串参数获取方式本章介绍,动态URL参数获取方式可以参考路由系统那章)
3、这个属性,常被用于我们进行某项操作时,如果不通过,返回用户先前浏览的页面。非常有用!
例4:method
⑴编辑视图:简单的获取请求方式
⑵编辑视图:判断请求方式来进行不同的处理
注:
1、实际中一个页面如果只是单纯的获取数据的话,那就只需要支持GET方式的请求就可以了。但是有时候一个页面不仅要获取数据并且还可以提交数据(一个页面只有获取到提交数据的页面后才能进行提交数据,不获取到提交数据的页面的话,又在哪里填写需要提交的数据呢)
2、即一个URL往往既可以使用GET方法也可以使用POST方式进行请求,因此就需要在视图函数中判断当前的请求使用的是哪种方式,针对不同的请求方式进行不同的处理。这里就需要使用到了request.method属性了
3、request.method属性最常见的用法就是在视图函数中判断当前的请求方式,然后根据请求方式来进行不同的处理
4、返回值:字符串类型,表示请求使用的HTTP方法。默认为大写
例5:GET
⑴编辑视图:
注:
1、WSGIRequest对象中的GET属性是一个django.http.request.QueryDict对象。操作起来类似于字典。这个属性中包含了所有以?xxx=xxx的方式上传上来的参数。因此可以使用字典方法get()或[]来获取其中的值
2、即:如果要获取前端传过来的查询字符串参数,那么就需要使用WSGIRequest对象中的GET属性,且因为其是一个类字典类型,因此可以使用字典方法来获取
3、请求格式:在请求地址结尾使用?,之后以“键=值”的格式拼接,多个键值对之间以&连接
例6:POST
⑴编辑视图
⑵访问
注:
1、WSGIRequest对象中的POST属性也是一个django.http.request.QueryDict对象。这个属性中包含了所有以POST方式上传上来的参数。因此可以使用字典方法get()或[]来获取其中的值
2、即:如果要获取前端通过POST方法传递过来的参数,那么就需要使用WSGIRequest对象中的POST属性,且因为其是一个类字典类型,因此可以使用字典方法来获取
3、用form表单请求时,method方式为post则会发起post方式的请求,需要使用HttpRequest对象的POST属性接收参数,POST属性返回QueryDict类型的对象
例7:META
⑴编辑视图
注:
1、META:存储的客户端发送上来的所有header信息
2、通过上面例子中的输出可以看出,它是把所有的请求header信息打包成了一个字典类型的数据,键为属性名,值为具体header的值。因为也是一个字典,因此也可以使用字典方法
3、META属性中含有的具体的属性有以下一些:
CONTENT_LENGTH | 请求正文的长度(以字符串计) |
CONTENT_TYPE | 请求正文的MIME类型 |
HTTP_ACCEPT | 可接收的响应Content-Type |
HTTP_ACCEPT_ENCODING | 可接收的响应编码类型 |
HTTP_ACCEPT_LANGUAGE | 可接收的响应语言种类 |
HTTP_HOST | 客服端发送的Host头部 |
HTTP_REFERER | Referring页面 |
HTTP_USER_AGENT | 客户端的user-agent字符串 |
QUERY_STRING | 查询字符串 |
REMOTE_ADDR | 客户端的IP地址。想要获取客户端的ip信息,就在这里 |
REMOTE_HOST | 客户端的主机名 |
REMOTE_USER | 服务器认证后的用户,如果可用 |
REQUEST_METHOD | 表示请求方法的字符串,例如"GET" 或"POST" |
SERVER_NAME | 服务器的主机名 |
SERVER_PORT | 服务器的端口(字符串) |
注:
1、REMOTE_ADDR:客户端的IP地址。如果服务器使用了nginx做反向代理或者负载均衡,那么这个值返回的是127.0.0.1,这时候可以使用HTTP_X_FORWARDED_FOR来获取,所以获取ip地址的代码片段如下:
if request.META.has_key('HTTP_X_FORWARDED_FOR'):
ip = request.META['HTTP_X_FORWARDED_FOR']
else:
ip = request.META['REMOTE_ADDR']
#python3字典中没有has_key()这个方法
2、上面只是介绍了WSGIRequest对象中一些属性的例子,比如FILES,COOKIES等都没有具体介绍例子,这是因为后面会单独学习这些,所以这里就先不介绍了
3、另外,在Django中WSGIRequest对象还有很多属性,只是这里没有写到
WSGIRequest对象常用方法
is_secure() | 是否是采用https协议 |
is_ajax() | 是否采用ajax发送的请求。原理就是判断请求头中是否存在X-Requested-With:XMLHttpRequest |
get_host() | 服务器的域名。如果在访问的时候还有端口号,那么会加上端口号。比如www.baidu.com:9000 |
get_full_path() | 返回完整的path。如果有查询字符串,还会加上查询字符串。比如/music/bands/?print=True |
get_raw_uri() | 获取请求的完整url |
例8:is_secure()
⑴编辑视图
例9:is_ajax()
⑴编辑视图
⑵查询任意一个可提交数据的网站
例10:get_raw_uri()
⑴编辑视图
总结
1、总的来说WSGIRequest对象,也就只reuqest,这里面包含了客户端上传上来的所有信息。所以我们在视图函数中就可以使用其对象下合适的属性或方法来获取我们想要的东西
⑵目前感觉最常用的估计就是:method、GET、POST属性了
2、当请求一个页面时, Django会建立一个包含请求元数据的 HttpRequest 对象. 当Django 加载对应的视图时, HttpRequest对象将作为视图函数的第一个参数.。每个视图会返回一个HttpResponse对象(HttpResponse对象后面介绍)
HttpRequest对象
1、当请求一个页面时,Django把请求的metadata数据包装成一个HttpRequest对象,然后Django加载合适的view方法,把这个HttpRequest对象作为第一个参数传给view方法。任何view方法都应该返回一个HttpResponse对象
2、HttpRequest对象表示来自某客户端的一个单独的HTTP请求。HttpRequest对象是Django自动创建的,HttpResponse对象由程序员创建
HttpRequest中的META属性
1、request.META是一个Python字典,包含了所有本次HTTP请求的Header信息
⑴比如用户IP地址和用户Agent(通常是浏览器的名称和版本号)
⑵注意,Header信息的完整列表取决于用户所发送的Header信息和服务器端设置的Header信息
⑶这个字典中几个常见的键值有:
①HTTP_REFERER:进站前链接网页,如果有的话。 (请注意,它是REFERRER的笔误)
②HTTP_USER_AGEN:用户浏览器的user-agent字符串,如果有的话。 例如: "Mozilla/5.0 (X11; U; Linux i686; fr-FR; rv:1.8.1.17) Gecko/20080829 Firefox/2.0.0.17"
③REMOTE_ADDR 客户端IP:如:"12.345.67.89" 。(如果申请是经过代理服务器的话,那么它可能是以逗号分割的多个IP地址,如:"12.345.67.89,23.456.78.90" )
④……
2、request.META是一个普通的Python字典,因此当你试图访问一个不存在的键时,会触发一个KeyError异常
⑴HTTP header信息是由用户的浏览器所提交的、不应该给予信任的“额外”数据,因此你总是应该好好设计你的应用以便当一个特定的Header数据不存在时,给出一个优雅的回应
⑵你应该用try/except 语句,或者用Python字典的get()方法来处理这些“可能不存在的键”
例11:比如我要获得用户的浏览器信息,可以这么设计函数
def ua_display(request):
ua = request.META.get('HTTP_USER_AGENT', 'unknown')
return HttpResponse("Your browser is %s" % ua)
#Your browser is Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/28.0.1500.95 Safari/537.36
例11_1:
def ua_display_2(request):
try:
ua = request.META['HTTP_USER_AGENT']
except KeyError:
ua = 'unknown'
return HttpResponse("Your browser is %s" % ua)