django 进阶-- 视图

URL配置过程
1、settings.py中,指定入口urls文件(项目创建时自动配置的)
ROOT_URLCONF = '项目.urls'
2.在项目中urls.py中,包含到应用的urls.py
url(正则, include('应用.urls'))
3.应用中urls.py中,调用views.py对应的函数
url(正则, views.函数名)

URL函数
url函数有两个参数,第一个参数是一个正则表达式,第二个是对应的处理动作。配置url时,有两种语法格式:
  • a) url(正则表达式,视图函数名)
  • b) url(正则表达式,include(应用中的urls文件))

URL匹配过程


Django在检查URL模式前,移除每一个申请的URL开头的斜杠(/)。 这意味着我们为/hello/写URL模式不用包含斜杠(/)。(刚开始,这样可能看起来不直观,但这样的要求简化了许多工作,如URL模式内嵌,我们将在第八章谈及。)
模式包含了一个尖号(^)和一个美元符号($)。这些都是正则表达式符号,并且有特定的含义: 上箭头要求表达式对字符串的头部进行匹配,美元符号则要求表达式对字符串的尾部进行匹配。
最好还是用范例来说明一下这个概念。 如果我们用尾部不是$的模式’^hello/’,那么任何以/hello/开头的URL将会匹配,例如:/hello/foo 和/hello/bar,而不仅仅是/hello/。类似地,如果我们忽略了尖号(^),即’hello/$’,那么任何以hello/结尾的URL将会匹配,例如:/foo/bar/hello/。如果我们简单使用hello/,即没有^开头和$结尾,那么任何包含hello/的URL将会匹配,如:/foo/hello/bar。因此,我们使用这两个符号以确保只有/hello/匹配,不多也不少。
你大多数的URL模式会以^开始、以$结束,但是拥有复杂匹配的灵活性会更好。
你可能会问:如果有人申请访问/hello(尾部没有斜杠/)会怎样。 因为我们的URL模式要求尾部有一个斜杠(/),那个申请URL将不匹配。 然而, 默认地, 任何不匹配或尾部没有斜杠(/)的申请URL,将被重定向至尾部包含斜杠的相同字眼的URL。 (这是受配置文件setting中APPEND_SLASH项控制的,参见附件D。)
如果你是喜欢所有URL都以’/’结尾的人(Django开发者的偏爱),那么你只需要在每个URL后添加斜杠,并且设置”APPEND_SLASH”为”True”. 如果不喜欢URL以斜杠结尾或者根据每个URL来决定,那么需要设置”APPEND_SLASH”为”False”,并且根据你自己的意愿来添加结尾斜杠/在URL模式后.
另外一个重点,正则表达式字符串的开头字母“r”。 它告诉Python这是个原始字符串,不需要处理里面的反斜杠(转义字符)。 在普通Python字符串中,反斜杠用于特殊字符的转义。比如n转义成一个换行符。 当你用r把它标示为一个原始字符串后,Python不再视其中的反斜杠为转义字符。也就是说,“n”是两个字符串:“”和“n”。由于反斜杠在Python代码和正则表达式中有冲突,因此建议你在Python定义正则表达式时都使用原始字符串。 从现在开始,本文所有URL模式都用原始字符串。

正则书写规则
  • 推荐使用r,表示字符串不转义,这样在正则表达式中使用\只写一个就可以
  • 不能在开始加反斜杠,因为在截取url时会自动去掉前面的反斜杠再和正则匹配,如果在正则前面加反斜杠就匹配不上了。
正确:index/正确:index错误:/index错误:/index/
URL中取值
如果想从URL中获取值,需要在正则表达式中使用分组,获取值分为两种方式
  • 位置参数 参数的位置不能错
  • 关键字参数 参数的位置可以变,跟关键字保持一致即可
注意:两种参数的方式不要混合使用,在一个正则表达式中只能使用一种参数方式

使用位置参数
urls配置:
url(r'^(\d+)/(\d+)/$', views.index)
视图中配置:
def index(request, value1, value2): context = {'v1':value1, 'v2':value2} return render(request, 'booktest/index.html', context)
使用关键字参数
urls配置:
url(r'^(?P<canshu1>\d+)/(?P<canshu2>\d+)/$', views.index),
视图中配置:
def index(request, canshu2, canshu1): context = {'v1':canshu1, 'v2':canshu2} return render(request, 'booktest/index.html', context)


Django内置处理HTTP错误的视图,主要错误及视图包括:
  • 404错误:page not found视图 url匹配不成功会发生404错误
  • 400错误:bad request视图 来自客户端的安全方面非法操作会引发400错误
  • 500错误:server error视图 在视图中代码运行报错会发生500错误
只需要在模板中定义指定html文件即可,不需要配置URL和准备视图,之前的模板路径配置正确就行了。
定义404模板内容:


想看到错误视图,需要修改settings.py文件的DEBUG项,否则默认还是显示调试的错误信息,这个调试的错误信息是针对开发人员的,不能给用用户看到。



