06-Django视图

一、视图概述

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()
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,793评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,567评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,342评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,825评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,814评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,680评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,033评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,687评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,175评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,668评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,775评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,419评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,020评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,206评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,092评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,510评论 2 343

推荐阅读更多精彩内容

  • Spring Web MVC Spring Web MVC 是包含在 Spring 框架中的 Web 框架,建立于...
    Hsinwong阅读 22,306评论 1 92
  • 模块间联系越多,其耦合性越强,同时表明其独立性越差( 降低耦合性,可以提高其独立性)。软件设计中通常用耦合度和内聚...
    riverstation阅读 2,059评论 0 8
  • 1.ios高性能编程 (1).内层 最小的内层平均值和峰值(2).耗电量 高效的算法和数据结构(3).初始化时...
    欧辰_OSR阅读 29,300评论 8 265
  • 我仰望这星空 其中几颗 是你曾经许下的梦 这是很久前看到这图片时想到的句子,有时候我们仰望的,不只是星空,还有那生...
    6abe3eebe003阅读 144评论 0 0
  • 一般喷上去几秒就开始起效,前5分钟会比较热辣,是因为产品里有羌活提取物,可以快速发热,打开毛细血管,让药快速渗透到...
    陈丽钦阅读 166评论 0 0