View视图简介
- View的本质
- 我们之前说过,Django框架中的View视图本质上是一大堆具有单一功能的python函数。它一般被定义在“应用/views.py”文件中。
- View的函数实现的功能
- View视图负责接受Web请求(HttpRequest),进行逻辑处理,最后返回Web响应(HttpResponse)给请求者;
- View视图函数可以接收的参数:request请求(必须接收),通过正则表达式组获得的关键字参数,通过正则表达式组获取的位置参数
- 返回而且必须返回response对象或者子对象
- request请求是Django自动创建的
- response是开发人员创建的
View视图函数响应客户端的流程
- HttpRequest & HttpResponse
- HttpRequest
- 是django构造好的一个类,Django接收到用户发送的请求后将发送过来的请求报文封装到HttpRequest对象中去传递给View
- 在django.http模块中定义了HttpRequest对象的API,HttpRequest对象属性几乎都是只读的,用于读取请求报文,不是用来设置请求报文的;
- 在view函数的第一个参数的request就是HttpRequest类型的请求对象,request对象的作用就是为了获取用户请求的数据用的。
- HttpResponse
- 是django内部代码已经封装好的一个类。他返回的是一个应答的数据报文对象,我们平常使用的render,他内部已经封装好了HttpResponse类,;
- View调用模板的流程(了解,实际上可以直接用render封装好的功能)
- from django.template import loader,RequestContext,render
- 1.找到模板 -- 定义模板对象
- loader.get_template 加载模板对象
- 实例:template=loader.get_template('book_app/index.html')
- 2.定义上下文 -- 定义context对象
- RequestContext() 根据内容,定义一个组合成的对象
- 实例:context=RequestContext(request,{'title':'图书列表'})
- 3.渲染模板 --生成相应报文返回客户端
- template.render(context) 接受context作为render的参数,然后生成一个对象
- HttpResponse(template.render(context)) 生成响应报文
- 实例:return HttpResponse(template.render(context))
- View调用模板流程的简化(Django专门提供的render()方法)
- render方法
- 视图调用模板的流程都要执行以上三部分(获定渲),于是Django专门提供了一个函数render,这个函数封装了调用模板流程代码,而且还实现了更多的功能。
- render方法接收的参数
- 第一个参数为request对象
- 第二个参数为模板文件路径
- 第三个参数为字典,表示向模板中传递的上下文数据
- Django请求处理流程图
- 错误视图的匹配
- 匹配异常处理逻辑
- Django 找不到一个匹配请求的URL 的正则表达式时,或者当抛出一个异常时,Django 将调用一个错误处理视图,常见错误视图(404错误:page not found视图、500错误:server error视图、400错误:bad request视图);
- 如何自定义错误视图
- 当发生错误的时候,django会默认返回django自带的错误视图,但是我们可以通过在url中配置错误视图的处理路径,来自定义错误视图
- 404错误的路径django已经帮我们设定好了,在templates目录,如果去们在templates目录项创建404.html,那么服务器会默认去调用该模板文件
- 更改返回的异常视图的步骤
- 修改setting 文件的DEBUG项
- 修改第一条不会显示异常的具体信息,不会暴露异常目录及具体异常
- 第二条是添加允许访问服务器的主机(当取消debug选项必须设置,不然客户端不能访问服务器)
- 在project/urls.py文件,配置错误的自定义的处理路径
- 在templates目录下设置的templates模板的目录下创建对应错误文件;例如:404.html(创建用来返回404错误的模板)。500.html 等
HttpResquest对象的属性详细解释
- HttpResquest的属性的作用
- HttpResquest中包含了所有用户请求相关的内容,我们可以从其中查看各种我们需要的信息,进行之后的操作,获取的格式为:request.属性;
- HttpResquest的属性(一般都是只可读取的属性)
- path 一个字符串,表示请求的页面的完整路径,不包含域名端口和参数
- get_full_path() 获取带参数的路径
- method 获取客户端的求情方式(最常见的方法为GET、POST)
- encoding 一个字符串,表示提交的 数据的编码方式
- 这个属性是可以进行修改的,对属性进行了编码规则的修改后,之后对该请求对象属性的访问都将使用新定义的encoding
- GET 注意大写 一个 类似于字典的对象,包含get请求方式的所有数据
- POST 注意大写 一个 类似于字典的对象,包含post请求方式的所有数据
- FILES 一个类似于字典的对象,包含所有的上传文件,适用于上传图片的场景
- COOKIES 一个标准的Python字典,包含所有的cookie,键和值都为字符串
- session 一个既可读又可写的类似于字典的对象,表示当前的会话,只有当Django启用会话的支持时才可用,
- 详细内容见“状态保持”;
- 备注:在模板文件中访问httprequest对象属性的时候,因为在模板文件的替换标签中不能使用(),所以在通过实例方法访问的时候可以将()省略,这是模板标签已经实现的 功能;
- 客户端使用get与post的区别
- get方法
- 一般只用来获取数据用
- 将请求数据放在url中,可以直接从浏览器的地址栏看见
- 请求体一般不包含内容,请求数据以键值对的形式存在在url中
- 服务器端可以通过GET过去所有客户端的请求数据
- post方法
- 一般用来向服务器端传输数据,但是也可以用来获取数据
- 将请求和传输的数据放在请求体中,用户不能直接从浏览器地址栏看到请求的具体数据
- 请求体包含所有的请求相关和上传文件的信息,以键值对的形式存在
- 服务器端可以通过POST来获取post的请求数据,也可以使用FILES来获取客户端上传过问的文件数据;
- HttpResquest对象GET、POST属性的获取结果(只强调几个特殊格式的属性结果)
- 属性GET的值
- 一般情况获取结果
- <QueryDict : {'a' : ['2'], 'b' : ['3']}>
- 属性POST的值
- 一般情况获取结果
- <QueryDict : {'a' : ['2'], 'b' : ['3'], 'csrfmiddlewaretoken' : 'vSFDsO&HMS^M^)TZ!x2aN3wQIwP2bYas'}>
- 其中字典中的第三个值为csrf问题导致产生的的键值对,我们先不管
- 注意:
- POST方法的数据之能通过表单或者ajax来进行传递不能直接在浏览器的地址栏进行输入,所以要现在模板的对应位置定义响应的保单内容并进行提交
- 当客户单直接使用POST方法进行服务器的访问的时候,会报403的错误403错误,表示资源不可用。服务器理解客户的请求,但拒绝处理它,通常由于服务器上文件或目录的权限设置导致的WEB访问错误,这是关于权限的问题,我们先不考虑。
- 解决办法:
- 第一种:注释掉项目中中间件配置内容中关于CSRF的一项内容
- 第二种:在POST的表单中加上一行{\% csfr_token \%}
- 这种方法只先屏蔽掉该表单的csrf问题,我们先使用这一种
- GET、POST属性的作用
- 在客户端的请求中,url中经常包括通过表单input,ajax,和浏览器输入栏传递的参数,以键值对的方式传递给服务器,我们需要获取这些参数的内容,根据参数的来进行对应的处理逻辑,对处理结果通过模板进行返回;
- QueryDict对象
- QueryDict对象介绍
- QueryDict不是python默认的类型,而是定义在django.http.QueryDict中的一个对象,他类似于python的字典,但是跟字典不一样与python字典不同,QueryDict类型的对象可以用来处理同一个键带有多个值的情况
- QUeryDict与python字典的区别
- python的字典:一个键对应一个值, 字典中的键是不能重复的。
- QueryDict对象:接收的url的参数也是一个键对应一个值,但是他中间的键是可以重复的。
- 当存在一个键多个值得时候,QueryDict的值
- 示例:<QueryDict : {'a' : ['2', '3'], 'b' : ['3', '4']}>
- 获取QueryDict对象对应键的数值的方法
- 方法一:
- 使用的方法
- dict.get('键') 根据键获取值
- 可以通过给键一个默认值,当键没有内容的时候,会获取默认值,dict.get('键',默认值)
- get('键')可以简写成[ '键'] ,当一个无键无值得情况会报错
- 每种情况获取到的结果
- 1、在一键一值的情况下,键的值获取出来了
- 2、在一键多值的情况下,键的值是最后定义的一个值
- 3、在一个有键无值情况下,该键的值返回了空
- 4、在我们没有键也没有值的情况下,定义了默认值会返回默认值
- 5、在我们没有键名也没有值的情况下,没有给他定义的默认值,返回了None
- 方法二:
- dict.getlist('键') 根据键获取值,值以列表返回,可以获取指定键的所有值
- 可以通过给键一个默认值,当键没有内容的时候,会获取默认值,dict.get('键',默认值)
- 每种情况获取到的结果:
- 在一键一值的情况下,键的值获取出来了
- 在一键多值的情况下,返回了该键的全部值,而且在同一个列表中
- 在一个有键无值情况下,该键名c的值返回一个存储了一个空字符串的列表
- 在我们没有键也没有值的情况下,定义了默认值,返回默认值
- 在我们没有键也没有值的情况下,没有给他定义的默认值,返回了空列表
- get与getlist的相同点与区别
- 相同点:
- get和getlist获取的值的类型是 字符串类型
- 在有键无值情况下,返回的都是空字符串
- get和getlist都有提供默认值的功能
- 不同点
- get方法是将获取的值,直接以字符串方式展示了,getlist是将字符串放到了一个列表中
- 如果是一键一值情况下,那么两种方法使用效果一致
- 如果是一键多值情况下,get方法获取的值是 最后的那个键名的值,getlist方法获取的值是键名所有的值
- 无键无值的情况下:get方法返回的内容是一个None,getlist方法返回的内容是空列表
Response应答对象的详细解释
- HttpResponse对象在view文件中的创建方式
- 方式一: 返回一个模板页面或一个动态模板页面
- render(request, 'book_app/index.html',context)
- 第三个参数的两种形式
- 字典形式的参数,通过键值对的形式,django通过字典中的键值对来对模板文件中的变量进行渲染
- locals(),将view函数定义的所有局部变量都作为参数,django将view函数定义的所有局部变量作为参数来渲染模板文件;
- 方式二: 返回一个静态模板页面
- render_to_response('book_app/index.html')
- 方式三: 进行页面跳转,类似于超链接
- redirect('/')
- 方式四: 进行页面跳转,类似于超链接,继承自HttpResponse,被定义在django.http模块中,返回的状态码为302
- HttpResponseRedirect('/')
- 方式五: 直接在返回的页面中添加字符串功能
- HttpResponse('str ')
- 方式六: 接收字典形式的参数返回一个json格式的数据, 继承自HttpResponse,下面就进行详细解释
- JsonResponse(json数据)
- 备注:
- 其中:render 、render_to_response、HttpResponse、redirect 在django.shortcuts的模块中
- HttpResponseRedirect、JsonResponse 在 django.http的模块中
- JsonResponse对象详细解释
- JsonResponse对象简介:
- JsonResponse继承自HttpResponse,被定义在django.http模块中,它创建对象时候接收字典作为参数,当需要响应json数据给请求者时,需要用到JsonResponse,既然他是基础HTTPResponse的,那么就有那几个常见的属性,其中我们需要注意的是一点,JsonResponse的content-type属性值默认是application/json,也就是说JsonResponse响应的内容格式默认是json的
- JsonResponse对象的功能
- 生成JsonResponse对象
- 进行json数据应答,将传入的字典格式的数据内容转化成json格式的数据(实际上json格式的数据,就是字符串形式的字典)
- ajax收到了响应报文后jquery会把json格式的数据转化为js类的数据形式传再传递给ajax的回调函数
- JsonResponse对象响应案例,步骤:
- 配置js静态文件
- 在setting中配置Django的静态文件存放路径,并且在项目根目录下创建static文件夹存储js静态文件
- 在static文件夹中创建js文件夹,里面上传jq静态文件
- 在html中加载静态文件
- ajax使用get和each方法来展示数据
- 设置view函数,要在页面上展示图书信息,那么我们就要构造一个字典,给ajax使用
- HttpResponse对象的属性 (response对象或自动帮我们设置该部分属性,一般不需要我们手动进行修改)
- content 表示返回的内容
- charset 表示response采用的编码字符集,默认为utf-8
- status_code 返回的HTTP响应状态码
- 1XX 收到请求,请处理
- 2XX 操作成功,正常返回
- 3XX 对请求继续进一步处理,常见的就是重定向
- 4XX 客户端访问遇到的一些问题,找不到或者权限
- 5XX 服务端的问题
- content-type 指定返回数据的的MIME类型,默认为'text/html'
- MIME(Multipurpose Internet Mail Extensions)多用途互联网邮件扩展类型。是设定某种扩展名的文件用一种应用程序来打开的方式类型, 当该扩展名文件被访问的时候, 浏览器会自动使用指定应用程序来打开。多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式。这个东西就是一个标准,我们在网上一搜一大堆,都烂大街了,所以为了节省时间,我们直接忽略它。
- HttpResponse对象常见方法
- init 创建HttpResponse对象后完成返回内容的初始化
- set_cookie 设置Cookie信息
- 格式:set_cookie('key', 'value', max_age=None, expires=None)
- max_age 是一个整数,表示在指定秒数后过期,与expires二选一如果不指定过期时间,默认两个星期后过期
- expires 是一个datetime或timedelta对象,会话将在这个指定的日期/时间过期
- delete_cookie 删除指定的key的Cookie,如果key不存在则什么也不发生
- 格式:delete_cookie(key)
- write 向响应体中写数据
- cookie 是网站以键值对格式存储在浏览器中的一段纯文本信息,用于实现用户跟踪
视图的状态保持(HttpResponse和HttpRequest的cookie和session相关方法的应用)
- 状态保持的基础知识
- 无状态的介绍
- 浏览器的请求服务是无状态的,无状态就是指当用户的一次请求时,浏览器、服务器无法知道之前这个用户做过什么,无法记录用户端之前的所有状态,每次请求都是一次新的请求
- 无状态产生的原因:
- 浏览器和服务器之间的通信都遵守HTTP协议,HTTP请求报文无法记录状态的。
- 浏览器与服务器是使用Socket套接字进行通信的,每次客户端都会对HTTP报文进行构建和发送,服务器端接收到报文进行报文的回复,报文发送后就会对请求报文和响应报文对象进行删除,之后对套接字进行关闭,中间没有任何状态记录。
- 让请求保持状态的方法
- 在客户端存储信息使用Cookie,将状态信息保存在客户端 (可以被浏览器禁止使用)
- 在服务器端存储信息使用session,将状态信息保存在服务器端
- cookie的使用
- cookie使用的原理
- Cookie是由服务器端生成,发送给客户端浏览器,浏览器会将Cookie的key/value保存(key/value的值可能是客户端设定,也可能是服务器端自动生成),下次请求同一网站时就发送该Cookie给服务器(前提是浏览器设置为启用cookie),服务器根据发送过来的cookie来执行对应的逻辑操作。
- cookie的特点
- 由服务器端生成保存到浏览器
- Cookie是存储在浏览器中的一段纯文本信息,建议不要存储敏感信息如密码,当电脑被其他人攻击的时候,可以使用本机浏览器和cookie进行网页访问;
- Cookie基于域名安全,不同域名的Cookie是不能互相访问的,即浏览器存储的一个域名的cookie只能用于访问同一个域名
- 当浏览器请求某网站时,会将本网站下所有Cookie信息提交给服务器,所以在request中可以读取Cookie信息
- Cookie相关的方法:
- 设置Cookie
- Response.set_cookie('mark','hello')
- 也可以相当于修改cookie的对应的键的指标
- 读取Cookie
- c = Request.COOKIES['mark']
- Request.COOKIES 的结果为所有的cookie键值对组成的字典
- 判断是否存在某个Cookie
- if Request.COOKIES.has_key('mark'):
- # do something
- 删除Cookie
- Response.delete_cookie('mark')
- 删除cookie的一条键值对内容
- 测试浏览器支不支持cookie
- 第一次客户端请求执行
- request.session.set_test_cookie() 向客户端发送测试cookie
- 第二次客户端请求执行
- ret = request.session.test_cookie_worked() 获取侧是的cookie,如果不支持ret为空
- 创建cookie的参数(全部为缺省参数,在使用set_cookie的时候可以使用)
- max_age 默认None cookie生存时间,如果参数是None,这个cookie会延续到浏览器关闭为止
- expires 默认None cookie失效的实际日期/时间,格式必须是:Wdy, DD-Mth-YY HH:MM:SS GMT,这个参数会覆盖max_age参数
- 示例:
- path 默认"/" cookie生效的路径前缀,浏览器只会把cookie回传给带有该路径的页面,这样你可以避免将cookie传给站点中的其他的应用。
- domain 默认None 这个cookie在那个站点生效,如果为None,就是当前站点,如果设为domain=".example. com",则所有带example.com的二级域名站点都可读到cookie
- secure 默认False 如果设置为True,浏览器将通过HTTPS来回传cookie
- session的使用
- session的介绍
- 是在http协议的基础上通过具体的动态页面技术来实现的,对于敏感、重要的信息,建议要储在服务器端,不能存储在浏览器中,如用户名、余额、等级、验证码等信息,服务器可以根据scrf防止其他人攻击客户端的电脑进行模仿登录;
- session和Cookie的关联
- 想要使用session首先浏览器必须支持cookie,cookie中的sessionid的value相对应;
- 都是从服务器端生成的
- 使用session后,会生成一个经过编码的键值对(然后把编码后的键值对分别存储起来),服务器端会把sessionid和编码过后的键以键值对的形式存储在cookie中,当访问服务器的时候会携带session信息去数据库中寻找对应的session的数值
- session数据在存储前会自动获取一个base64格式的key,并将session的键值对集合编码成base64格式,两个数据加上session的修改日期存储到存储中,其key的值与
- session和cookie的区别
- session的数据是存储在服务器中的。cookie的数据是存储在客户端的
- 当访问增多,会比较占用你服务器的性能。
- session存储数据没有上限制,cookie存储数据具有上限、
- 一般的浏览器会限制保存cookie的数量小于20个
- cookie不安全,将数据直接存储在客户端
- session占用性能,用session存储数据会延长访问网站的时间
- session的使用
- 配置session
- 1、在setting中进行应用配置(要在数据库中创建出来对应存储session的表)
- 2、配置session的中间件
- 3、设置session的存储方法
- 我们服务器端的Session数据,可以存储在数据库、缓存、Redis等在Django项目中,我们可以通过设置SESSION_ENGINE项指定Session存储方式
- 存储方式设置(三种常见的方式):
- 如果不设置会默认存储在databased指定的数据库中
- 4、进行数据库迁移
- 5、会在数据库中生成用来存储session的表(如果是用数据库的存储方式)
- 包含字段:session_key session_data session_data
- session的使用方法
- 以键值对格式设置Session
- request.session['键'] = 值
- 设置后生成一个与之对应的session_key编号,设置的键值对会编码后,会和该session_key以对应关系存储在数据库中, 该session_kry会以 sessionid 字符串的value来和他存储在cookie中;
- 根据键读取Session值
- request.session.get('键',默认值)
- 如果没有对应的键,会读取到默认值
- 删除指定session键值对
- del request.session['键']
- 当所有的键的值对都被删除的时候,session_key不会被删除
- 清除所有session键值对
- request.session.clear()
- 当所有的键的值对都被删除的时候,session_key不会被删除
- 清除所有session键值对,并删除数据库的session_key(想当与清空了数据库表)
- request.session.flush()
- 当所有的键的值对都被删除的时候,session_key会被删除
- 设置会话的超时时间
- request.session.set_expiry(value)
- 如果没有指定过期时间则两个星期后过期,如果value是一个整数,会话将在value秒没有活动后过期,如果value为0,那么用户会话的Cookie将在用户的浏览器关闭时过期,如果value为None,那么会话永不过期
- 技巧:
- base64编码命令
- echo "hello" | base64 将字符串进行编码
- echo "aGVsbG8K" | base64 -d 将字符串进行解码
- 使用Redis存储session
django.contrib message框架模块
- message对象
- 作用:
- 可以快速的封装和获取session内容,取出的内容是可迭代对象,会将以该方法存储的内容都删除掉,经常用于做一次标志内容的确认,在一次确认完成后,删除session信息
- 使用方法:
- 存储session:
- message.add_message(request, message_type, value )
- request 为客户端的请求报文对象
- message_type 为存储类型,常用为messages.INFO(消息类型)
- value 为封装的消息,与request.session方法不同,这里传的不是key,value,但是我们可以自己进行封装
- 获取session
- message.get_messages(request)
- request为用户请求的报文对象
- 获取的内容为可迭代对象,可以通过迭代,将上一次通过add_message封装的消息都取出来,但是当使用get方法之后,之前add方法存入session的内容,都将被删除