HttpReqeust对象 #即视图中的request参数
以下列出了HttpRequest对象的属性,除特别说明,属性都是只读的:
类型
说明
GET
一个类似于字典的QueryDict对象,包含get请求方式的所有参数,也就是请求地址“?”后面的内容
POST
一个类似于字典的QueryDict对象,包含post请求方式的所有参数
COOKIES
一个标准的Python字典,包含所有的cookie,键和值都为字符串
session
一个既可读又可写的类似于字典的对象,表示当前的会话,只有当Django启用会话的支持时才可用
path
一个字符串,表示请求的页面的完整路径,不包含域名
method
一个字符串,表示请求使用的HTTP方法,常用值包括:GET、POST,使用浏览器的地址栏发请求采用的是get方式,在表单中可以通过method属性设置get或post方式
FILES
一个类似于字典的QueryDict对象,包含所有的上传文件
  • 服务器接收到http请求后,django框架会自动根据报文创建HttpRequest对象
  • 视图的第一个参数必须是HttpRequest类型的对象
  • 在django.http模块中定义了HttpRequest对象的API
  • 使用HttpRequest对象的不同属性值,可以获取请求中多种信息
GET属性
# get请求通过HttpRequest对象的GET属性获取
获取请求地址栏“?”后面的数据,需要用到HttpRequest对象的GET属性,获取到的是一个QueryDict对象。
# 通过GET属性获取地址栏上的数据,获取的QueryDict对象 dict = request.GET

POST属性
使用form表单提交请求时,method方式为post则会发起post方式的请求,需要使用HttpRequest对象的POST属性接收参数,POST属性返回QueryDict类型的对象。
思考 :form表单如何提交请求参数呢? 标签name属性的值作为键,value属性的值为值,构成键值对提交,如果控件没有name属性则不提交。
提示: 对于checkbox多选项,name属性的值相同为一组,被选中的项会被提交,出现一键多值的情况

QueryDict对象
#get和post属性都是QueryDict对象,QueryDict对象形式和字典类似,但是可以一键对应多个值
  • QueryDict对象定义在django.http.request中,HttpRequest对象的GET、POST属性都是QueryDict类型的对象
  • 与标准python字典不同,QueryDict类型的对象可以用来处理同一个键带有多个值的情况
  • QueryDict类型的对象,键和值都是字符串类型
  • 键是开发人员在编写代码时确定下来的,值是根据数据生成的
  • QueryDict类型的对象不是字典,仅仅是类似字典的对象而已

相关方法
get()方法
根据键获取值,如果一个键同时拥有多个值将获取最后一个值,如果键不存在则返回None值,可以设置默认值进行后续处理。
两种写法:
dict.get('键',默认值) # 如果不存在键对应的值,且没有设默认值,返回none dict['键'] # 简写方式, 如果不存在键对应的值,会报异常
getlist()方法
根据键获取值, 值以列表返回 ,可以获取指定键的所有值, 如果键不存在则返回空列表 [], 可以设置默认值进行后续处理。
dict.getlist('键',默认值)

HttpResponse对象
  • 视图在接收请求并处理后,必须返回HttpResponse对象或子对象:JsonResponse和HttpResponseRedirect
  • 在django.http模块中定义了HttpResponse对象的API
  • HttpResponse对象由开发人员创建

HttpResponse对象常用方法
set_cookie:设置Cookie信息
delete_cookie:删除指定的key的Cookie

调用模板-简写:
from django.shortcuts import renderdef test(request): # 定义上下文 context = {'key':'value'} # 获取模板,渲染模板,让模板语言执行 return render(request, 'booktest/test.html', context)

JsonResponse #返回json数据响应
JsonResponse继承自HttpResponse,被定义在django.http模块中, 接收字典作为参数。
使用场景:当页面的需要制作ajax效果时,需要用到JsonResponse对象,它可以返回json数据格式。

HttpResponseRedirect #重定向
Django中提供了HttpResponseRedirect对象实现重定向功能,这个类继承自HttpResponse,被定义在django.http模块中。

重定向简写函数redirect
在django.shortcuts模块中为重定向类提供了简写函数redirect,修改booktest/views.py文件中red1视图,代码如下:
from django.shortcuts import redirect...def red1(request): return redirect('/')

状态保持
  • 浏览器请求服务器是无状态的。
  • 无状态:指一次用户请求时,浏览器、服务器无法知道之前这个用户做过什么,每次请求都是一次新的请求。
  • 无状态原因:浏览器与服务器是使用Socket套接字进行通信的,服务器将请求结果返回给浏览器之后,会关闭当前的Socket连接,而且服务器也会在处理页面完毕之后销毁页面对象。
  • 有时需要保持下来用户浏览的状态,比如:用户是否登录,浏览过哪些商品等
  • 实现状态保持主要有两种方式:
  • 在客户端存储信息使用Cookie
  • 在服务器端存储信息使用Session
