Django/HttpRequest/HttpResponse--Cookie/Session

一、HttpRequest对象

利用HTTP协议传参的几种途径:

  • 提取URL的特定部分,如/weather/beijing/2018,可以在服务器端的路由中用正则表达式截取;
  • 查询字符串(query string),形如key1=value1&key2=value2;
  • 请求体中发送的数据,比如表单数据、json、xml;
  • 在http报文的头(header)中。

(1)URL路径参数

  • 如果想从URL中获取值,需要在正则表达式中使用分组
  • 获取值分为两种方式
    • 位置参数 ,参数的位置不能错
      在这里插入图片描述
      在这里插入图片描述
    • 关键字参数,参数的位置可以变,跟关键字保持一致即可(推荐使用)
  • 注意:两种参数的方式不要混合使用,在一个正则表达式中只能使用一种参数方式。
    在这里插入图片描述

(2)Django中的QueryDict对象

HttpRequest对象的属性GET、POST都是QueryDict类型的对象
与python字典不同,QueryDict对象用来处理同一个键带多个值的情况

  • 方法get() :根据键获取值,如果一个键同时拥有多个值将获取最后一个值,如果值不存在则返回None,可以设置默认值进行后续处理 方法:get(‘键’,默认值)
  • 方法getlist() :根据键获取值,值以列表返回,可以获取指定键的所有值,如果键不存在则返回空列表[],可以设置默认值进行后续处理 方法:gelistt(‘键’,默认值)

(3)查询字符串Query String

获取请求路径中的查询字符串参数(形如?k1=vi&k2=v2),可以通过request.GET属性获取,返回QueryDict对象。
重要:查询字符串不区分请求方式,即假使客户端进行POST方式的请求,依然可以通过request.GET获取请求中的查询字符串数据。

def detail(request,category_id,book_id):
    # ##############################GET查询字符串###############################
    # https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&rsv_idx=1&tn=baidu&wd=itcast&fenlei=256&rsv_pq=0xb16063170009388c&rsv_t=b9d90iqw%2FQspk4IHUhg9EQkuv5l65tu6XjGz0mUiL1DhxDYpfr40UaI%2B5zXO&rqlang=en&rsv_dl=ib&rsv_enter=1&rsv_sug3=6&rsv_sug1=4&rsv_sug7=100&rsv_sug2=0&rsv_btype=i&inputT=4372&rsv_sug4=4372
    '''
    问号后边的参数是get方式传递的参数,称为‘查询字符串’
    http://127.0.0.1:8000/2/100/?username=itcast&password=xxx
    '''
    # 想要获取参数 使用
    query_params = request.GET
    # print(query_params)
    # http://127.0.0.1:8000/2/100/?username=itcast&password=xxx 得到结果:<QueryDict: {'username': ['itcast'], 'password': ['xxx']}> 是一个字典  ,获取值
    # http://127.0.0.1:8000/2/100/?username=itcast&password=xxx&username=itheima得到结果:<QueryDict: {'username': ['itcast', 'itheima'], 'password': ['xxx']}> 当username有多个值时 get方式只能得到最后一个 
    # 想要获取一健一值,需要使用QueryDict的get方法
    username = query_params['username'] #该方式只能获取一个值  当有多个值时获取最后一个 itheima
    username1 = query_params.get('username')
    password = query_params.get('password')
    # 想要获取一健多值,需要使用QueryDict的getlist方法
    username3 = query_params.getlist('username') # ['itcast', 'itheima']

    print(username3)
    return HttpResponse('detail')

(4)POSTform表单数据

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

(5)POST方式传递/解析JSON数据

  • 非表单类型Non-Form Data,非表单类型的请求体数据,Django无法自动解析,可以通过request.body属性获取最原始的请求体数据,自己按照请求体格式(JSON/XML等)进行,request.bady返回bytes类型。
    在这里插入图片描述
# ##############################POST JSON数据###############################
    '''    
    {
        JSON是双引号
        "username": "itcast",
        "password": "123"
    }'''
    body = request.body # b'{\n    "username": "itcast",\n    "password": "123"\n}' 需要使用body.decode()转换成json格式
    # print(body)
    body_str = body.decode()
    '''
    得到:
    {
    "username": "itcast",
    "password": "123"
    }
    json形式的字符串,但是不是字典,不能通过键取值,需要转换成字典
    '''
    '''
    json 的取值方式:
    json.dumps  将字典转换为JSON形式的字符串
    json.loads 将JSON形式的字符串转换为字典
    '''
    data = json.loads(body_str) # 得到 {'username': 'itcast', 'password': '123'}
    # print(data )
    username = data['username']  # 得到 itcast
    print(username)
    # print(body_str)
    return HttpResponse('detail')

(6)请求头

# ##############################POST JSON数据###############################
    print(request.META) #打印系统中的原始的信息头
    context_type = request.META['CONTENT_TYPE']  # 得到某一个属性值
    print(context_type)
    return HttpResponse('detail')

使用postman在请求头中自定义一个属性值
在这里插入图片描述
得到自定义的属性值
在这里插入图片描述

