django的request对象的理解
django使用Request对象和Response对象在系统间传递'状态'。

以前误区:
1、request对象,只知道当我们在写django视图的时候,里面的函数需要必须带有request参数,这个参数的名字可以随便起,只要函数的有一个参数即可(非默认参数)。
更正:
当用户发送请求的时候,会创建一个包含用户请求的元数据的HttpRequest对象,当HttpRequest对象经过django的时候,HttpRequest对象传递到视图函数的时候,变为视图的函数的第一个参数。
进过视图函数的处理,返回给用户一个HttpRespone对象。
即开篇说的,django使用Request对象和Reponse对象在django系统间传递状态。
renquest对象的属性:
HttpRequest.body:一个字节字符串,表示原始请求正文,处理常规表单的数据,一般用HttpRequest.POST.
HttpRequest.read():我们可以用类文件形式访问HttpRequest对象的数据。
HttpRequest.path:一个字符串,表示请求的页面的完整路径。不包含域名(即主机名和端口)
http://www.jd.com/a/b/c 其中HttpRequest.path为:/a/b/c
HttpRequest.path_info:在某些Web 服务器配置下,主机名后的URL 部分被分成脚本前缀部分和路径信息部分。path_info 属性将始终包含路径信息部分,不论使用的Web 服务器是什么。使用它代替path 可以让代码在测试和开发环境中更容易地切换。例如,如果应用的WSGIScriptAlias 设置为"/minfo",那么当path 是"/minfo/music/bands/the_beatles/" 时path_info 将是"/music/bands/the_beatles/"。
HttpRequest.method:一个字符串,表示使用HTTP方法,method必须为大写。
1 if request.method=="GET": 2 pass 3 elif request.method=='POST': 4 pass
HttpRequest,encoding:
一个字符串,表示数据的编码格式(如果是None的话,则表示使用DEFAULT_CHARSET 设置) 。这个属性是可写的。你可以修改他来访问body里提交的数据。
HttpRequest.POST:
是QueryDict的对象,而 QueryDict是继承dict,所以HttpRequest.POST是字典对象。所以字典的方法适用于HttpRequest.POST对象。
HttpRequest.GET:
同样也是QueryDict的对象,所以字典的方法适用于HttpRequest.POST对象。
需要注意:
在判断request的对象的方法的时候,不能以按下面的方法进行判断;
1 def function(request): 2 if request.method=='POST': 3 pass 4 else: 5 pass
不能以if/else来判断request对象的方法,用else来判断GET 方法,因为HTTP方法不仅是POST和GET,还有PUT、DELETE等方法。
1 if request.POST: 2 pass
不能以request.POST的字典是否为空值来判断一个是否是POST方法,如果有用户请求的数据的是空,进行GET或者POST请求的时候。
正确:
1 if request.method=='POST': 2 pass 3 elif request.method='GET': 4 pass
HtppRequest.cookie:
一个标准的python字典,包含的cookie的值,键和值都是字符串。
HttpRequest.FILES:
一个类似于字典对象,包含所有上传的东西,FILES中的每个键都是<input name='file_upload' type='file'>中的name属性,
注意:FILES 只有请求的方法为POST 且提交的form表单带有 enctype="multipart/form-data"的情况下才包含数据,否则该对象类似于空的字典对象。
HttpRequest.META:一个标准的python字典,包含所有的HTTP头部信息。具体的头部信息,取决于客户端和服务器。
常见的头部信息 如下:
1 CONTENT_LENGTH —— 请求的正文的长度(是一个字符串)。 2 CONTENT_TYPE —— 请求的正文的MIME 类型。 3 HTTP_ACCEPT —— 响应可接收的Content-Type。 4 HTTP_ACCEPT_ENCODING —— 响应可接收的编码。 5 HTTP_ACCEPT_LANGUAGE —— 响应可接收的语言。 6 HTTP_HOST —— 客服端发送的HTTP Host 头部。 7 HTTP_REFERER —— Referring 页面。 8 HTTP_USER_AGENT —— 客户端的user-agent 字符串。 9 QUERY_STRING —— 单个字符串形式的查询字符串(未解析过的形式)。 10 REMOTE_ADDR —— 客户端的IP 地址。 11 REMOTE_HOST —— 客户端的主机名。 12 REMOTE_USER —— 服务器认证后的用户。 13 REQUEST_METHOD —— 一个字符串,例如"GET" 或"POST"。 14 SERVER_NAME —— 服务器的主机名。 15 SERVER_PORT —— 服务器的端口(是一个字符串)。
从上面我们中的REMOTE_ADDR: 获取客户端IP,有时候做接口认证的时候,需要获取客户端的IP。
HttpRequest.user
一个AUTH_USER_MODEL类型对象,表示当前登录用户,前提是使用django的认证系统,如果当前没有登录用户,user将设置django.contrib.models.AnymouseUser的一个实例。
判断当前用户是否登录:
1 if request.user.is_authenticated(): 2 #login do something you like 3 else: 4 #anymous do something
request.user.is_authenticated()返回是当前用户的对象,None表示当前用户未登录。
HttpRequest.session:
一个即可以读,也可以写的字典对象,表示当前登录回话。只有当Django启用会话的支持才可以使用。
启用session:
setting.py文件中的MIDDLEWARE_CLASSES或者MIDDLEWARE中注册一下中间件:
django.contrib.sessions.middleware.SessionMiddleware
以及在INSTALLED_APPS中注册:
1 django.contrib.sessions
默认我使用命令创建python manager startapp xxxx的时候已经启用session。
不想启用session 可以把如上两项配置去除。
如果我们不使用django自身的认证系统的时候,我们需要自己设置username以及当我们分页的时候,也需要写入session。
request.session['user']=xxx
如果使用django的认证系统的时候,需要调用login()函数,把当前登录的用户信息写入session中。
1 from django.contrib.auth import authenticate, login 2 3 def my_view(request): 4 username = request.POST['username'] 5 password = request.POST['password'] 6 user = authenticate(username=username, password=password) 7 if user is not None: 8 login(request, user)#对session进行写入 9 # Redirect to a success page. 10 ... 11 else: 12 # Return an 'invalid login' error message. 13 ...
去除用户session的信息,直接调用 logout()函数即可。
二、request的方法:
1、get_host():获取客户端请求的IP和端口。根据从HTTP_X_FORWARDED_HOST(如果打开USE_X_FORWARDED_HOST)和HTTP_HOST 头部信息返回请求的原始主机。如果这两个头部没有提供相应的值,则使用SERVER_NAME 和SERVER_PORT,在PEP 3333 中有详细描述。

当主机位于多个代理后面的时候,get_host()会失效,有一个解决方法就是使用中间件重写代理头部。如下:
1 class MultipleProxyMiddleware(object): 2 FORWARDED_FOR_FIELDS = [ 3 'HTTP_X_FORWARDED_FOR', 4 'HTTP_X_FORWARDED_HOST', 5 'HTTP_X_FORWARDED_SERVER', 6 ] 7 8 def process_request(self, request): 9 """ 10 Rewrites the proxy headers so that only the most 11 recent proxy is used. 12 """ 13 for field in self.FORWARDED_FOR_FIELDS: 14 if field in request.META: 15 if ',' in request.META[field]: 16 parts = request.META[field].split(',') 17 request.META[field] = parts[-1].strip()
该中间件的位置:这个中间件应该放置在所有依赖于get_host() 的中间件之前 —— 例如,CommonMiddleware 和CsrfViewMiddleware。
至于中间件书写规则,请参考:http://python.usyiyi.cn/django/index.html

在MIDDLEWARE_CLASSES中,每一个中间件组件用字符串的方式描述:一个完整的Python全路径加上中间件的类名称。
更多例子:;请参考:http://python.usyiyi.cn/django/index.html

浙公网安备 33010602011771号