Cookie
  • Cookie可以在前端用JavaScript生成,也可以由后端生成,发送给前端浏览器
  • Cookie是以key/value的形式字符串在浏览器上保存的
  • 下次请求同一网站时,在浏览器中保存的Cookie会跟随http协议一起传回给服务器
Cookie的应用
  • 记录用户状态,比如:判断用户是否已经登录
  • 网站的广告推送
  • 购物车信息
Cookie使用注意点
  • 不要用Cookie存储敏感信息,比如:密码,因为cookie存在本地浏览器,可能会被其他人获取
  • Cookie基于域名安全,不同域名的Cookie是不能互相访问的
  • 当浏览器请求某网站时,此网站所有Cookie信息会自动携带上传,所以在django中可以通过request对象获取到Cookie信息

Cookie的使用
1、查看Cookie

2、设置Cookie #使用response.set_cookie设置cookie,返回的response对象会携带cookie
response.set_cookie('mark', 'hello', max_age=None, expires=None)
Cookie参数说明:
  • max_age是一个整数,表示在指定秒数后过期
  • expires是一个datetime或timedelta对象,会话将在这个指定的日期/时间过期
  • max_age与expires二选一
  • 如果不指定过期时间,默认关闭浏览器,cookie就会过期
3、 读取Cookie,获取的数据是字典格式
c = request.COOKIES['mark']

Session
对于敏感、重要的信息,建议要储在服务器端,不能存储在浏览器中,如用户名、余额、等级、验证码等信息,在服务器端进行状态保持的方案就是Session。
启用Session
Django项目默认启用Session,在settings文件中的 MIDDLEWARE_CLASSES默认启用了Session中间件,如果想禁用session,可以将这一句删掉。 

存储方式
ENGINE项指定Session数据存储的方式,可以存储在数据库、缓存、Redis等
存储在数据库中,这是默认存储方式(可以不写),如用其它方式储存,需要添加设置、
SESSION_ENGINE='django.contrib.sessions.backends.db'
存储在缓存中:存储在本机内存中,如果丢失则不能找回,比数据库的方式读写更快
SESSION_ENGINE='django.contrib.sessions.backends.cache'
混合存储:优先从本机内存中存取,如果没有则从数据库中存取
SESSION_ENGINE='django.contrib.sessions.backends.cached_db'
如果存储在数据库中,需要在项INSTALLED_APPS中安装Session应用 

迁移后会在数据库中创建出存储Session的表:

表结构如下图,由表结构可知,操作Session包括三个数据:键,值,过期时间


Session依赖于Cookie
所有请求者的Session都会存储在服务器中,服务器如何区分请求者和Session数据的对应关系呢?
答:在使用Session后,会在Cookie中存储一个sessionid的数据,每次请求时浏览器都会将这个数据发给服务器,服务器在接收到sessionid后,会根据这个值找出这个请求者的Session 结果:如果想使用Session,浏览器必须支持Cookie,否则就无法使用Session了 存储Session时,键与Cookie中的sessionid相同,值是开发人员设置的键值对信息,进行了base64编码,过期时间由开发人员设置。

对象及方法
设置session
request.session['键']=值
根据键读取值
request.session.get('键',默认值)
# 也可以用request.session[键]获取,如果不存在,会报错。
清除所有会话,在存储中删除值部分
request.session.clear()
清除会话数据,在存储中删除会话的整条数据
request.session.flush()
删除会话中的指定键及值,在存储中只删除某个键及对应的值
del request.session['键']
设置会话的超时时间:
  • 如果value是一个整数,会话sessionid对应的cookie将在value秒后过期
  • 如果value为0,会话sessionid对应的cookie将在用户的浏览器关闭时过期
  • 如果value为None,会话sessionid对应的cookie将在两周后过期
request.session.set_expiry(value)

类视图
1.导入类视图模块
from django.views.generic import View
2.配置url View类自带as_view()方法
url(r'^register/$', RegisterView.as_view(),name='register')
3. 创建类视图 # 继承View即可
自动判断请求类型调用对应的函数
class RegisterView(View):
def get(self,request):
return render(request, 'register.html')
def post(self,request):
pass

# itsdangerous 的使用
pip install itsdangerous
from itsdangerous import TimedJSONWebSignatureSerializer as Itsdanger
from itsdangerous import SignatureExpired # 解密异常类
# 秘钥,解密过期时间,返回一个对象
sce= Itsdanger(‘secret_key’,3600)
sce1= Itsdanger(‘secret_key’,3600)
# TimedJSONWebSignatureSerializer 对象的 dumps()方法对数据进行加密
# 数据可以是对象,也可以是其它类型数据,返回一个字节型(二进制)对象
res = sce.dumps(数据)
# TimedJSONWebSignatureSerializer 对象的 loads()方法对数据进行解密
resec = sce.loads(res)
# 如果创建时参数相同,
# 其它对象也可以对此对象的加密数据进行解密, 解密返回原数据类型
resec1 = sce1.loads(res)
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值