(7)其他常用HttpRequest对象属性

  • method:一个字符串,表示请求使用的HTTP方法,常用值包括:GET POST;
  • user:请求的用户对象;
  • path:一个字符串,表示请求的页面的完整路径,不包含域名和参数部分;
  • encoding:一个字符串,表示提交的数据的编码格式
    • 如果为None则表示使用浏览器的默认设置,一般为utf-8
    • 这个属性是可写的,可以通过修改它来修改访问表单数据使用的编码,接下来对属性的任何访问将使用新的encoding值
  • FILES:一个类似于字典的对象,包含所有的上传文件

在这里插入图片描述

二、HttpResponse

(1)HttpResponse

# ##############################HttpResponse###############################
    data = {'name':'itcast'} # 只能返回  name
    # return HttpResponse(content=b"", status,*args, **kwargs))
    # content 传递字符串,不要传递对象/字典等数据
    # status  只能使用系统规定的 100 to 599
    # content_type 是一个MIME类型,语法形式是: 大类/小类 比如  text/html  text/css  text/javascript application/json  image/png  image/gif
    return HttpResponse(data,status=400 )

在这里插入图片描述

(2)JsonResponse

# ##############################JsonResponse###############################
    from django.http import  JsonResponse
    data = {'name': 'itcast'}

    return JsonResponse(data)

在这里插入图片描述

(3)redirect重定向

# ##############################跳转页面###############################
    # 跳转到首页,通过reverse名字找到路径
    path = reverse('book:indexname')
    # 跳转页面
    return redirect(path)
#     return redirect('https://www.baidu.com')

在这里插入图片描述

(4)状态保持

  • 浏览器请求服务器是无状态的
  • 无状态:指一次用户请求时,浏览器、服务器无法知道之前这个用户做过什么,每次请求都是一次新的请求。
  • 无状态的原因:浏览器与服务器是使用Socket套接字进行通讯的,服务器将请求结果返回给浏览器之后,会关闭当前的socket连接,而且服务器也会在处理页面完毕之后销毁页面对象。
  • 有时需要保持下来用户浏览的状态,比如用户是否登录过,浏览过哪些商品等
  • 实现状态保持主要有两种方式:
    • 在客户端存储信息使用Cookie
    • 在服务器端存储信息使用Session
1、Cookie

保存在客户端的数据叫cookie
cookie保存在客户端
cookie是基于域名(IP)的
0.概念
1.流程(原理)
第一次请求服务器的过程:
① 浏览器第一次请求服务器的时候不会携带任何cookie信息
② 服务器接收到请求之后,发现请求中没有任何cookie信息
③ 服务器设置一个cookie信息,在响应中返回
④ 浏览器接收到响应后,发现响应中有cookie信息,浏览器会将cookie信息保存起来
第二次请求服务器及其之后的过程:
⑤ 浏览器第二次及其之后的请求都会携带cookie信息
⑥ 服务器接收到请求之后,会发现请求中携带的cookie信息,这样的话就认识是谁的请求了。
2.看效果
3.从http协议角度深入掌握cookie的流程(原理)
第一次请求:
①第一次请求服务器时,不会携带任何的cookie信息,请求头中没有任何的cookie信息
②服务器会为响应设置cookie信息,响应头中有set_cookie信息
第二次及其之后的请求:
③第二次及其之后的请求都会在请求头中携带cookie信息
④(可选)在当前的代码中,没有再设置cookie,所以响应头中没有set_cookie信息

设置Cookie

通过HttpResponse对象中的set_cookie方法来设置cookie

HttpResponse.set_cookie(cookie名,value=cookie值,max_age=cookie有效期)
  • max_age单位为秒,默认为None,如果是临时cookie,可将max_age设置为None
读取cookie

可以通过HttpResponse对象的COOKIES属性来读取本次请求携带的cookie值,request.COOKIES为字典类型

def get_cookie(request):
	# 1.服务器可以接收(查看)cookie信息
    cookies = request.COOKIES
    # cookies是一个字典
    username = cookies.get('username')
    return HttpResponse('get_cookie')
删除cookie
    # 删除cookie的2种方式delete_cookie或者max_age=0
    response.delete_cookie(key)
    response.set_cookie(key,value,max_age=0)
# ##############################Cookie###############################

def set_cookie(request):
    '''
    第一次请求服务器的过程:
    ① 浏览器第一次请求服务器的时候不会携带任何cookie信息
    ② 服务器接收到请求之后,发现请求中没有任何cookie信息
    ③ 服务器设置一个cookie信息,在响应中返回
    ④ 浏览器接收到响应后,发现响应中有cookie信息,浏览器会将cookie信息保存起来
    '''
    # 先判断有没有cookie信息,(假设第一次请求,没有cookie信息)
    # 判断是否存在cookie信息
    # request.COOKIES
    # 获取用户名
    username = request.GET.get('username')
    # 因为假设没有cookie信息,服务器设置cookie信息
    response = HttpResponse('set_cookie111')
    # key value
    # max_age:设置cookie失效时间  单位是秒 时间是从服务器接收到这个请求时间+秒数 计算之后的时间  3600秒:一个小时
    response.set_cookie('username',username,max_age=3600)
    
    # 删除cookie的2种方式delete_cookie或者max_age=0
    # response.delete_cookie(key)
    # response.set_cookie(key,value,max_age=0)
    #返回响应
    return response

def get_cookie(request):
    '''
	第二次请求服务器及其之后的过程:
	⑤ 浏览器第二次及其之后的请求都会携带cookie信息
	⑥ 服务器接收到请求之后,会发现请求中携带的cookie信息,这样的话就认识是谁的请求了。
    '''
    # 1.服务器可以接收(查看)cookie信息
    cookies = request.COOKIES
    # cookies是一个字典
    username = cookies.get('username')
    # 2.得到用户信息,就可以继续其他的业务逻辑了
    return HttpResponse('get_cookie')

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2、Session

保存在服务器的数据叫session
在这里插入图片描述

① 启用Session

Django项目默认启用session。可以在settings.py文件中查看,如需禁用session,将上图中的session中间件注释掉即可
在这里插入图片描述

② 存储方式

在settings.py文件中,可以设置session数据的存储方式,可以保存在数据库、本地缓存等。

a. 数据库

存储在数据库中,如下设置可以写,也可以不写,这是默认存储方式

SESSION_ENGING = 'django.contrib.sessions.backends.db'

如果存储在数据库中,需要在INSTALLED_APPS中安装Session应用
在这里插入图片描述
数据库中的表如图:数据包括键、值、过期时间
在这里插入图片描述

b . 本地缓存

存储在本机内存中,如果丢失则不能找回,比数据库的方式读写更快

SESSION_ENGING = 'django.contrib.sessions.backends.cache'
c. 混合存储

优先从本地内存中存取,如果没有则从数据库中存取

SESSION_ENGING = 'django.contrib.sessions.backends.cached_db'
d. Redis

在redis中保存session,需要引入第三方扩展,可以使用django-redis来解决

  • 安装扩展
pip install django-redis
  • 配置
    在setting.py文件中做如下设置
CACHES = {
    'default': {
        'BACKEND': 'django_redis.cache.RedisCache',
        'LOCATION': 'redis://127.0.0.1:6379/1',
        'OPTIONS': {
            'CLIENT_CLASS':'django_redis.client.DefaultClient',
        }
    }
}
SESSION_ENGINE = 'django.contrib.session.backiends.cache'
SESSION_CACHE_ALIAS = 'default'

注意:如果redis的ip地址不是本地回环127.0.0.1,而是其他地址,访问Django时,可能出现Redis连接错误
解决办法:修改redis的配置文件,添加特定的IP地址

sudo vim /etc/redis/redis.conf

在这里插入图片描述
重新启动redis服务

sudo service redis-server restart
③ Session操作

通过HttpRequest对象的session属性进行会话的读写操作

  • 以键值对的格式写session
request.session['键'] =
  • 根据键读取值
request.session.get('键',默认值)
  • 清除所有的session,在存储中删除值部分
request.session.clear()
  • 清除session数据,在存储中删除session的整条数据
request.session.flush()
  • 删除session中的指定键和值,在存储中只删除某个键及对应的值
del request.session['键']
  • 设置session的有效期
  • 如果value是一个整数,session将在value秒没有活动后过期
  • 如果value为0,那么用户session的Cookie将在用户的浏览器关闭时过期
  • 如果value为None,那么session有效期将采用系统默认值,默认为两周,可以通过在settings.py中设置SESSION_COOKIE_AGE来设置全局默认值
request.session.set_expiry(value)
'''
0.概念
1.流程
	第一次请求:
		① 第一次请求服务器时,可以携带一些信息(用户名/密码),此时cookie中没有任何信息。
		② 服务器接收到请求后,进行用户名和密码的验证,验证没有问题可以设置session信息。
		③ 在设置session信息的同时(session信息保存在服务器端),服务器会在响应头中设置一个sessionid
		④ 客户端(浏览器)在接收到响应后,会将cookie信息保存起来(保存的是sessionid的信息)
	第二次及其之后的请求:
		⑤ 第二次及其之后的请求都会携带sessionid信息
		⑥ 当服务器接收到这个请求之后,会获取到sessionid的信息,然后进行验证,验证成功,则可以获取session信息
		
2.效果
3.从原理(http)角度

'''
def set_session(request):
    '''
    以get方式传递用户名和密码
    127.0.0.1:8000/set_session/?username=itcast&password=123
    '''
    # 1.首次发送请求 cookie中没有任何信息
    # print(request.COOKIES)
    # 2.对用户名和密码进行验证,假设用户名和密码正确 则设置一个字典形式的session
    user_id = 6666
    # 3.设置session信息
    request.session['user_id']=user_id
    # 返回响应
    return HttpResponse('set_session')

def get_session(request):
    # 1.第二次及其之后的请求 都会携带session id信息
    print(request.COOKIES)
    # 2.服务器获取到sessionid信息进行验证,验证成功可以获取session信息
    # request.session 字典
    user_id = request.session['user_id']
    user_id = request.session.get('user_id')

    # 3.
    return HttpResponse('session')

在这里插入图片描述

在这里插入图片描述

④ Session保存到Redis
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值