CBV 简版流程
AddPublisher.as_view() --》 view 函数
当请求来的时候才执行 view
view 中执行:
1. 先实例化 AddPublisher, 给 self
- def view(request, *args, **kwargs):
- self = cls(**initkwargs)
- if hasattr(self, 'get') and not hasattr(self, 'head'):
- self.head = self.get
- self.request = request
- self.args = args
- self.kwargs = kwargs
- return self.dispatch(request, *args, **kwargs)
执行 self.dispatch() self 有 dispatch 就执行自己的 没有就是执行 父类 (View) 的 dispatch 方法
dispatch 中执行: 先通过反射获取到 AddPublisher 中定义 get 或者 post 方法. 执行 get 或者 post 方法 返回 httpresponse 对象
view 接收到 dispatch 的返回值 --httpresponse 对象
view 返回 httpresponse 对象
Request 对象
当一个页面被请求时, Django 就会创建一个包含本次请求原信息的 HttpRequest 对象.
Django 会将这个对象自动传递给响应的视图函数, 一般视图函数约定俗成地使用 request 参数承接这个对象.
请求相关的常用值
path_info 返回用户访问 url, 不包括域名
method 请求中使用的 HTTP 方法的字符串表示, 全大写表示.
GET 包含所有 HTTP GET 参数的类字典对象
POST 包含所有 HTTP POST 参数的类字典对象
body 请求体, byte 类型 request.POST 的数据就是从 body 里面提取到的
属性
属性:
django 将请求报文中的请求行, 头部信息, 内容主体封装成 HttpRequest 类中的属性.
除了特殊说明的之外, 其他均为只读的.
0.HttpRequest.scheme
表示请求方案的字符串(通常为 http 或 https)
1.HttpRequest.body
一个字符串, 代表请求报文的主体. 在处理非 HTTP 形式的报文时非常有用, 例如: 二进制图片, xml,JSON 等.
但是, 如果要处理表单数据的时候, 推荐还是使用 HttpRequest.POST .
另外, 我们还可以用 python 的类文件方法去操作它, 详情参考 HttpRequest.read() .
2.HttpRequest.path
一个字符串, 表示请求的路径组件(不含域名).
例如:"/music/bands/the_beatles/"
3.HttpRequest.method
一个字符串, 表示请求使用的 HTTP 方法. 必须使用大写.
例如:"GET","POST"
4.HttpRequest.encoding
一个字符串, 表示提交的数据的编码方式(如果为 None 则表示使用 DEFAULT_CHARSET 的设置, 默认为'utf-8').
这个属性是可写的, 你可以修改它来修改访问表单数据使用的编码.
接下来对属性的任何访问 (例如从 GET 或 POST 中读取数据) 将使用新的 encoding 值.
如果你知道表单数据的编码不是 DEFAULT_CHARSET , 则使用它.
5.HttpRequest.GET
一个类似于字典的对象, 包含 HTTP GET 的所有参数. 详情请参考 QueryDict 对象.
6.HttpRequest.POST
一个类似于字典的对象, 如果请求中包含表单数据, 则将这些数据封装成 QueryDict 对象.
POST 请求可以带有空的 POST 字典 -- 如果通过 HTTP POST 方法发送一个表单, 但是表单中没有任何的数据, QueryDict 对象依然会被创建.
因此, 不应该使用 if request.POST 来检查使用的是否是 POST 方法; 应该使用 if request.method == "POST"
另外: 如果使用 POST 上传文件的话, 文件信息将包含在 FILES 属性中.
7.HttpRequest.COOKIES
一个标准的 Python 字典, 包含所有的 cookie. 键和值都为字符串.
8.HttpRequest.FILES
一个类似于字典的对象, 包含所有的上传文件信息.
FILES 中的每个键为 < input type="file" name="" /> 中的 name, 值则为对应的数据.
注意, FILES 只有在请求的方法为 POST 且提交的 < form> 带有 enctype="multipart/form-data" 的情况下才会
包含数据. 否则, FILES 将为一个空的类似于字典的对象.
9.HttpRequest.META
一个标准的 Python 字典, 包含所有的 HTTP 首部. 具体的头部信息取决于客户端和服务器, 下面是一些示例:
CONTENT_LENGTH -- 请求的正文的长度(是一个字符串).
CONTENT_TYPE -- 请求的正文的 MIME 类型.
HTTP_ACCEPT -- 响应可接收的 Content-Type.
HTTP_ACCEPT_ENCODING -- 响应可接收的编码.
HTTP_ACCEPT_LANGUAGE -- 响应可接收的语言.
HTTP_HOST -- 客服端发送的 HTTP Host 头部.
HTTP_REFERER -- Referring 页面.
HTTP_USER_AGENT -- 客户端的 user-agent 字符串.
QUERY_STRING -- 单个字符串形式的查询字符串(未解析过的形式).
REMOTE_ADDR -- 客户端的 IP 地址.
REMOTE_HOST -- 客户端的主机名.
REMOTE_USER -- 服务器认证后的用户.
REQUEST_METHOD -- 一个字符串, 例如 "GET" 或 "POST".
SERVER_NAME -- 服务器的主机名.
SERVER_PORT -- 服务器的端口(是一个字符串).
从上面可以看到, 除 CONTENT_LENGTH 和 CONTENT_TYPE 之外, 请求中的任何 HTTP 首部转换为 META 的键时,
都会将所有字母大写并将连接符替换为下划线最后加上 HTTP_ 前缀.
所以, 一个叫做 X-Bender 的头部将转换成 META 中的 HTTP_X_BENDER 键.
10.HttpRequest.user
一个 AUTH_USER_MODEL 类型的对象, 表示当前登录的用户.
如果用户当前没有登录, user 将设置为 django.contrib.auth.models.AnonymousUser 的一个实例. 你可以通过 is_authenticated() 区分它们.
例如:
- if request.user.is_authenticated():
- # Do something for logged-in users.
- else:
- # Do something for anonymous users.
user 只有当 Django 启用 AuthenticationMiddleware 中间件时才可用.
-------------------------------------------------------------------------------------
匿名用户
class models.AnonymousUser
django.contrib.auth.models.AnonymousUser 类实现了 django.contrib.auth.models.User 接口, 但具有下面几个不同点:
id 永远为 None.
username 永远为空字符串.
get_username() 永远返回空字符串.
is_staff 和 is_superuser 永远为 False.
is_active 永远为 False.
groups 和 user_permissions 永远为空.
is_anonymous() 返回 True 而不是 False.
is_authenticated() 返回 False 而不是 True.
set_password(),check_password(),save() 和 delete() 引发 NotImplementedError.
New in Django 1.8:
新增 AnonymousUser.get_username() 以更好地模拟 django.contrib.auth.models.User.
11.HttpRequest.session
一个既可读又可写的类似于字典的对象, 表示当前的会话. 只有当 Django 启用会话的支持时才可用.
完整的细节参见会话的文档.
request 属性相关
上传文件小案例
- def upload(request):
- """
- 保存上传文件前, 数据需要存放在某个位置. 默认当上传文件小于 2.5M 时, django 会将上传文件的全部内容读进内存. 从内存读取一次, 写磁盘一次.
- 但当上传文件很大时, django 会把上传文件写到临时文件中, 然后存放到系统临时文件夹中.
- :param request:
- :return:
- """ if request.method =="POST":
- # 从请求的 FILES 中获取上传文件的文件名, file 为页面上 type=files 类型 input 的 name 属性值
- filename = request.FILES["file"].name
- # 在项目目录下新建一个文件
- with open(filename, "wb") as f:
- # 从上传的文件对象中一点一点读
- for chunk in request.FILES["file"].chunks():
- # 写入本地文件
- f.write(chunk)
- return HttpResponse("上传 OK")
上传文件示例代码
来源: http://www.bubuko.com/infodetail-3001112.html