我会记住生命中不期而遇的温暖 记得大雨磅礴 没有带伞的日子
不要怕目录长,这可以更好更快的找到你想要的知识点!!!
奉上目录
- Request对象
1.1 HttpRequest对象
1.1.1 属性
1.1.2 方法
1.2 QueryDict 对象
1.3 GET 属性
1.4 POST 属性 - Response对象
2.1 HttpResponse 对象
2.1.1 属性
2.1.2 方法
2.1.3 Cookie
2.1.3.1 汉字 Cookie 编码问题
2.1.4 子类HttpResponseRedirect
2.1.5 子类 JsonResponse
2.1.6 简写函数
2.1.6.1 render
2.1.6.2 重定向 - 状态保持
3.1 启用session
3.2 使用session
3.3用户登录示例
3.4会话过期时间
3.5存储session
3.5使用Redis缓存session
—————————————————————————
1. Request对象
1.1 HttpRequest对象
服务器接收到 http 协议的请求后,会根据报文创建 HttpRequest 对象
视图函数的第一个参数是 HttpRequest 对象
在 django.http 模块中定义了 HttpRequest 对象的 API
—————————————————————————
1.1.1 属性
下面除非特别说明,属性都是只读的
path:一个字符串,表示请求的页面的完整路径,不包含域名.method:一个字符串,表示请求使用的 HTTP 方法,常用值包括: 'GET'、 'POST'
encoding:一个字符串,表示提交的数据的编码方式,如果为 None ,则表示使用浏览器的默认设置,一般为 utf-8,这个属性是可写的,可以通过修改它来修改访问表单数据使用的编码,接下来对属性的
任何访问将使用新的 encoding 值
GET:一个类似于字典的对象,包含 get 请求方式的所有参数
POST:一个类似于字典的对象,包含 post 请求方式的所有参数
FILES:一个类似于字典的对象,包含所有的上传文件
COOKIES:一个标准的 Python 字典,包含所有的 cookie,键和值都为字符串
session:一个既可读又可写的类似于字典的对象,表示当前的会话,只有当 Django 启
用会话的支持时才可用,详细内容请找目录:“状态保持“
—————————————————————————
1.1.2 方法
is_ajax():如果请求是通过 XMLHttpRequest 发起的,则返回 True
—————————————————————————
1.2 QueryDict 对象
定义在 django.http.QueryDict
request 对象的属性 GET、 POST 都是 QueryDict 类型的对象
与 python 字典不同, QueryDict 类型的对象用来处理同一个键带有多个值的情况
方法 get():根据键获取值
注意:
只能获取键的一个值
如果一个键同时拥有多个值,获取最后一个值
dict.get('键',default)
或简写为
dict['键']
方法 getlist():根据键获取值
将键的值以列表返回,可以获取一个键的多个值
dict.getlist('键',default)
—————————————————————————
1.3 GET 属性
QueryDict 类型的对象
包含 get 请求方式的所有参数
与 url 请求地址中的参数对应,位于?后面
参数的格式是键值对,如 key1=value1
多个参数之间,使用&连接,如 key1=value1&key2=value2
键是开发人员定下来的,值是可变的
示例如下
创建视图 getTest1 用于定义链接, getTest2 用于接收一键一值, getTest3 用于接收一键多值:
def getTest1(request):
return render(request,'booktest/getTest1.html')
def getTest2(request):
return render(request,'booktest/getTest2.html')
def getTest3(request):
return render(request,'booktest/getTest3.html')
项目 url 配置
urlpatterns = [
path('admin/', admin.site.urls),
url(r'^ booktest/', include('booktest.urls',namespace='booktest')),
]
应用 url 配置
url(r'^getTest1/$', views.getTest1),
url(r'^getTest2/$', views.getTest2),
url(r'^getTest3/$', views.getTest3),
创建 getTest1.html,定义链接
<html>
<head>
<title>Title</title>
</head>
<body>
链接 1:一个键传递一个值
<a href=" /booktest/getTest2/?a=1&b=2">gettest2</a><br>
链接 2:一个键传递多个值
<a href=" /booktest/getTest3/?a=1&a=2&b=3">gettest3</a>
</body>
</html>
完善视图 getTest2 的代码
def getTest2(request):
a=request.GET['a']
b=request.GET['b']
context={'a':a,'b':b}
return render(request,'booktest/getTest2.html',context)
创建 getTest2.html,显示接收结果
<html>
<head>
<title>Title</title>
</head>
<body>
a:{{ a }}<br>
b:{{ b }}
</body>
</html>
完善视图 getTest3 的代码
def getTest3(request):
a=request.GET.getlist('a')
b=request.GET['b']
context={'a':a,'b':b}
return render(request,'booktest/getTest3.html',context)
创建 getTest3.html,显示接收结果
<html>
<head>
<title>Title</title>
</head>
<body>
a:{% for item in a %}
{{ item }}
{% endfor %}
<br>
b:{{ b }}
</body>
</html>
—————————————————————————
1.4 POST 属性
POST 属性
QueryDict 类型的对象
包含 post 请求方式的所有参数
与 form 表单中的控件对应
问:表单中哪些控件会被提交?
答:控件要有 name 属性,则 name 属性的值为键, value 属性的值为键,构成键值对提交
对于 checkbox 控件, name 属性一样为一组,当控件被选中后会被提交,存在一键多值
的情况
键是开发人员定下来的,值是可变的
示例如下
定义视图 postTest1
def postTest1(request):
return render(request,'booktest/postTest1.html')
配置 url
url(r'^postTest1$',views.postTest1)
创建模板 postTest1.html
<html>
<head>
<title>Title</title>
</head>
<body>
<form method="post" action="/booktest/postTest2/">
<br />{% csrf_token %}<br />
姓名: <input type="text" name="uname"/><br>
密码: <input type="password" name="upwd"/><br>
性别: <input type="radio" name="ugender" value="1"/>男
<input type="radio" name="ugender" value="0"/>女<br>
爱好: <input type="checkbox" name="uhobby" value="胸口碎大石"/>胸口碎大石
<input type="checkbox" name="uhobby" value="跳楼"/>跳楼
<input type="checkbox" name="uhobby" value="喝酒"/>喝酒
<input type="checkbox" name="uhobby" value="爬山"/>爬山<br>
<input type="submit" value="提交"/>
</form>
</body>
</html>
创建视图 postTest2 接收请求的数据
def postTest2(request):
uname=request.POST['uname']
upwd=request.POST['upwd']
ugender=request.POST['ugender']
uhobby=request.POST.getlist('uhobby')
context={'uname':uname,'upwd':upwd,'ugender':ugender,'uhobby':uhobby}
return render(request,'booktest/postTest2.html',context)
配置 url
url(r'^postTest2$',views.postTest2)
创建模板 postTest2.html
<html>
<head>
<title>Title</title>
</head>
<body>
{{ uname }}<br>
{{ upwd }}<br>
{{ ugender }}<br>
{{ uhobby }}
</body>
</html>
注意:表单页面添加<br />{% csrf_token %}<br />
或者给 postTest2 方法添加修饰器@csrf_exempt
—————————————————————————
2. Response对象
2.1 HttpResponse 对象
在 django.http 模块中定义了 HttpResponse 对象的 API
HttpRequest 对象由 Django 自动创建, HttpResponse 对象由程序员创建
不调用模板,直接返回数据
#coding=utf-8
from django.http import HttpResponse
def index(request):
return HttpResponse('你好')
调用模板
from django.http import HttpResponse
from django.template import RequestContext, loader
def index(request):
# 获取图书表中所有的记录
booklist = BookInfo.objects.all()
# 加载 index.html 模版
template = loader.get_template('index.html')
# 字典,用于插入模版中的数据
context = {'booklist': booklist}
# 返回模版渲染的结果
return HttpResponse(template.render(context))
—————————————————————————
2.1.1 属性
content:表示返回的内容,字符串类型
charset:表示 response 采用的编码字符集,字符串类型
status_code: HTTP 响应状态码
content-type:指定输出的 MIME 类型
—————————————————————————
2.1.2 方法
init :使用页内容实例化 HttpResponse 对象
write(content):以文件的方式写
flush():以文件的方式输出缓存区
—————————————————————————
2.1.3 Cookie
基于 Internet 的各种服务系统应运而生,建立商业站点或者功能比较完善的个人站点,常常需要记录访问者的一些信息;目前公认的是,通过 Cookie 和 Session 技术来实现记录
访问者的一些基本信息。接下来记录一下 Cookie 的使用:
response. delete_cookie(key):删除指定的 key 的 Cookie,如果 key 不存在则什么也不发生
request.COOKIES.get("name")
response.set_cookie(key, value='', max_age=None, expires=None):设置 Cookie
key、 value 都是字符串类型
max_age 是一个整数,表示在指定秒数后过期
expires 是一个 datetime 或 timedelta 对象,会话将在这个指定的日期/时间过期,注意datetime 和 timedelta 值只有在使用 PickleSerializer 时才可序列化
max_age 与 expires 二选一
如果不指定过期时间,则两个星期后过期
from django.http import HttpResponse
from datetime import *
def cookieTest (request):
response = HttpResponse()
if 'h1' in request.COOKIES:
response.write('<h1>' + request.COOKIES['h1'] + '</h1>')
response.set_cookie('h1', 'hello', 120)
# response.set_cookie('h1', ''hello'', None, datetime(2016, 10, 31))
return response
—————————————————————————
2.1.3.1 汉字 Cookie 编码问题
当 cookie 值包含中文是, Django 无法执行 response.set_cookie,在服务器控制台报错:
AttributeError:'NoneType' object has no attribute 'split'
解决办法:使用 Json
import json
def cookieTest2(request):
response = HttpResponse("OK")
if 'h1' in request.COOKIES:
h1 = request.COOKIES['h1']
response.write('<h1>' + json.loads(h1) + '</h1>')
response.set_cookie("h1", json.dumps("你好"))
return response
—————————————————————————
2.1.4 子类HttpResponseRedirect
重定向,服务器端跳转
构造函数的第一个参数用来指定重定向的地址
在 views1.py 中
from django.http import HttpResponse,HttpResponseRedirect
def redirectTest(request):
#return HttpResponseRedirect(reverse('booktest:getTest1')) #使用反向解析
return HttpResponseRedirect('http://www.baidu.com')
在应用的 urls.py 中增加一个 url 对象
url(r'^redirectTest/$', views1.redirectTest, name='getTest1')
—————————————————————————
2.1.5 子类 JsonResponse
返回 json 数据,一般用于异步请求
帮助用户创建 JSON 编码的响应
参数 data 是字典对象
JsonResponse 的默认 Content-Type 为 application/json
from django.http import JsonResponse
def index2(requeset):
return JsonResponse({'list': 'abc'})
—————————————————————————
2.1.6 简写函数
2.1.6.1 render
render(request, template_name[, context])
结合一个给定的模板和一个给定的上下文字典,并返回一个渲染后的 HttpResponse 对象
request:该 request 用于生成 response
template_name:要使用的模板的完整名称
context:添加到模板上下文的一个字典,视图将在渲染模板之前调用它
from django.shortcuts import render
def getTest2(request):
a = request.GET['a']
b = request.GET['b']
context = {'a': a, 'b': b}
return render(request, 'booktest/getTest2.html', context)
—————————————————————————
2.1.6.2 重定向
redirect(to)
为传递进来的参数返回 HttpResponseRedirect
推荐使用反向解析
from django.shortcuts import redirect
from django.urls import reverse
def getTest (request):
return redirect(reverse('booktest:index1'))
应用的 urls.py 中增加一个 url 对象
url(r'^getTest/$', views.getTest),
得到对象或返回 404
get_object_or_404(klass, args, *kwargs)
通过模型管理器或查询集调用 get()方法,如果没找到对象,不引发模型的 DoesNotExist异常,而是引发 Http404 异常
klass:获取对象的模型类、 Manager 对象或 QuerySet 对象
**kwargs:查询的参数,格式应该可以被 get()和 filter()接受
如果找到多个对象将引发 MultipleObjectsReturned 异常
from django.shortcuts import *
def detail(request, id):
try:
book = get_object_or_404(BookInfo, pk=id)
except BookInfo.MultipleObjectsReturned:
book = None
return render(request, 'booktest/detail.html', {'book': book})
将 settings.py 中的 DEBUG 改为 False
将请求地址输入 2 和 100 查看效果
得到列表或返回 404
get_list_or_404(klass, args, *kwargs)
klass:获取列表的一个 Model、 Manager 或 QuerySet 实例
**kwargs:查寻的参数,格式应该可以被 get()和 filter()接受
from django.shortcuts import *
def index(request):
# list = get_list_or_404(BookInfo, pk__lt=1)
list = get_list_or_404(BookInfo, pk__lt=6)
return render(request, 'booktest/index.html', {'list': list})
将 settings.py 中的 DEBUG 改为 False
—————————————————————————
3.状态保持
http 协议是无状态的:每次请求都是一次新的请求,不会记得之前通信的状态
客户端与服务器端的一次通信,就是一次会话
实现状态保持的方式:在客户端或服务器端存储与会话有关的数据
存储方式包括 cookie、 session,会话一般指 session 对象
使用 cookie,所有数据存储在客户端,注意不要存储敏感信息
推荐使用 sesison 方式,所有数据存储在服务器端,在客户端 cookie 中存储 session_id
状态保持的目的是在一段时间内跟踪请求者的状态,可以实现跨页面访问当前请求者的数据
注意:不同的请求者之间不会共享这个数据,与请求者一一对应
—————————————————————————
3.1 启用session
使用 django-admin startproject 创建的项目默认启用
在 settings.py 文件中
项 INSTALLED_APPS 列表中添加:
'django.contrib.sessions',
项 MIDDLEWARE_CLASSES 列表中添加:
'django.contrib.sessions.middleware.SessionMiddleware',
禁用会话: 默认是开启的, 删除上面指定的两个值,禁用会话将节省一些性能消耗
—————————————————————————
3.2 使用session
启用会话后,每个 HttpRequest 对象将具有一个 session 属性,它是一个类字典对象
get(key, default=None):根据键获取会话的值
clear():清除所有会话
flush():删除当前的会话数据并删除会话的 Cookie
del request.session['member_id']:删除会话
—————————————————————————
3.3用户登录示例(这是一个较为完整的登录项目)
新建应用 usertest
在 setting.py 中添加应用
在 views.py 文件中创建视图
from django.shortcuts import render, redirect
from django.urls import reverse
def index(request):
uname = request.session.get('uname')
return render(request, 'usertest/index.html', {'uname': uname})
def login(request):
return render(request, 'usertest/login.html')
@csrf_exempt
def login_handle(request):
request.session['uname'] = request.POST['uname']
return redirect(reverse('usertest:index'))
def logout(request):
# request.session['uname'] = None
# del request.session['uname']
# request.session.clear()
request.session.flush()
return redirect(reverse('usertest:index'))
配置 url
主 url:
from django.conf.urls import include, url
urlpatterns = [
url(r'^user', include('usertest.urls',namespace='usertest')),
]
应用 url:
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'login/$', views.login, name='login'),
url(r'loginhandle/$', views.loginhandle, name='loginhandle'),
url(r'logout/$', views.logout, name='logout')
]
创建模板 index.html
<!DOCTYPE html>
<html>
<head>
<title>首页</title>
</head>
<body>
你好: {{uname}}
<hr/>
<a href="{%url 'main:login'%}">登录</a>
<hr/>
<a href="{%url 'main:logout'%}">退出</a>
</body>
</html>
创建模板 login.html
<!DOCTYPE html>
<html>
<head>
<title>登录</title>
</head>
<body>
<form method="post" action="/login_handle/">
<input type="text" name="uname"/>
<input type="submit" value="登录"/>
</form>
</body>
</html>
—————————————————————————
3.4会话过期时间
set_expiry(value):设置会话的超时时间
如果没有指定,则两个星期后过期
如果 value 是一个整数,会话将在 values 秒没有活动后过期
如果 value 是一个 timedelta 对象,会话将在当前时间加上这个指定的日期/时间过期
如果 value 为 0,那么用户会话的 Cookie 将在用户的浏览器关闭时过期
如果 value 为 None,那么会话永不过期
修改视图中 login_handle 函数,查看效果
def login_handle(request):
request.session['uname'] = request.POST['uname']
# request.session.set_expiry(10)
# request.session.set_expiry(timedelta(days=5))
# request.session.set_expiry(0)
# request.session.set_expiry(None)
return redirect(reverse('usertest:index'))
—————————————————————————
3.5存储session
需要在 setting.py 的 INSTALLED_APPS 设置中添加 django.contrib.sessions
存储会话的方式
可以使用 settings.py 的 CACHES 中指定 SESSION_ENGINE 项
基于数据库的会话
SESSION_ENGINE='django.contrib.sessions.backends.db'
django 默认的会话存储方式
运行 manage.py migrate
基于缓存的会话
SESSION_ENGINE='django.contrib.sessions.backends.cache'
只存在本地缓存中,如果丢失则不能找回,比数据库的方式读写更快
缓存和数据库同时使用
SESSION_ENGINE='django.contrib.sessions.backends.cached_db'
优先从本地缓存中获取,如果没有则从数据库中获
—————————————————————————
3.5使用Redis缓存session
会话还支持文件、纯 cookie、 Memcached、 Redis 等方式存储,下面演示使用 redis存储
安装包
pip install django-redis-sessions==0.5.6
修改 settings 中的配置,增加如下项
SESSION_ENGINE = 'redis_sessions.session'
SESSION_REDIS_HOST = 'localhost'
SESSION_REDIS_PORT = 6379
SESSION_REDIS_DB = 1
SESSION_REDIS_PASSWORD = '123'
SESSION_REDIS_PREFIX = 'session'
View 方法
def set_session(request):
""""保存 session 数据"""
request.session['username'] = 'Django'
request.session['verify_code'] = '123456
return HttpResponse('保存 session 数据成功')
def get_session(request):
"""获取 session 数据"""
username = request.session.get('username')
verify_code = request.session.get('verify_code')
text = 'username=%s, verify_code=%s' % (username, verify_code)
return HttpResponse(text)
url 配置
url(r'^set_session$', views.set_session), # 保存 session 数据
url(r'^get_session$', views.get_session), # 获取 session 数据
查看:
redis:1>keys *
"session:otomthrfjr32ms4gt75ovyeld3b4o1fj"
redis:1>
管理 redis 的命令
启动:sudo redis-server /etc/redis/redis.conf
停止:sudo redis-server stop
重启: sudo redis-server restart
redis-cli:使用客户端连接服务器
keys *:查看所有的键
get name:获取指定键的值
del name:删除指定名称的键
—————————————————————————
感谢语
感谢茫茫人海中,你点进了我的文章,看见我写的文章都是一种缘,点击进来就是分,有缘分的人,学习到知识之后点点关注吧!还有跟多的精彩文章在后面哦!!!
网友评论