美文网首页Django
06-Django视图

06-Django视图

作者: EndEvent | 来源:发表于2018-07-29 16:17 被阅读1099次

    一、视图概述

    Django用视图这个概念封装处理用户请求并返回响应的逻辑。
    定义视图函数相关的URL(网址) (即规定 访问什么网址对应什么内容)。或者说视图接受Web请求,并响应Web请求。

    视图的本质就是一个python函数.

    • 概念
    - 响应
        网页(包含重定向、错误视图404、错误视图500、错误视图400)
        JSON数据
    - 过程
        用户在浏览器中输入网址www.zyz.com/meituan/detail.html
        django获取到网址信息,截取掉IP和端口 meituan/detail.html
        对应虚拟路径和文件名,在url管理器中逐个匹配urlconf列表 detail
        调用视图管理器中的detail,返回对应结果给浏览器
    
    • 定义视图
    from  django.http import HttpResponse
    # 没有使用任何的模板
    def index(request):
        return HttpResponse('hello zyz!!!')
    
    • 配置url (简单)
    # 修改project/urls.py文件
    from django.conf.urls import url,include
    from django.contrib import admin
    
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^', include('myapp.urls', namespace='app')),   # 会定位到myapp.urls中
    ]
    
    
    # 在对应应用中appname中,创建urls.py文件(与上面文件类似)
    from django.conf.urls import url
    from . import views     # 导入视图
    
    urlpatterns = [
        url(r'^$', views.index, name='index')   # 匹配到的就是views中的首页
    ]
    
    • 配置url (带参数)
    # 描述(在views.py中定义的视图)
    def detail(request,num):
        return HttpResponse('detail-%s' % num)
    
    
    # 在appname/urls.py中配置即可     
    urlpatterns = [
        url(r'^$', views.index), 
        # 添加括号,其实就是正则表达式中的组的概念。
        # 而匹配到的就是可以给到 detail(request,num) 函数中的num
        url(r'^(\d+)/$', views.detail)
    ]
    

    二、URL配置

    • 配置流程
    - URL配置文件
        settings.py文件中ROOT_URLCONF=project.urls (默认已经配置好)
    - project.urls.py文件
        urlpatterns是一个url实例列表
        url对象(正则表达式,视图名称,名称)
        例如: url(r'^admin/', admin.site.urls,name='admin')
    - url匹配正则注意事项
        想要从url中获取一个值,需要对正则加小括号(即分组)
        匹配正则前方不需要加反斜杠
        正则前面需要加r表示字符串不转义
    
    • 引入其他配置
    - 在应用中创建urls.py文件,配置该应用内的路由
    from django.conf.urls import url
    from . import views
    urlpatterns = [
        url(r'^$', views.index, name='index'),
        url(r'^(\d+)/$', views.detail, name='detail'),
    ]
    
    - 在工程目录中urls.py分发到对应应用中
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^app/', include('myapp.urls', namespace='app')),
    ]
    
    • 反向解析
    - 概述: 如果在视图、模板中使用了硬编码链接,在url配置发生改变时,动态生成链接地址
    - 解决: 在使用链接时,通过url配置的名称,动态生成url地址
    - 作用: 使用url模板或试图中
    

    模板中: {% url 'namespace:name' value1 value2 ...%}
    视图中: redirect('namespace:name', arg1, arg2...)

    三、视图函数

    • 定义视图
    - 本质: 视图即是一个函数
    - 参数: 一个HttpRequest对象,通过正则表达式获取的参数
    - 位置: 一般会在views.py中定义
    
    • 错误视图
    - 404视图   
        找不到网页时返回(url匹配不成功)
        在temmplates目录下定义404.html({{request_path}}会输出导致错误的网址)
        配置settings.py(DEBUG如果为True永远不会调用404.html页面)
        配置settings.py(ALLOWED_HOSTS=['*'])
    
    - 505视图
        视图代码出现错误(服务器错误)
    
    - 400视图
        错误出现在客户的操作
    

    四、HttpRequest对象

    • 概述
    - 服务器接收http请求后,会根据报文创建HttpRequest对象
    - 视图的第一个参数就是HttpRequest对象
    - django创建的,之后调用视图时传递给视图
    
    • 属性
    - path 
        请求的完整路径(不包括域名和端口)
    - method 
        请求的方式,常用有GET、POST
    - encoding
        浏览器提交数据的编码方式
    - GET [GET请求参数]
        类似字典对象,包含get请求的所有参数
    - POST [POST请求参数]
        类似字典对象,包含post请求的所有参数
    - FILES
        类似字典对象,包含所有上传的文件
    - COOKIES 
        字典,包含所有的cookie
    - session
        类似字典对象,表示当前会话
    
    • 方法
    - is_ajax()
        通过XMLHttpRequest发起的,就会返回True
    
    • QueryDict对象
    - request对象中的GET、POST都属于QueryDict对象
    - get() 
        根据键获取值(只能获取一个)
        也可以通过方括号的方式获取数据(如果不存在会报错)
    - getlist()
        根据键获取值(返回的是一个列表,可以获取多个值)
    
    • GET属性
    - 获取浏览器传递给服务器的数据
    - 例如: http://127.0.0.1:8000/zyz/get1?a=1&b=2&c=3
    def get1(request):  
        a = request.GET.get('a')
        b = request.GET['b']
        c = request.GET.get('c')
    
        return HttpResponse('a:%s  b:%s  c:%s' % (a,b,c))
    - 例如: http://127.0.0.1:8000/zyz/get2?a=1&a=2&b=3
    def get2(request): 
        a = request.GET.getlist('a')
        a1 = a[0]
        a2 = a[1]
    
        b = request.GET['b']
    
        return HttpResponse('a1:%s  a2:%s  b:%s' % (a1, a2, b))
    

    GET请求,请求的数据会添加到URL之后,以?分割URL和传输数据,多个参数用&连接;

    • POST属性
    def register(request):
        # 例如在输入框中对应name属性
        name = request.POST['user']
        passwd = request.POST.get('passwd')
        tel = request.POST.get('tel')
    
        return HttpResponse('注册成功,%s正在登录中....' % (name))
    

    使用表单提交post请求时,需要关闭csrf(settings.py中的MIDDLEWARE内的'django.middleware.csrf.CsrfViewMiddleware',)
    POST请求: 请求的数据放置在是HTTP的请求体中;

    • 什么是 HTTP
      超文本传输协议(HTTP)的设计目的是保证客户机与服务器之间的通信。
      HTTP 的工作方式是客户机与服务器之间的请求-应答协议。
      客户端(浏览器)向服务器提交 HTTP 请求;服务器向客户端返回响应。

    • HTTP请求方法

    1   GET     请求指定的页面信息,并返回实体主体。
    2   HEAD    类似于get请求,只不过返回的响应中没有具体的内容,用于获取报头
    3   POST    向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的建立和/或已有资源的修改。
    4   PUT     从客户端向服务器传送的数据取代指定的文档的内容。
    5   DELETE  请求服务器删除指定的页面。
    6   CONNECT HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。
    7   OPTIONS 允许客户端查看服务器的性能。
    8   TRACE   回显服务器收到的请求,主要用于测试或诊断。
    
    • GET和POST请求
    - get一般是从服务器上获取数据,post一般是向服务器传送数据;
    - get传送的数据量较小,不能大于2KB。post传送的数据量较大,一般被默认为不受限制;
    - get安全性非常低,post安全性较高();
      如果没有加密,他们安全级别都是一样的,随便一个监听器都可以把所有的数据监听到(即也没有所谓的安全性高低问题);
    

    五、HttpResponse对象

    • 概述
    - 用于给浏览器返回数据
    - HttpRequest对象是django创建的,HttpResponse对象是自己创建的
        response = HttpResponse()
    
    • 返回操作
    - 不调用模板(HttpResponse)
        def index(request):
            return HttpResponse('hello zyz!!!')
            
    - 调用模板(render)
        原型: render(request,templateName,[context...])
        作用: 结合数据和模板,返回完整的HTML页面
        参数: request(请求体对象)、templateName(模板路径)、context(传递给模板的数据)
        例如: return render(request,'myapp/students.html',{'students':studentList})
    
    • 属性
    - content 
        返回的内容
    - charset
        返回的编码类型
    - status
        返回的状态码(200/304/404)
    - content-type
        指定输出的MIME类型
    
    • 方法
    - init 
        使用页面内容实例化HttpResponse对象
    - write(content)
        以文件的形式写入
    - flush()
        以文件的形式输出缓冲区
    - set_cookie(key,value)
        设置cookie
    - delete_cookie(key)
        删除cookie
        删除一个不存在的key,就当什么都没发生
    
    • 子类HttpResponseRedirect
    - 作用
        重定向,服务器端的跳转
    - 简写
        return  HttpResponseRedirect('/redirect2') 
    
        from django.shortcuts import redirect
        return redirect('/redirect2')
    

    反向解析不带参数: return redirect('meituan:detail')
    反向解析带参数: return redirect('meituan:detail', 10, 5)

    • 子类JsonResponse
    返回json数据,一般用于异步请求
    def jsonrequest(request):
        stu = {
            'name':'zhangsan',
            'score':90,
            'age':20
        }
        return JsonResponse(stu)
    

    Content-type类型: application/json

    六、会话技术之cookie

    • 概述
    - http协议是无状态的,每次请求都是一次新的请求,不会保持之前的请求状态
    - 客户端与服务器的一次通信就是一次回话
    - 实现状态保持,在客户端或服务器存储有关回话数据
    - 存储方式
        cookie: 所有数据存储在客户端(不要存储敏感的数据)
        session: 所有数据存储在服务端(在客户端用cookie存储session_id)
    - 状态保持的目的
        在一段时间内跟踪请求者的状态,可以实现跨页面访问当前的请求者数据
    

    会话技术,其实也就是为了状态的保持,延长请求的生命周期。

    • cookie概述
    cookie 客户端的会话技术(数据存储在客户端);
    cookie 本身由浏览器生成,通过Response将cookie写到浏览器上,下次访问,浏览器会根据不同的规则携带cookie过来;
    
    • cookie使用
    - 创建响应
      response = HttpResponse()
    
    - 设置cookie
        response.set_cookie(key,value)
    
    - 获取cookie
        request.COOKIE.get(key, defaultvalue=None)
        
    - 删除cookie
        response.delete_cookie(key)
        
    - 支持过期时间
        默认: 关闭浏览器即cookie自动清除(Django)
        response.set_cookie(key,value,max_age=None,expires=None)
            max_age: 整数,指定cookie过期时间(单位秒)
            expires: 整数,指定过期时间,还支持datetime或timedelta指定具体时间
            max_age和expires两个选一个指定
    
    
            max_age=0           浏览器关闭失效
            max_age=Node        永不过期
            max_age=Int数值     指定过期时间(单位秒)
            expires             过期时间,和max_age基本一致,多一个时间差
            例如: expires=timedelta(days=10)    10天后过期
            例如: expires=timedelta(minutes=1)  1分钟
    

    cookie不能跨浏览器!

    • cookie使用场景
    用户系统状态、购物车(京东的)...
    
    Cookie交互流程

    七、会话技术之session

    • session概述
    session 服务端的会话技术;
    session 依赖于cookie;
        将session在数据库中的session_key当做sessionid存储在cookie中;
    在Django中数据被存储在数据库中,并做了数据安全,使用base64进行编码;
    
    • 启用session
    在settings文件中(默认是已经启用)
        INSTALLED_APPS: 'django.contrib.sessions',
        MIDDLEWARE: 'django.contrib.sessions.middleware.SessionMiddleware',
    
    • 使用session
    启用session后,每个HttpRequest对象中都会有session属性(类似字典的对象)
    - 设置session
        request.session[key] = value
        
    - 获取session
        request.session.get(key, defaultvalue=None)
    
    - 清除当前会话
        response.delete_cookie('sessionid')
        del request.session[key]
        
    - 同时清除cookie 和 session
        request.session.flush()
    

    要注意浏览器中会有缓存问题!

    • 设置过期时间
    set_expiry(value)
        value是整数(秒数): request.session.set_expiry(10)
        value是时间对象
        value是0: 关闭浏览器时失效
        value是None: 永不过期
    

    默认有效时间为两周

    • 存储session的位置
    - 数据库
        默认存储在数据库中,在settings.py中添加
        SESSION_ENGINE = 'django.contrib.sessions.backends.db'
    - 缓存
        只存储在本地内容中,如果丢失不能找回,但速度会比在数据库中快
        SESSION_ENGINE = django.contrib.sessions.backends.cache'
    - 数据库和缓存
        有限从本地缓存中读取,读取不到再去数据库中获取
        SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'
    
    • 使用redis缓存session
    - 安装redis: pip3 install django-redis-sessions
    - 在settings.py中添加
        # redis服务相关信息
        SESSION_ENGINE = 'redis_sessions.session'
        SESSION_REDIS_HOST = 'localhost'
        SESSION_REDIS_PORT = 6379
        SESSION_REDIS_DB = 0  # 选择数据库
        SESSION_REDIS_PASSWORD = '123456'  # 如果没有密码,则不需要
        SESSION_REDIS_PREFIX = 'session'  # 前缀
    - 使用时还需要启动redis
        redis-server
    
    session交互流程

    八、会话技术之token

    • token概述
    token 服务端会话技术;
    token 实际就是手动实现session;
    
    • token生成
    # token唯一标识
    # 策略1: 时间戳 + 随机数 + 公司域名 + ip信息
    # 策略2: 时间戳 + 域名
    # ...
    
    
    def generate_token():
        token = str(time.time()) + str(random.random())
        # md5算法
        md5 = hashlib.md5()
        md5.update(token.encode('utf-8'))
        
        token = md5.hexdigest()
        
        return token
    

    MD5消息摘要算法,一种被广泛使用的密码散列函数,可以产生出一个128位(16字节)的散列值(hash value),用于确保信息传输完整一致。【摘要算法、哈希算法】

    • UUID

    通用唯一标识符(Universally Unique Identifier), 对于所有的UUID它可以保证在空间和时间上的唯一性。
    通过MAC地址, 时间戳, 命名空间, 随机数, 伪随机数来保证生成ID的唯一性。 UUID可以被用作多种用途, 既可以用来短时间内标记一个对象, 也可以可靠的辨别网络中的持久性对象。

    - uuid1() 基于时间戳 【不建议使用】
        由MAC地址、当前时间戳、随机数生成;
        但MAC的使用同时带来安全性问题,局域网中可以使用IP来代替MAC;
        例如: token = uuid.uuid1()
        
    - uuid2() 基于分布式计算环境DCE 【Python中没有这个函数】
        算法与uuid1相同,不同的是把时间戳的前4位置换为POSIX的UID;
        实际中很少用到该方法;
        
    - uuid3(namespace,name) 基于名字的MD5散列值   【推荐使用】
        通过计算名字和命名空间的MD5散列值得到;
        保证了同一命名空间中不同名字的唯一性和不同命名空间的唯一性;
        但同一命名空间的同一名字生成相同的uuid;
        例如: token = uuid.uuid3(uuid.NAMESPACE_DNS, 'test')
        
    - uuid4() 基于随机数            【不推荐使用】
        由伪随机数得到,有一定的重复概率,该概率可以计算出来;
        例如: token = uuid.uuid4()
        
    - uuid5(namespace,name) 基于名字的SHA-1散列值 【推荐使用】
        算法与uuid3相同,不同的是使用 Secure Hash Algorithm 1 算法;
        例如: token = uuid.uuid5(uuid.NAMESPACE_DNS, 'test')
    

    namespace 可以是任意 uuid 字符串,例如: temp = uuid.uuid5(uuid.uuid4(), 'test')

    九、数据安全

    服务器的数据对任何人来说都应该是不可见的(不透明的);
    可以使用常见的摘要算法对数据进行摘要(md5,sha);
    如果使用了数据安全,那么就需要在所有数据验证的地方都加上 数据安全;

    # 例如使用MD5
    def password_set(password):
        md5 = hashlib.md5()
        md5.update(password.encode("utf-8"))
        return md5.hexdigest()
    

    相关文章

      网友评论

        本文标题:06-Django视图

        本文链接:https://www.haomeiwen.com/subject/mzzzmftx.html