1. URLConf
- 浏览器访问地址由哪个视图处理有url决定。创建django项目时,默认已在setting.py中配置好了url配置入口:
- 一般在项目urls.py中包含应用的urls.py,在应用的urls.py中创建具体匹配;
- urls.py内容为urlpatterns,为url()对象列表。url()在django.conf.urls中定义,有两种用法:
url(r'^', include('booktest.urls')) # 包含应用中urls
url(r'^$', views.index) # 指向应用中具体视图
注意:正则部分前面推荐使用'r',表示字符串不转义,另外匹配的字符串前面不能有'/'。请求url按普通字符串匹配,不包括域名以及get或post参数。
2. 视图
2.1 获取请求参数
- 直接在请求匹配中获取参数需要在正则表达式中使用小括号,有两种使用方式:
- 位置参数:按位置依次在视图内接收小括号中的值;
- 关键字参数:使用“?P<参数名>”,例:
url(r'book/(?P<bookid>\d+)$', views.detais)
2.2 内置错误视图
- django内置404 Page Not Found视图和500 server error视图。
- 要显示错误视图而不是错误信息,需将默认debug改为False:
- 可以自定义404.html和500.html(模板查询有顺序,按一定路径找不到后使用默认页面):
2.3 HttpRequest对象
django收到请求后,会根据报文创建HttpResquest对象,必须在视图的第一个参数。
- 属性(除非特殊说明,否则属性都是只读的):
- path:完整请求路径,不包含域名和请求参数;
- method:请求方法,常用的有'GET'和'POST';
- encoding:提交数据的编码方式,None表示使用浏览器默认编码方式,一般为utf8。注意这是一个可写属性,修改后对属性的接收使用的是新的编码方式:
- GET:QueryDict类型对象,类似于python字典,包含get方式请求的所有参数;
- POST:QueryDict类型对象,类似于字典,包含post方式请求的所有参数;
- FILES:类似于字典的对象,包含上传的所有文件;
- COOKIES:标准的python字典,包含所有cookies,键和值都是字符串;
- session:类字典对象,表示当前会话。注意session也是一个即可读又可写属性;
- QueryDict对象:
- 定义在django.http.QueryDict;
- 用来处理同一个键对多个值的情况;
- 方法:
get('key')
:如果有多个值获取最后一个,没有返回None;get('key','default')
:没有时返回default值;getlist('key')
:返回值列表,如果没有返回[];getlist('key', 'default')
:如果没有,返回default值。
2.4 HttpResponse对象
HttpRequest对象由django创建,HttpResponse对象需要用户自定义。
- 属性:
- content:返回的内容
- charset:response采用的编码字符集,默认为utf-8;
- status_code:响应码;
- 方法:
- set_cookie:
set_cookie('key', value='', max_age=None, expires=None)
- max_age:指定秒后过期;
- expires:datetime或timedelta对象,会话将在这个指定的日期/时间过期;
- max_age和expires二选一。如果不指定过期时间,则在关闭浏览器时cookie过期。
- del_cookie(key):如果key不存在则不作任何处理;
- write():向响应体中写数据;
2.4.1 子类JsonResponse
继承自Response,定义在django.http模块,创建对象时接受字典作为参数。JsonResonse对象的Content-Type为'application/json'。
- 添加jquery文件:
- 配置静态文件查找目录:
- 配置url,定义视图
- 定义页面:
- 视图:
- 效果:
- 交互过程:
2.4.2 子类HttpResponseRedirect
也是继承自Response,定义在django.http模块,返回的状态码为302。
使用:return HttpResponseRedirect('/')
,简写为return redirect('/')
。
3. cookie和session
3.1 cookie
cookie由服务器生成,发送到浏览器,以key-value的形式保存在某个目录下的文本文件内,下次请求同一网站时将cookie发送给服务器。
cookie基于域名安全,不同域名的cookie不能互相访问。
浏览器请求某网站时,会将浏览器存储的跟网站相关的所有cookie信息提交给服务器。
- django中使用cookie
- 设置cookie:创建HttpResponse对象,使用对象的
set_cookie('key', 'value')
方法设置cookie;- 获取cookie:使用request的COOKIES属性(标准字典)获取cookie;
3.2 session
cookie是将数据存至浏览器,而且还得时浏览器打开cookie使用时。对于一些重要状态数据,保存至浏览器并不安全,这个时候就需要使用session。
session使用也要浏览器支持cookie,服务器将数据存储起来后,会有唯一对应的id,该id一般作为返回给浏览器的cookie中'sessionid'
的值。
- django默认开启session,在
settings.py
中MIDDLE_WARE CLASSES
中通过中间件开启。如果禁用,则将session中间件删除即可:- session存储方式:
- 存储在数据库中,如下设置可以不写,默认就是存在数据库中:
SESSION_ENGINE = 'django.contrib.sessions.backends.db'
- 存储在缓存中,在本机内存中,读写更快但关闭后无法找回:
SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
- 混合存储:优先从本机内存存取,如果没有则访问数据库:
SESSION_ENGINE = 'django.contrib.sessions.cached_db'
- 以数据库方式存储,需要在应用中添加Session应用(默认已有):
- session_key:sessionid;
- session_data:设置的session数据经过base64编码后的内容;
- expire_date:过期时间;
- session方法:通过request的session属性就行session读写。
- 以键值对的形式保存session:
request.session['key'] = value
- 根据键读取值:
request.session.get('key', 'default')
- 清除session,在存储中删除值部分:
request.session.clear()
- 清除session,在存储中删除整条session记录:
request.session.flush()
- 删除指定键值:
del request.session['key']
- 设置会话过期时间,如果不设置则两周后过期:
request.session.set_expiry(value)
- value是整数,则在value秒没有活动后过期;
- value是0则用户会话的Cookie将在浏览器关闭时过期;
- value是None则永不会过期;
- session示例
- 查询数据库发现有一条session记录(应该是之前测试什么添加的):
- 解析发现里面值为空:
- 测试del方法:
- 第一次调用:
del方法删除的是session中的键,所以使用不对。
- 测试session.flush()方法:
- 此时查看session值:
- 设置session,先调用set_session:
- 查看数据库:
可以看出数据库的expire_date和响应的cookie有效时间一致,默认2周。
- 解码查看session值:
- 调用set_session2设置:
- 再次查看数据库:
可以看出有效期和值都变了
- 解码查看值:
- 调用get_session方法:
session.get()方法也用错。
- 修改get视图:
- 重新调用:
- 调整del方法:
- 重新调用:
- 查询数据库:
- 解析数据:
可以看出每次更新session值,过期时间都要更新至默认两周后。
- 设置过期时间:
- 调用后:
- 查询数据库:
- 再次调用get:
- 再次调用set:
- 查询数据库:
- 通过cookie设置过期:
- 调用后查询数据库:
- 等待过期后调用get:
可以看出,通过session设置过期时间和通过cookie设置过期处理方式不同。
- cookie:通过cookie设置是修改了浏览器cookie的过期时间,数据库中session还在而且过期时间不变(可能成为死数据);
- session:通过session设置不仅修改数据库的session过期值,而且会把浏览器的cookie过期也同时修改。
- 测试clear,先调用set后查询数据库:
- 调用get:
- 调用clear后:
- 查询数据库:
- 解析:
- 使用redis存储session:
- 安装依赖包:
pip install django-redis-sessions==0.5.6
- settings.py增加如下配置:
- 调用set_session方法:
修改redis所在服务器redis配置文件,修改protected-mode为no:再次访问:再次修改配置文件,注释掉绑定本地:
- 查询数据库: