Django-View

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的内容,都将被删除

刘小恺(Kyle) wechat
如有疑问可联系博主