Session:
session是服务器端生成保存的一个键值对 , session内部机制依赖于cookie 。 用户登录后返回给客户端一个随机字符串,客户端带着随机字符串访问服务器,用于验证是否登录。
用户登录并创建session:
def login(request): """ :type request: object """ message = "" if request.method == "POST": #获取登录用户和密码 并验证 user = request.POST.get('username') passwd = request.POST.get('password') print(user, passwd) c = models.Administrator.objects.filter(username=user, password=passwd).count() if c: #验证通过, 创建session键值对 request.session['is_login'] = True request.session['username'] = user req = redirect('/index') print(req) # req.set_cookie('username',user) return req else: #验证失败报错 message = "用户名或密码错误!" return render(request, 'login.html', {'msg': message})
装饰器:用于判断是否登录
def auth(func): def inner(request,*args,**kwargs): is_login=request.session.get('is_login') if is_login: return func(request,*args,**kwargs) else: return redirect('/login') return inner
注销登录
@auth def logout(request): #session的键 session_key: dict_keys(['is_login', 'username']) session_key=request.session.keys() print("session_key: ", session_key) #值 session_values: dict_values([True, 'root']) session_values=request.session.values() print("session_values: ",session_values) #全部 session_items: dict_items([('is_login', True), ('username', 'root')]) session_items=request.session.items() print("session_items: ",session_items) # session 的key (后台生成的随机字符串) key: rk2o5cr47ychj0kgk6a7c5854d1zosrv key=request.session.session_key # print("key: ",key) # 将所有Session失效日期小于当前日期的数据删除 request.session.clear_expired() # 检查 用户session的随机字符串 在数据库中是否 request.session.exists("session_key") #注销登录信息,但是数据库依然保留了key和values request.session.clear() session_items=request.session.items() print("session_items: ",session_items) # 删除当前用户的所有Session数据 request.session.delete("session_key") #注销,删除session数据库表中的数据,达到注销的效果 request.session.delete(key) return redirect("/login")
用面向对象的方法实现 登录和注销
from django import views from django.utils.decorators import method_decorator def outer(func): def inner(request, *args, **kwargs): print(request.method) return func(request, *args, **kwargs) return inner class Order(views.View): pass # CBV # @method_decorator(outer, name='dispatch') class Login(views.View): # @method_decorator(outer) def dispatch(self, request, *args, **kwargs): ret = super(Login, self).dispatch(request, *args, **kwargs) return ret def get(self,request, *args, **kwargs): print('GET') return render(request, 'login.html', {'msg': ''}) def post(self, request, *args, **kwargs): print('POST') user = request.POST.get('user') pwd = request.POST.get('pwd') c = models.Administrator.objects.filter(username=user, password=pwd).count() if c: request.session['is_login'] = True request.session['username'] = user rep = redirect('/index.html') return rep else: message = "用户名或密码错误" return render(request, 'login.html', {'msg': message})
html前端界面
<!DOCTYPE html> <html lang="en" class="no-js"> <head> <meta charset="utf-8"> <title>后台管理登录</title> <style> /* * * Template Name: Fullscreen Login * Description: Login Template with Fullscreen Background Slideshow * Author: Anli Zaimi * Author URI: http://azmind.com * */ body { background: #f8f8f8; font-family: 'PT Sans', Helvetica, Arial, sans-serif; text-align: center; color: #fff; background-color: aquamarine; } .page-container { margin: 120px auto 0 auto; } h1 { font-size: 30px; font-weight: 700; text-shadow: 0 1px 4px rgba(0,0,0,.2); } form { position: relative; width: 305px; margin: 15px auto 0 auto; text-align: center; } input { width: 270px; height: 42px; margin-top: 25px; padding: 0 15px; background: #2d2d2d; /* browsers that don't support rgba */ background: rgba(45,45,45,.15); -moz-border-radius: 6px; -webkit-border-radius: 6px; border-radius: 6px; border: 1px solid #3d3d3d; /* browsers that don't support rgba */ border: 1px solid rgba(255,255,255,.15); -moz-box-shadow: 0 2px 3px 0 rgba(0,0,0,.1) inset; -webkit-box-shadow: 0 2px 3px 0 rgba(0,0,0,.1) inset; box-shadow: 0 2px 3px 0 rgba(0,0,0,.1) inset; font-family: 'PT Sans', Helvetica, Arial, sans-serif; font-size: 14px; color: #fff; text-shadow: 0 1px 2px rgba(0,0,0,.1); -o-transition: all .2s; -moz-transition: all .2s; -webkit-transition: all .2s; -ms-transition: all .2s; } input:-moz-placeholder { color: #fff; } input:-ms-input-placeholder { color: #fff; } input::-webkit-input-placeholder { color: #fff; } input:focus { outline: none; -moz-box-shadow: 0 2px 3px 0 rgba(0,0,0,.1) inset, 0 2px 7px 0 rgba(0,0,0,.2); -webkit-box-shadow: 0 2px 3px 0 rgba(0,0,0,.1) inset, 0 2px 7px 0 rgba(0,0,0,.2); box-shadow: 0 2px 3px 0 rgba(0,0,0,.1) inset, 0 2px 7px 0 rgba(0,0,0,.2); } button { cursor: pointer; width: 300px; height: 44px; margin-top: 25px; padding: 0; background: #ef4300; -moz-border-radius: 6px; -webkit-border-radius: 6px; border-radius: 6px; border: 1px solid #ff730e; -moz-box-shadow: 0 15px 30px 0 rgba(255,255,255,.25) inset, 0 2px 7px 0 rgba(0,0,0,.2); -webkit-box-shadow: 0 15px 30px 0 rgba(255,255,255,.25) inset, 0 2px 7px 0 rgba(0,0,0,.2); box-shadow: 0 15px 30px 0 rgba(255,255,255,.25) inset, 0 2px 7px 0 rgba(0,0,0,.2); font-family: 'PT Sans', Helvetica, Arial, sans-serif; font-size: 14px; font-weight: 700; color: #fff; text-shadow: 0 1px 2px rgba(0,0,0,.1); -o-transition: all .2s; -moz-transition: all .2s; -webkit-transition: all .2s; -ms-transition: all .2s; } button:hover { -moz-box-shadow: 0 15px 30px 0 rgba(255,255,255,.15) inset, 0 2px 7px 0 rgba(0,0,0,.2); -webkit-box-shadow: 0 15px 30px 0 rgba(255,255,255,.15) inset, 0 2px 7px 0 rgba(0,0,0,.2); box-shadow: 0 15px 30px 0 rgba(255,255,255,.15) inset, 0 2px 7px 0 rgba(0,0,0,.2); } button:active { -moz-box-shadow: 0 15px 30px 0 rgba(255,255,255,.15) inset, 0 2px 7px 0 rgba(0,0,0,.2); -webkit-box-shadow: 0 15px 30px 0 rgba(255,255,255,.15) inset, 0 2px 7px 0 rgba(0,0,0,.2); box-shadow: 0 5px 8px 0 rgba(0,0,0,.1) inset, 0 1px 4px 0 rgba(0,0,0,.1); border: 0px solid #ef4300; } .error { display: none; position: absolute; top: 27px; right: -55px; width: 40px; height: 40px; background: #2d2d2d; /* browsers that don't support rgba */ background: rgba(45,45,45,.25); -moz-border-radius: 8px; -webkit-border-radius: 8px; border-radius: 8px; } .error span { display: inline-block; margin-left: 2px; font-size: 40px; font-weight: 700; line-height: 40px; text-shadow: 0 1px 2px rgba(0,0,0,.1); -o-transform: rotate(45deg); -moz-transform: rotate(45deg); -webkit-transform: rotate(45deg); -ms-transform: rotate(45deg); } </style> </head> <body> <div class="page-container"> <h1>登录</h1> <form action="" method="post"> {% csrf_token %} <input type="text" name="username" class="username" placeholder="用户名"> <input type="password" name="password" class="password" placeholder="密码"> <span style="color: red">{{ msg }}</span> <button type="submit">提交</button> <div class="error"><span>+</span></div> </form> </div> </body> <script src="/static/jquery-2.1.4.min.js"></script> <script> jQuery(document).ready(function() { $('.page-container form').submit(function(){ var username = $(this).find('.username').val(); var password = $(this).find('.password').val(); if(username == '') { $(this).find('.error').fadeOut('fast', function(){ $(this).css('top', '27px'); }); $(this).find('.error').fadeIn('fast', function(){ $(this).parent().find('.username').focus(); }); return false; } if(password == '') { $(this).find('.error').fadeOut('fast', function(){ $(this).css('top', '96px'); }); $(this).find('.error').fadeIn('fast', function(){ $(this).parent().find('.password').focus(); }); return false; } }); $('.page-container form .username, .page-container form .password').keyup(function(){ $(this).parent().find('.error').fadeOut('fast'); }); }); </script> </html>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>{% block title %} welcome {% endblock %}</title> <style> *{ margin: 0px; padding: 0px; } .page_head{ position: absolute; width: 100%; top: 0; left: 0; height: 48px; background-color: aquamarine; } .page_head_memu{ position: relative; float: left; height: 48px; width: 100%; line-height: 48px; text-align: center; } .page_head_memu .span_names{ font-size: 30px; } .action-right{ position: absolute; top: 5px;; right: 10px; height: 48px; width: 100px; } .action-right a{ color: #3d3d3d; text-decoration: none; } .action-right #img_head{ height: 40px; width: 40px; border-radius: 50%; float: left; font-size: 10px; } .action-right #img_head:hover{ width: 50px; height: 50px; } .memu{ position: absolute; width: 150px; height: 550px; top: 50px; left: 20px; bottom: 0px; border: 1px solid #c0cddf; overflow :auto } .memu .items{ display: block; text-decoration: none; padding: 5px 10px; margin: 5px 10px; } .new{ background-color: #2d2d2d; } .content{ position:absolute; left: 175px; right: 0; top: 50px; bottom:0; background-color: azure; } .menu .items.active{ background-color: black; color: white; } #mytable { width: 1000px; padding: 0; margin: 0; } caption { padding: 0 0 5px 0; width: 700px; font: italic 20px "Trebuchet MS", Verdana, Arial, Helvetica, sans-serif; text-align: right; } th { font: bold 20px "Trebuchet MS", Verdana, Arial, Helvetica, sans-serif; color: #4f6b72; border-right: 1px solid #C1DAD7; border-bottom: 1px solid #C1DAD7; border-top: 1px solid #C1DAD7; letter-spacing: 2px; text-transform: uppercase; text-align: left; padding: 6px 6px 6px 12px; background: #CAE8EA no-repeat; } th.nobg { border-top: 0; border-left: 0; border-right: 1px solid #C1DAD7; background: none; } td { border-right: 1px solid #C1DAD7; border-bottom: 1px solid #C1DAD7; background: #fff; font-size:16px; padding: 6px 6px 6px 12px; color: #4f6b72; } td.alt { background: #F5FAFA; color: #797268; } th.spec { border-left: 1px solid #C1DAD7; border-top: 0; background: #fff no-repeat; font: bold 10px "Trebuchet MS", Verdana, Arial, Helvetica, sans-serif; } th.specalt { border-left: 1px solid #C1DAD7; border-top: 0; background: #f5fafa no-repeat; font: bold 10px "Trebuchet MS", Verdana, Arial, Helvetica, sans-serif; color: #797268; } #mytable td:hover{ background-color: #C1DAD7; } {% block css %} {% endblock %} </style> </head> <body> <div class="page_head"> <div class="page_head_memu"> <span class="span_names">后台管理</span> </div> <div class="action-right"> <a id="info" href="/logout"><img id="img_head" alt="传个头像吧" title="点击注销登录" src="/{{ img_list.0.path }}" /></a> <a class="action-nav">{{ username }}</a> <a href="#" class="action-nav username" style="float:left;display: none">注销</a><br> <a style="font-size: 8px">版本:V1.0</a> </div> </div> <div class="memu"> <a href="/classes/" class="items" id="memu_classes">班级管理</a> <a href="/student/" class="items" id="memu_student">学生管理</a> <a href="/teacher/" class="items" id="memu_teacher">教师管理</a> </div> <div class="content"> {% block content %} <div style="width: 700px"> <form method="POST" action="" enctype="multipart/form-data" style="width: 600px"> <input type="file" name="fafafa" /> <input type="submit" value="提交" /> </form> <div> {% for item in img_list %} <img style="height: 40px;width: 40px;border-radius: 50%" src="/{{ item.path }}" /> {% endfor %} </div> </div> {% endblock %} </div> {# <div class="page_foot"></div>#} <script src="/static/jquery-2.1.4.min.js"></script> <!--<script> $('.memu a').click(function(){ $(this).siblings().removeClass('new'); $(this).addClass('new'); }) </script>--> {% block js %} {% endblock %} </body> </html>