拓展知识 request---->请求信息
属性:
request.path # 获取访问文件路径
request.method属性 #获取请求中使用的HTTP方式(POST/GET)
request.body #含所有请求体信息 是bytes类型
request.GET #GET请求的数据(类字典对象) 请求头中的url中?后面拿值
request.POST # POST请求的数据(类字典对象) 请求体里拿值
request.COOKIES #包含所有cookies的标准Python字典对象;keys和values都是字符串。
request.FILES: 包含所有上传文件的类字典对象;FILES中的每一个Key都是<input type="file"
name="" />标签中
name属性的值,FILES中的每一个value同时也是一个标准的python字典对象,包
含下面三个Keys:
filename: 上传文件名,用字符串表示
content_type: 上传文件的Content Type
content: 上传文件的原始内容
请求url:http://127.0.0.1:8000/index.html/23?a=1
request.path : 请求路径 8000 以后的没有get请求
request.path结果为:/index.html/23
request.get_full_path() 8000 以后的包含get请求
request.get_full_path()结果为:/index.html/23?a=1
cookie 的理论
rep.set_cookie("k1", "v1", max_age=10) # 这里是设置cookie
rep.cookie.get('k1',None) # 这里是获取cookie
* default:默认值
* salt:加盐
* max_age:后台控制过期时间
- expires=None, 超时时间(IE requires expires, so set it if hasn't been already.)
- path='/', Cookie生效的路径,/ 表示根路径,特殊的:根路径的cookie可以被任何url的页面访问
- domain=None, Cookie生效的域名
- secure=False, https传输
- httponly=False 只能http协议传输,无法被JavaScript获取(不是绝对,底层抓包可以获取到也可以被覆盖)
from django.shortcuts import render,redirect # Create your views here. # # def login(request): # if request.method == 'POST': # user1 = request.POST.get('user') # pwd1 = request.POST.get('pwd') # if user1 == 'alex' and pwd1 == '123': # rep = redirect('/index1/') # # # 第一个uesrname设置cookie是个k 设置一个cookie 没有实际意义 # # rep.set_cookie('user2', user1) # # # 第二个加盐设置/ 后边就上一个salt 位置不能改变 # # rep.set_signed_cookie('pwd2',pwd1,salt='s8') # # # 第三种个加盐设置 并且限制拿到cookie 的时间 后边单位是秒 进入index.html 的时间是10s # # # 超过10秒后会自动退出到login中 # rep.set_signed_cookie('pwd2',pwd1,salt='s8',max_age=120) # # # 第四种 path='/index1/'只能是index1 才能有cooki,不设置这个 都会有在10秒之内 # # # rep.set_signed_cookie('pwd2', pwd1, salt='s8', max_age=10,path='/index1/') # return rep # return render(request, 'longin.html') # # @wrapper # def index1(request): # # # 第一种拿到上面设置的cookie 的名字 # # # username = request.COOKIES.get('user2') # # # 第二种拿到上面设置的cookie 的名字 # # username = request.get_signed_cookie('pwd2', salt='s8') # # # 要是为空自动返回login # # username = request.get_signed_cookie('pwd2', None, salt='s8') # # if not username: # # return redirect('/login/')', {'uesrw': username} # return render(request, 'index1.html') # 在页面上能显示的密码是123 但是在源代码中的回应体中显示加盐的效果就能显示 # # # def index2(request): # # 第一种拿到上面设置的cookie 的名字 # # username = request.COOKIES.get('user2') # # 第二种拿到上面设置的cookie 的名字 # # username = request.get_signed_cookie('pwd2',salt='s8') # # 要是为空自动返回login # username = request.get_signed_cookie('pwd2', None, salt='s8') # if not username: # return redirect('/login/') # return render(request, 'index2.html', {'uesrw': username}) # 运用装饰器函数的方法 减少代码的重复 # 装饰器函数的应用 return func() 要装饰的函数(关键点) # def login(request): # if request.method == 'POST': # user1 = request.POST.get('user') # pwd1 = request.POST.get('pwd') # if user1 == 'alex' and pwd1 == '123': # rep = redirect('/home/') # rep.set_signed_cookie('pwd2', pwd1, salt='s8', max_age=10) #加上path 就只能index访问 # return rep # return render(request, 'longin.html') # def wrapper(func): # def inner(request,*args,**kwargs): # # 装饰器之前要做的 # user = request.get_signed_cookie('pwd2', None, salt='s8') # if not user: # # return redirect('/login/') # else: # return func(request, *args, **kwargs) # return inner # @wrapper # def home(request): # user = request.get_signed_cookie('pwd2', salt='s8') # return render(request,'home.html',{'username':user}) # ----------------------------------------------------------------------- # request.path : 请求路径 8000 以后的没有get请求 # request.path结果为:/index.html/23 # # request.get_full_path() 8000 以后的包含get请求 # request.get_full_path()结果为:/index.html/23?a=1 def login(request): if request.method == 'POST': user1 = request.POST.get('user') pwd1 = request.POST.get('pwd') # /home/可以不用写 意思就是只要/?next= xxx 就会还是跳转登录页面 和login 一个效果 if user1 == 'alex' and pwd1 == '123': ret = request.GET.get('next', '/home/') # 直接登录home 也可以在别的页面next=xxx 登录 # 此时已经在login 中http://127.0.0.1:8000/login/?next=/home/ 就是后边就是加上next= xxx 也会跳转到登录页面 # rep = redirect('/home/') rep = redirect(ret) #网址栏http://127.0.0.1:8000/login/?next=/xxx 就返回这个页面 rep.set_signed_cookie('pwd2', pwd1, salt='s8') #加上path 就只能index访问 return rep return render(request, 'longin.html') def wrapper(func): def inner(request, *args, **kwargs): # 装饰器之前要做的 user = request.get_signed_cookie('pwd2', None, salt='s8') if not user: # 如果没得到要加盐的coolkie None 就返回登录页面 next_url = request.get_full_path() # 这个和get_path 区别就是获取800后边的多少 # get_full_path() 后边都可以获取 包括get请求 # 而 get_path() z只能获取800后边的一个url 不能获取get return redirect('/login/?next={}'.format(next_url)) #还跳转登录页面 else: #如果得到了要加盐的cookie 装饰以下的函数 home index1(登录的时候next=index1 的时候 登录后还会返回index的页面) return func(request, *args, **kwargs) return inner @wrapper def home(request): user = request.get_signed_cookie('pwd2', salt='s8') return render(request, 'home.html', {'username': user}) @wrapper ##你现在没有登录 def index1(request): return render(request, 'index1.html') def logout(request): ret = redirect('/login/') ret.delete_cookie('pwd2') return ret # ------------------------------------------------------------------------------------------------ # def cookie(fuc): # def inner(request, *args, **kwargs): # # 装饰的函数fuc 就是func1 # username = request.get_signed_cookie('pwd2', None, salt='s8') # if not username: # return redirect('/login/') # return fuc(request,*args, **kwargs) # return inner # @cookie # # func=cookie(func1) # # def index1(request): # username = request.get_signed_cookie('pwd2', None, salt='s8') # return render(request, 'index1.html', {'uesrw': username}) # @cookie # def index2(request): # username = request.get_signed_cookie('pwd2', None, salt='s8') # return render(request, 'index2.html', {'uesrw': username}) #
览器里面是有专门的设置选项,可以选择不保存cookie,但是我们设置了不保存cookie之后,登录一些页面的时候就无法登录成功,会有系统提示cookie没有开启,需要开启之后才能登录上
我们的cookie本质是在url上面添加的键对值,它的主要用途就是做登录校验用,我们的市面上主要的登录校验有两种方式:
1.加盐的cookie
数据都是保存在客户的浏览器上,服务端是没有什么压力的,
2.session
django中默认支持session,其内部提供了5种类型的session供开发者使用:
数据库(默认)
缓存文件
缓存+数据库
加密cookie
数据库session
数据库Session
SESSION_ENGINE = 'django.contrib.sessions.backends.db' # 引擎(默认)
缓存Session
SESSION_ENGINE = 'django.contrib.sessions.backends.cache' # 引擎 SESSION_CACHE_ALIAS = 'default' # 使用的缓存别名(默认内存缓存,也可以是memcache),此处别名依赖缓存的设置
文件Session
SESSION_ENGINE = 'django.contrib.sessions.backends.file' # 引擎 SESSION_FILE_PATH = None # 缓存文件路径,如果为None,则使用tempfile模块获取一个临时地址tempfile.gettempdir()
缓存+数据库
SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db' # 引擎
加密Cookie Session
SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies' # 引擎
1 SESSION_COOKIE_NAME='sessionid' 2 # session的cookie保存在浏览器上是的key,即sessionid=随机字符串(默认) 3 SESSION_COOKIE_PATH='/' 4 # session的bookie保存路径(默认) 5 SESSION_COOKIE_DAMAIN=None 6 #session的cookie保存的域名(默认) 7 SESSION_COOKIE_SECURE=False 8 #是否https传输cookie(默认) 9 SESSION_COOKIE_HTTPONLY=True 10 # 是否session的cookie只支持http传输(默认) 11 SESSION_COOKIE_AGE=1209600 12 #session的cookie失效日期(2周默认) 13 SESSION_EXPIRE_AT_BROWSER_CLOSE=False 14 #是否关闭浏览器是的session过期(默认) 15 SESSION_SAVE_EVERY_REQUEST=False 16 #是否每次请求都保存session,默认修改之后才保存(默认)
1 def index(request): 2 # 获取,设置,删除session中数据 3 request.session['k1'] 4 request.session.get('k1',None) 5 request.session['k1']=123 6 request.session.setdefault('k1',123) # 存在则不设置 7 del request.session['k1'] 8 9 # 所有键,值,键值对 10 request.sessin.keys() 11 request.session.values() 12 request.session.items() 13 request.session.iterkeys() 14 request.session.itervalues() 15 request.session.iteritems() 16 17 # 用户session的随机字符串 18 request.session.session_key 19 #将所有session失效日期小雨当前日期的数据删除 20 request.session.clear_expired() 21 #检查用户session的随机字符串在数据库中是否存在 22 request.session.exists('session_key') 23 # 删除当前用户的所有sessison数据 24 request.session.delete() 25 26 request.session.set_expiry(value) 27 * 如果value是个整数,session会在些秒数后失效 28 *如果value是个datatime或timedelta.session就会在这个时间之后失效 29 *如果value是0用户关闭浏览器session就会失效 30 *如果value是None,session会依赖全局session失效策略
django 操作session的时候,都是request.xxx
session
是保存在服务端的'键对值'数据
session必须要依赖于cookie
我们的session里面的键对值数据是在我们创建django项目的时候,自动生成的django_session的数据库表格里面,它会系统自动保存进去,
表格里面的字段有session_key(键)
session_data(值)
expire_date(失效时间)这里一般是默认值14天之后就会自动清空,为了缓解数据库的压力,这些数据不会永久保存下去的,
我们使用session的时候,它内部需要做的几件事,:
1生成随机字符串
2回给浏览器,让它写到cookie
3自己保留一份,作为一个key,存到一个地方,key后面对应一个保存用户相关信息的键值对
# 关于session的练习 # def logins(request): # if request.method== 'POST': # user = request.POST.get('user') # pwd = request.POST.get('pwd') # if user == 'wang' and pwd == '111': # # 设置session django封装好了包括三步( # # 1生成特殊随机字符串 # # 2会给浏览器让它写到cookie # # 3自己写一份 ,作为作为一个KEY存到一个地方,KEY后面对应一个保存用户相关信) # request.session['k1'] = user # return redirect('/indexs/') # return render(request,'logins.html') # # def indexs(request): # # session 的取值 # value = request.session.get('k1') # # 获取随机字符串 # print(request.session.session_key) # print('_' * 100) # # 设置有效的时间 如果是None的话就要看settings # request.session.set_expiry(10) # return render(request,'indexs.html', {'value':value}) # # # return HttpResponse(value) # 关于类的session 的练习 # 简单版开始 from django.views import View # class Login_View(View): # # def get(self,request): # return render(request,'login_c.html') # # def post(self,request): # user = request.POST.get('user') # pwd = request.POST.get('pwd') # if user == 'wang' and pwd == '111': # # 登陆成功 # request.session['k1'] = user # request.session.set_expiry(10) # return redirect('/index_c/') # # # class IndexView(View): # def get(self, request): # user = request.session.get('k1') # return render(request,'index_c.html',{'user':user}) # # # 这里有问题需要帮助????? # class Exit(View): # def logout_c(self, request): # ret = redirect('/login_c/') # ret.request.session.delete() # return ret # 类的简单版结束----------- # 类装饰器session的开始 # 先登陆 class Login_View(View): def get(self,request): return render(request,'login_c.html') def post(self,request): user = request.POST.get('user') pwd = request.POST.get('pwd') if user == 'wang' and pwd == '111': # 登陆成功 # 设置session request.session['k1'] = user request.session.set_expiry(10) return redirect('/index_c/') def wrapper(func): @wraps(func) def inner(request, *args, **kwargs): user3 = request.session.get('k1', None) if not user3: return redirect('/login_c/') else: ret = func(request, *args, **kwargs) return ret return inner from django.utils.decorators import method_decorator #类的装饰器 @method_decorator(wrapper, name='get') #第一种针对get 固定用法 name 和函数绑定 外边加name class IndexView(View): # @method_decorator(wrapper) #和第三种配合是针对 post get # def dispatch(self, request, *args, **kwargs): #第三种 针对post 和 get, 不加上句和第二种搭配 # return super(IndexView,self).dispatch( request, *args, **kwargs) #继承父类的 # 第二种针对get@method_decorator(wrapper) # 固定用法 name 和函数绑定 get函数里 不加name def get(self, request): user = request.session.get('k1') print(request.session.session_key) return render(request,'index_c.html',{'user':user}) # 类装饰器session的开始
CBV的session的url 的固定用法