python_day20_Django-

发布时间:2019-06-30 16:53:12编辑:auto阅读(1216)

    cookie-session

    1、cookie说明

    1.1、cookie的由来?

      因为http请求是没有状态的,每一次请求都是独立的(对于服务端来说,一切都只是原来的样子)

    1.2、cookie有效时间?

      cookie关闭浏览器之后,如果没有设置超时时间,键值对就会失效.

    1.3、cookie原理

      cookie的工作原理是:由服务器产生内容,浏览器收到请求后保存在本地;当浏览器再次访问时,浏览器会自动带上Cookie,这样服务器就能通过Cookie的内容来判断这个是“谁”了。

    1.4、查看cookie

    以chremoe为例,右键检查,或者直接按f12
    python_day20_Django-4 (cookie_session)

    1.5、django中操作cookie

    代码共享路径:链接: 密码:3wv2

    1.5.1、方法一

    set_cookie(key, value)     设置cookie键值对
    COOKIES.get("key")        获取
    delete_cookie("key")        删除
    
    from django.shortcuts import render, redirect, HttpResponse
    
    # 设置登陆界面
    def login(request):
        if request.POST:
            username = request.POST.get("username")
            passwd = request.POST.get("passwd")
            if username == "xiong" and passwd == "123":
                        # 先获取要返回页面的对象
                ret = redirect("/index/")
                        # 设置cookie的key,value,最后返回页面 
                ret.set_cookie("login",username)
                return ret
        return render(request, "login.html")
    
    def index(request):
       #  获取cookie的值
        ret = request.COOKIES.get("login")
        if ret == "xiong":
            return render(request, "index.html")
        else:
            return redirect("/login")
    
    def logout(request):
        ret = redirect("/login/")
        ret.delete_cookie("login")
        return ret

    1.5.2、方法二 [set|get]_signed_cookie

    设置cookie值: salt: 加密盐, max_age 过期时长(单位秒)
    set_signed_cookie("key","value",salt="xx", max_age=10)   
    
    获取cookie值   key ,value salt加密值
    get_signed_cookie("login",default=0,salt="xiongge1111")
    
    def login(request):
        if request.method == "POST":
            username = request.POST.get("username")
            passwd = request.POST.get("passwd")
            next_url = request.GET.get("page")
            if username == "xiong" and passwd == "123":
                if next_url:   # 如果页面存在就跳到输入的页面,不存在就返回home页面
                    ret = redirect(next_url)
                else:
                    ret = redirect("/home/")
                ret.set_signed_cookie("login","xiong",salt="xiongge1111", max_age=10)
                return ret
        return render(request, "login.html")
    
    def index(request):
        # 获取 键值以及加盐的字符
        ret = request.get_signed_cookie("login",default=0,salt="xiongge1111")
        if ret == "xiong":
            return render(request, "index.html")
        else:
            return redirect("/login")

    1.5.3、方法三 装饰器

    使用装饰器进行配置
    get_full_path : 获取url中的路径消息
    path_info:   url_path路径
    from functools import wraps   装饰器修复工具
    
    from django.shortcuts import render, redirect, HttpResponse
    from functools import wraps
    # Create your views here.
    
    def loggin_check(func):
        @wraps(func)    # 装饰器修复工具
        def wapper(request, *args, **kwargs):
            ret = request.get_signed_cookie("login", default=0, salt="xiongge1111")
            if ret == "xiong":
                return func(request, *args, **kwargs)
            else:
                next_url = request.path_info
                print("next_url: ",next_url)
                return redirect("/login/?page={}".format(next_url))
        return wapper
    
    def login(request):
        if request.method == "POST":
            username = request.POST.get("username")
            passwd = request.POST.get("passwd")
            next_url = request.GET.get("page")
            if username == "xiong" and passwd == "123":
                if next_url:   # 如果页面存在就跳到输入的页面,不存在就返回home页面
                    ret = redirect(next_url)
                else:
                    ret = redirect("/home/")
                ret.set_signed_cookie("login","xiong",salt="xiongge1111", max_age=10)
                return ret
        return render(request, "login.html")
    
    # 获取不到页面中的登陆消息,就会直接返回到login页面
    @loggin_check
    def home(request):
        username = request.get_signed_cookie("login",default=0,salt="xiongge1111")
        return render(request, "home.html",{"username":username})
    
    html页面, 返回的是在页面中写的值如图
    <form action="{{ request.get_full_path }}" method="post">
        {% csrf_token %}
        <p>
            帐号<input type="text" name="username">
        </p>
        <p>
            密码 <input type="password" name="passwd">
        </p>
        <input type="submit" value="提交">
    </form>
    

    python_day20_Django-4 (cookie_session)

    2、session说明

      Cookie虽然在一定程度上解决了“保持状态”的需求,但是由于Cookie本身最大支持4096字节,以及Cookie本身保存在客户端,可能被拦截或窃取,因此就需要有一种新的东西,它能支持更多的字节,并且他保存在服务器,有较高的安全性。这就是Session。

    2.1、session数据存取

    存session:
     1:在服务端生成随机字符串,
     2:生成一个和上面随机字符串对应的大字典,用来保存用户的数据
     3:随机字符串当成cookie返回给浏览器
     4:session必须依赖于cookie
    
     取session:
     1:从请求携带的cookie里面找到随机字符串
     2:拿到随机字符串去 session中找对应的大字典
     3:从大字典中根据Key取值

    2.2、session优缺点

     session优点: 
     1:比cookie能存的数据更多
     2:安全性好,数据都保存在服务端
    
     session缺点:
     1:session数据量大,会占用一些资源,会话保存时间更长

    2.3、django中session相关方法

     获取:  request.session.get("key")
     设置: request.session["key"]=value      # 存不存在都设置
                 request.session.setdefault("key",value) #存在不设置
     清空session及浏览器cookie request.session.flush()
     只删除浏览器的cookie  request.session.delete()
    
     将所有Session失效日期小于当前日期的数据删除 :  request.session.clear_expired()
    
    设置会话Session和Cookie的超时时间:  request.session.set_expiry(value)
        * 如果value是个整数,session会在些秒数后失效。
        * 如果value是个datatime或timedelta,session就会在这个时间后失效。
        * 如果value是0,用户关闭浏览器session就会失效。
        * 如果value是None,session会依赖全局session失效策略。
    

    图片来源: http://www.cnblogs.com/liwenzhou/p/8343243.html
    python_day20_Django-4 (cookie_session)

    方法一

     from django.shortcuts import render, redirect
    # Create your views here.
    def login(request):
        if request.method == "POST":
            username = request.POST.get("username")
            passwd = request.POST.get("passwd")
            if username == "xiong" and passwd == "123":
                request.session["login"] = "xiong"      # 设置session 键值对
                next_url = request.GET.get("path")  # 获取路径
                return redirect(next_url)   # 返回浏览器的路径 
        return render(request, "app02/login.html")
    
    def home(request):
        if request.session.get("login"):
            return render(request, "app02/home.html")
        else:
            return redirect("/app02/login/")
    
    # 清空session及cookie
    def logout(request):
        request.session.flush()
        return redirect("/app02/login/")

    方法二 装饰器

    from django.shortcuts import render, redirect
    from functools import wraps
    
    def check_login(func):
        @wraps(func)
        def warrper(request,*args,**kwargs):
            next_url = request.get_full_path()
            if request.session.get("login"):
                return func(request,*args,**kwargs)
            else:
                return redirect("/app02/login/?path={}".format(next_url))
        return warrper
    
    # Create your views here.
    def login(request):
        if request.method == "POST":
            username = request.POST.get("username")
            passwd = request.POST.get("passwd")
            if username == "xiong" and passwd == "123":
                request.session["login"] = "xiong"
                            # 如果获取不到那么就返回home
                next_url = request.GET.get("path")
                if next_url:
                    return redirect(next_url)
                else:
                    return redirect("/app02/home/")
        return render(request, "app02/login.html")
    
    def home(request):
        if request.session.get("login"):
            return render(request, "app02/home.html")
        else:
            return redirect("/app02/login/")
    
    @check_login
    def index(request):
        return render(request, "app02/index.html")
    
    def logout(request):
        request.session.flush()
        return redirect("/app02/login/")

    2.4、django中的session配置

    文档来源: http://www.cnblogs.com/liwenzhou/p/8343243.html

    1. 数据库Session
    SESSION_ENGINE = 'django.contrib.sessions.backends.db'   # 引擎(默认)
    
    2. 缓存Session
    SESSION_ENGINE = 'django.contrib.sessions.backends.cache'  # 引擎
    SESSION_CACHE_ALIAS = 'default'                            # 使用的缓存别名(默认内存缓存,也可以是memcache),此处别名依赖缓存的设置
    
    3. 文件Session
    SESSION_ENGINE = 'django.contrib.sessions.backends.file'    # 引擎
    SESSION_FILE_PATH = None                                    # 缓存文件路径,如果为None,则使用tempfile模块获取一个临时地址tempfile.gettempdir() 
    
    4. 缓存+数据库
    SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'        # 引擎
    
    5. 加密Cookie Session
    SESSION_ENGINE = 'django.contrib.sessions.backends.signed_cookies'   # 引擎
    
    其他公用设置项:
    SESSION_COOKIE_NAME = "sessionid"                       # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串(默认)
    SESSION_COOKIE_PATH = "/"                               # Session的cookie保存的路径(默认)
    SESSION_COOKIE_DOMAIN = None                             # Session的cookie保存的域名(默认)
    SESSION_COOKIE_SECURE = False                            # 是否Https传输cookie(默认)
    SESSION_COOKIE_HTTPONLY = True                           # 是否Session的cookie只支持http传输(默认)
    SESSION_COOKIE_AGE = 1209600                             # Session的cookie失效日期(2周)(默认)
    SESSION_EXPIRE_AT_BROWSER_CLOSE = False                  # 是否关闭浏览器使得Session过期(默认)
    SESSION_SAVE_EVERY_REQUEST = False                       # 是否每次请求都保存Session,默认修改之后才保存(默认)
    

    在django项目settings.py文件中增加一行SESSION_COOKIE_NAME = "web.com" 浏览器中对应的session key名就会改变
    python_day20_Django-4 (cookie_session)

    settings.py文件中修改 SESSION_SAVE_EVERY_REQUEST = True 设置过期时间为10秒, 当页面在刷新的时候,只要在在10秒内刷新,那么就不会过期

    方法三 CBV 类函数

    from django.shortcuts import render, redirect
    from django import views        # 导入视图函数
    from functools import wraps
    # 类方法装饰器
    from django.utils.decorators import method_decorator
    
    def check_login(func):
        @wraps(func)
        def warrper(request,*args,**kwargs):
            next_url = request.get_full_path()
            if request.session.get("login"):
                return func(request,*args,**kwargs)
            else:
                return redirect("/app02/login/?path={}".format(next_url))
        return warrper
    
    # 加在函数上
    class HomeView(views.View):
        @method_decorator(check_login)
        def get(self,requset):
            return render(requset, "app02/home.html")
    
    # 加在类上 必须要传name关键字参数
    @method_decorator(check_login,name="get")
    # @method_decorator(check_login,name="post")
    class HomeView(views.View):
        def get(self,requset):
            return render(requset, "app02/home.html")
    

    FAQ:

    no such table: django_session
    说明没有创建session表,不管是mysql还是sqlite3 都需要执行
    python manage.py makemigrations
    python manage.py migrate
    

关键字