1.请求行中的路径即URL中的特定部分
2.查询字符串
3.请求体
4.请求头
2.1位置参数——
url(r'^weather/([a-z]+)/(\d{4})/$', views.weather),
# URL去传递参数——通过正则表达式实现传参
# 获取URL路径中的数据,使用小括号方式 例如:/([a-z]+)/(\d+)
# 使用小括号传递的参数是位置参数,需要和视图函数里面的顺序相对应
def weather(request, city, year):
# 读取正则中的组提取的参数
print('city=%s' % city)
print('year=%s' % year)
return HttpResponse('OK')
2.2关键字参数——
url(r'^weather/(?P<city>[a-z]+)/(?P<year>\d{4})/$', views.weather),
# 使用正则表达式中的正则组——即给正则组起别名,传递和提取参数时 就变为关键字传参
# 需要注意 给正则组起别名时 别名要和视图函数里面传递的参数名一致
def weather(request, year, city):
# 读取正则中关键字提取的参数
print('city=%s' % city)
print('year=%s' % year)
return HttpResponse('OK')
3.1需求:提取问号后面的查询字符串
例如:/weather3/beijing/?a=10&b=20&a=30
3.2 通过request.GET属性获取请求路径中的查询字符串参数,返回QueryDict对象
# /qs/?a=1&b=2&a=3
# get():根据键获取值
def qs(request):
a = request.GET.get('a')
b = request.GET.get('b')
alist = request.GET.getlist('a')
print(a) # 3
print(b) # 2
print(alist) # ['1', '3']
return HttpResponse('OK')
# 目标:演示获取url中查询参数/查询字符数据
# weather/beijing/2018/?a=10&b=10&a=30
# GET: /get_query_par/
# request下的两种属性:GET 和 POST 说明:GET和POST是属性,返回的是QueryDict对象 get和post为浏览器的请求方式
def request_response(request):
# get获取的是一键一值,但是获取的是最后一个数据
# print(request.GET.get('a')) # a = 30
# # getlist获取的是一键多值
# print(request.GET.getlist('a')) # a = 10
# print(request.GET.get('b'))
# # return http.HttpResponse('request_response')
# return http.HttpResponse('ok')
# 这里既可以用POST模式也可以用GET模式 但是获取元素都是用get或getlist
print(request.POST.get('a'))
print(request.POST.getlist('a'))
print(request.POST.get('b'))
return http.HttpResponse('request_response')
3.3.get()方式读取一个键一个值,获取最后一个值
getlist()方式读取一个键多个值,返回列表
# /qs/?a=1&b=2&a=3
# get():根据键获取值
def qs(request):
a = request.GET.get('a')
b = request.GET.get('b')
alist = request.GET.getlist('a')
print(a) # 3
print(b) # 2
print(alist) # ['1', '3']
return HttpResponse('OK')
# 目标:演示获取url中查询参数/查询字符数据
# weather/beijing/2018/?a=10&b=10&a=30
# GET: /get_query_par/
# request下的两种属性:GET 和 POST 说明:GET和POST是属性,返回的是QueryDict对象 get和post为浏览器的请求方式
def request_response(request):
# get获取的是一键一值,但是获取的是最后一个数据
# print(request.GET.get('a')) # a = 30
# # getlist获取的是一键多值
# print(request.GET.getlist('a')) # a = 10
# print(request.GET.get('b'))
# # return http.HttpResponse('request_response')
# return http.HttpResponse('ok')
# 这里既可以用POST模式也可以用GET模式 但是获取元素都是用get或getlist
print(request.POST.get('a'))
print(request.POST.getlist('a'))
print(request.POST.get('b'))
return http.HttpResponse('request_response')
1.请求体数据格式不固定,表单,json字符串,XML
2.发送请求体的请求方式:POST,PUT,PATCH,DELETE
1.通过request.POST属性获取,返回Query.Dict类型的对象
# 目标: 演示获取请求体表单数据 request.POST
# POST /get_form_data/
# 在提取form表单数据时,需要把限制解除 在settings.py文件中MIDDLEWARE关闭CSRF防护
# 得到表单数据——用到调试工具Postman
# 在发送数据栏 如果应用路由后面有/,需要在发送数据的时候也要带上/
# 发送表单数据,选择Body下的form-data
# def post_form_data(request):
# print(request.POST)
# query_dict = request.POST
# # query_dict.dict() # 如果需要删除表单数据,query_dict.dict() 将QueryDict类型转换成普通的字典格式——dict
# return http.HttpResponse('post_form_data')
# 获取请求体中的表单数据
def get_form_data(request):
a = request.POST.get('name')
# a.dict('name')
print(a)
b=request.POST.get('age')
print(b)
return http.HttpResponse('get_form_data')
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BjHPlY2G-1587286520055)(C:\Users\86155\AppData\Roaming\Typora\typora-user-images\1577072440806.png)]
1.通过request.body属性获取原始请求体数据
2.request.body返回bytes类型
# 目标: 演示获取请求体中的非表单数据(json,xml) request.body
# POST: /get_json_data/
# 获取非表单数据的第一步: request.body获取bytes类型的数据
# 第二步:将bytes类型数据转换成str类型 用decode()
# 第三步:把str类型的数据转换成json数据(字典类型)——json.load()
# def post_no_form_data(request):
# data_bytes = request.body # request.body获取的是bytes类型的数据
# json_str = data_bytes.decode() # 将bytes类型转换成str类型
# dict1 = json.loads(json_str) # 把str类型的数据转换成json数据(字典类型) "{'name': 'zs'}" ---> {'name': 'zs'}
# print(dict1)
# # json.loads((request.body.decode()))
# return http.HttpResponse('post_no_form_data')
# 获取请求体中的非表单数据(json,html)——request.body
def get_noform_data(request):
str = request.body.decode()
dict = json.loads(str)
print(dict['name'])
print(dict['age'])
return http.HttpResponse('get_noform_data')
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BnjGwIkU-1587286520058)(C:\Users\86155\AppData\Roaming\Typora\typora-user-images\1577073371650.png)]
1.通过request.META属性获取请求头headers中的数据
2.request.META为字典类型
# 常见的请求头如下:
CONTENT_LENGTH – The length of the request body (as a string).
CONTENT_TYPE – The MIME type of the request body.
HTTP_ACCEPT – Acceptable content types for the response.
HTTP_ACCEPT_ENCODING – Acceptable encodings for the response.
HTTP_ACCEPT_LANGUAGE – Acceptable languages for the response.
HTTP_HOST – The HTTP Host header sent by the client.
HTTP_REFERER – The referring page, if any.
HTTP_USER_AGENT – The client’s user-agent string.
QUERY_STRING – The query string, as a single (unparsed) string.
REMOTE_ADDR – The IP address of the client.
REMOTE_HOST – The hostname of the client.
REMOTE_USER – The user authenticated by the Web server, if any.
REQUEST_METHOD – A string such as "GET" or "POST".
SERVER_NAME – The hostname of the server.
SERVER_PORT – The port of the server (as a string).
5.1语法结构——
def get_headers(request):
print(request.META['CONTENT_TYPE'])
return HttpResponse('OK')
method:一个字符串,表示请求使用的HTTP方法,常用值包括:'GET'、'POST'。
user:请求的用户对象。
path:一个字符串,表示请求的页面的完整路径,不包含域名和参数部分。
encoding:一个字符串,表示提交的数据的编码方式。
如果为None则表示使用浏览器的默认设置,一般为utf-8。
这个属性是可写的,可以通过修改它来修改访问表单数据使用的编码,接下来对属性的任何访问将使用新的encoding值。
FILES:一个类似于字典的对象,包含所有的上传文件
6.1语法结构
print(request.method, request.path)
1.1可以使用django.http.HttpResponse来构造响应对象
HttpResponse(content=响应体, content_type=响应体数据类型, status=状态码)
# 注意:响应体参数必须传
return HttpResponse('OK',content_type='text/html',status=200)
1.2 也可以通过HttpResponse对象属性来设置响应体和状态码
# 创建相应对象
response = HttpResponse('OK',content_type='text/html',status=200)
# 自定义响应头:键值对形式 键:Itcast 值:Python
response['Itcast'] = 'Python'
return response
from django.http import HttpResponse
def demo_view(request):
return HttpResponse('itcast python', status=400)
或者
response = HttpResponse('itcast python',status=400)
response.status_code = 400
response['Itcast'] = 'Python'
return response
# 演示响应对象基本操作
# GET /httpresponse_data/
# def httpresponse_data(request):
# # return http.HttpResponse(content='响应体',content_type='响应体类型',status='状态码')
# response = http.HttpResponse(content='httpresponse_data',content_type='text/html',status=200) # 200必须为int类型 不能是字符串
#
# print(response.content) # 得到的数据是响应体 但是把响应体转换成为bytes类型
# print(response.status_code) # 得到的状态码
#
# # 自定义响应头
# response['itcast'] = 'heima'
# return response
1.使用JsonResponse来构造响应对象,返回json数据
# GET /response_json/ (表示⽤用户向我们索取json)
def response_json(request):
"""响应json数据"""
# 准备字典:json字符串的key,需要双引号
json_dict = {"name":"zxj", "age":2.5}
# 默认会设置状态码
# 默认会将数据类型设置为 Content-Type: application/json
# 默认会将json字典转json字符串串,再将json字符串串转⼆二进制响应给⽤用户
return JsonResponse(json_dict)
# 演示响应json数据
# 如果响应的json数据 一般选用JsonResponse响应
# 1.将数据转换成json字符串
# 2.设置响应体类型为application/json
# def jsonresponse_data(request):
# # json响应的数据一般默认为字典类型,如果非要响应列表,需要把json里面的safe改为False模式
# data = ['A']
# data1 = {
# "name":"lisi",
# "age":18
# }
# return JsonResponse(data1,safe=False)
# 2.JsonResponse来构造响应对象 返回json数据
# json数据一般默认是字典类型
# 如果要响应列表类型 需要在后面加safe=False
def json_response(request):
dict1={
'name':'lisi',
'age':18
}
list1=['A','B','C']
return JsonResponse(data=list1,safe=False)
# GET /response_redirect/
def response_redirect(request):
"""重定向"""
# 需求:重定向到users应⽤用的index视图
# 使⽤用最原始的⽅方式
# return redirect('/users/index/')
# 使⽤用反向解析实现重定向
return redirect(reverse('users:index'))
# 演示重定向
# 第一步 需要导包——redirect
# def redirect_data(request):
# 其实内部的运行是判断当前用户是否登录,如果登录就响应用户中心界面
# 如果没有响应登录,就重定向到lpl
# 显示的结果就是lpl函数下的内容:釜底抽薪
# 在写重定向的路由时,lpl前面的/一定要写上 如果不写 会变成redirect_data/lpl/
# 1.redirect(函数名)
# return redirect('/lpl/') # 首先是人为的去发送请求redirect_data 因为是redirect重定向 浏览器会自动发送请求/lpl/
# 2.redirect(路由别名)
#return redirect('abc')
# 3.redirect('命名空间:路由别名')
# 如果给路由起命名空间 那么上面1,2就不会执行了
# return redirect('users:abc')
# 3.重定向
def drict(request):
return redirect('/json_response/')
# return http.HttpResponse('hello direct')
url(r'^weather/([a-z]+)/(\d{4})/$', views.weather),
def weather(request, city, year):
print('city=%s' % city)
print('year=%s' % year)
return HttpResponse('OK')
url(r'^weather/(?P<city>[a-z]+)/(?P<year>\d{4})/$', views.weather),
def weather(request, year, city):
print('city=%s' % city)
print('year=%s' % year)
return HttpResponse('OK')
QueryDict介绍(支持一个键带多个值)
提取URL查询参数
请求路径:?k1=v1&k2=v2&k1=v3
获取:
request.GET.get('k1', "")
request.GET.get('k2', "")
request.GET.getlist('k1', [])
注意:查询字符串不区分请求方式,即假使客户端进行POST方式的请求,依然可以通过request.GET获取请求中的查询字符串数据。
# 演示重定向
# redirect既可以重定向,又可以反向解析
# 第一步 需要导包——redirect
def redirect_data(request):
# 其实内部的运行是判断当前用户是否登录,如果登录就响应用户中心界面
# 如果没有响应登录,就重定向到lpl
# 显示的结果就是lpl函数下的内容:釜底抽薪
# 在写重定向的路由时,lpl前面的/一定要写上 如果不写 会变成redirect_data/lpl/
# 1.redirect(函数名)
# return redirect('/lpl/') # 首先是人为的去发送请求redirect_data 因为是redirect重定向 浏览器会自动发送请求/lpl/
# 2.redirect(路由别名)
return redirect('abc')
# 3.redirect('命名空间:路由别名')
# 如果给路由起命名空间 那么上面1,2就不会执行了
# return redirect('users:abc')
设置Cookie
response.set_cookie(cookie名, value=cookie值, max_age=cookie有效期)
注意:max_age(秒),默认None(当前会话结束)
读取Cookie
扩展:删除cookie
response.delete_cookie(cookie名)
def cookie_data(request):
response =http.HttpResponse('cookie_data')
# HttpResponse.set_cookie(cookie名, value=cookie值, max_age=cookie有效期)
# cookie存储的是key-value
# 如果max_age=0 则表示删除cookie 如果为None,表示会话结束,清除cookie
data = response.set_cookie(key='name',value='ssj',max_age=None)
data1 = request.COOKIES.get('name') # 得到对应的cookie值
print(data1)
return response
session的存和取都是通过请求对象而不是响应对象的原因:
# 1.session存储在服务端,响应是给浏览器传数据
# 2.session依赖cookie 而cookie是存储在请求对象中,
服务器
通过配置将内容存储到redis
数据库`。Cookie和Session的对比
Session的特点
安装扩展
pip install django-redis
settings配置文件
# 指定session存储方案——存储在cache中,这里会出现不能共享问题,因此修改为RedisCache
SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
SESSION_CACHE_ALIAS = "default" # 表示连接哪个redis数据库
# 指定Django缓存配置
CACHES = {
"default": {
# 这里需要安装一个django_redis的模块
"BACKEND": "django_redis.cache.RedisCache", # 缓存后端
# 这里是连接redis的IP地址 端口号 以及是第几个数据库(redis有16个数据库,因此可以写16个)
"LOCATION": "redis://192.168.103.210:6379/1",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
}
}
}
注意:如果提示链接失败
sudo vim /etc/redis/redis.conf
修改 -》 bind 127.0.0.1 自己的ip
sudo service redis-server restart
or
sudo redis-server /etc/redis/redis.conf
设置session:
request.session["key"] = "value"
获取session:
request.session.get("key", "")
删除session:
# 方法1 根据key清除value
del request.session["like"]
# 方法2 清除所有数据——清除所有键值对
request.session.clear()
# 1.session存在mysql数据库中,读写速度慢
# 2.session存在cache服务器内存条中,读写速度快 但是多个服务器之间没法共享 因此
# 3.session存在redis缓存中
拓展:
# 设置过期时长,默认是:2个星期过期
# 参数:过期的秒数
request.session.set_expiry(3600)
# 删除整条记录——删除整个session数据
request.session.flush()
# Http协议无状态
COOKIE和SESSION区别:
1. 相同点: 都可以用来做状态保持,会话(一次响应,一次请求)状态保持, 都可以缓存数据
2. 不同点:
COOKIE 它缓存的数据在客户端(浏览器), 存储长度有限最大4kb, 在浏览器上同一个域名最多只能存20个cookie, 直接是明文可以见,数据不安全
SESSION 它缓存在服务器, 存储长度没有限制, 数据更加安全
设置/修改cookie response.set_cookie(key, value, max_age=过期时间) 过期时间必须是int类型 设置cookie时把cookie包装在响应头 Set-cookie
获取cookie request.COOKIES.get('key') 请求头 Cookie
"""
# # 演示session缓存
# def session_data(requset):
# # session缓存 是存储在服务器的内存条cache中,但是会出现共享问题,需要把数据存储在redis中
# # 第一步:安装django_redis模块
# # 第二步:设置存储方案——SESSION_ENGINE = 'django.contrib.sessions.backends.cache'
# # 第三步:指定缓存配置——主要是两个地方
# # BACKEND": "django_redis.cache.RedisCache", # 缓存后端
# # "LOCATION": "redis://127.0.0.1:6379/1",
# # 第四步:指定缓存哪个数据库 这里是数据库1
# # key存在为修改,不存在为新建
# # session首先把{'name':'zhangsan'} 转换成字符串类型存储在redis中,然后在进行字符串的拼接,构成sessionid 作为redis的key值
# # requset.session['name']='zhangsan' # 当新建session时,会生成一个sessionid值,把值存储到cookie中
# # 获取session
# print(requset.session.get('name')) # 这里得到的数据类型为字符串
# return http.HttpResponse('session_data')
# session依赖cookie——主要是依赖cookie的sessionid 当删除浏览器里面的cookie时,再次调用就会报错
# session的过期时间不设置或默认为None 时间默认是两周
# session过期时间如果为0 表示会话结束就删除
1.依赖cookie;
# session依赖cookie——主要是依赖cookie的sessionid 当删除浏览器里面的cookie时,再次调用就会报错
# session的过期时间不设置或默认为None 时间默认是两周
# session过期时间如果为0 表示会话结束就删除
###### session弊端:
1.依赖cookie;
2.数据是存储在后端(会占用后端缓存)
3.集成服务器群会出现共享资源的问题