博主最近想基於Django框架開發一個測試平台,第一版先實現查看下載自動化的測試報告文件
第一步:前端框架
網上選擇一款開源boostrap的前端框架 AdminLTE,這里給個鏈接 https://adminlte.io/
第二步:實現登錄/注銷功能
需要加入對登錄狀態的校驗,准備引入session
1、base.html 基於開源框架:
1 <!DOCTYPE html> 2 <html lang="zh-cn"> 3 4 <head> 5 <meta charset="utf-8"> 6 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 7 <title>xx</title> 8 <!-- Tell the browser to be responsive to screen width --> 9 <meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport"> 10 <link rel="stylesheet" href="/static/bower_components/bootstrap/dist/css/bootstrap.min.css"> 11 <!-- Font Awesome --> 12 <link rel="stylesheet" href="/static/bower_components/font-awesome/css/font-awesome.min.css"> 13 <!-- Ionicons --> 14 <link rel="stylesheet" href="/static/bower_components/Ionicons/css/ionicons.min.css"> 15 <!-- Theme style --> 16 <link rel="stylesheet" href="/static/dist/css/AdminLTE.min.css"> 17 <link rel="stylesheet" href="/static/dist/css/skins/skin-blue.min.css"> 18 <link rel="icon" href="/static/icon/icon-a.png"> 19 20 <!-- Google Font --> 21 <link rel="stylesheet" 22 href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,600,700,300italic,400italic,600italic"> 23 </head> 24 25 26 {% block starter %} 27 {% endblock %} 28 29 {% block login %} 30 {% endblock %} 31 32 33 <script src="/static/bower_components/jquery/dist/jquery.min.js"></script> 34 <!-- Bootstrap 3.3.7 --> 35 <script src="/static/bower_components/bootstrap/dist/js/bootstrap.min.js"></script> 36 <!-- AdminLTE App --> 37 <script src="/static/dist/js/adminlte.min.js"></script> 38 39 <!-- Optionally, you can add Slimscroll and FastClick plugins. 40 Both of these plugins are recommended to enhance the 41 user experience. --> 42 </html>
2、登錄頁面
1 {% extends 'base.html' %} 2 {% block login %} 3 <body class="hold-transition login-page"> 4 <div class="login-box"> 5 <div class="login-logo"> 6 <a href="/login"><b>自動化</b>平台</a> 7 </div> 8 <!-- /.login-logo --> 9 <div class="login-box-body"> 10 <p class="login-box-msg">輸入用戶郵箱與密碼</p> 11 12 <form method="post"> 13 {% csrf_token %} 14 <div class="form-group has-feedback"> 15 {{ uf.email }} 16 <span class="glyphicon glyphicon-envelope form-control-feedback"></span> 17 </div> 18 <div class="form-group has-feedback"> 19 {{ uf.password }} 20 <span class="glyphicon glyphicon-lock form-control-feedback"></span> 21 </div> 22 <div class="row"> 23 <div class="col-xs-12"> 24 <button type="submit" class="btn btn-primary btn-block btn-flat">登錄</button> 25 </div> 26 <!-- /.col --> 27 </div> 28 </form> 29 30 </div> 31 <!-- /.login-box-body --> 32 </div> 33 </div> 34 {% endblock %}
3、首頁
1 {% extends 'base.html' %} 2 {% block starter %} 3 <body class="hold-transition skin-blue sidebar-mini"> 4 <div class="wrapper"> 5 <!-- Main Header --> 6 <header class="main-header"> 7 8 <!-- Logo --> 9 <a href="/index" class="logo"> 10 <!-- mini logo for sidebar mini 50x50 pixels --> 11 <span class="logo-mini"><b>自</span> 12 <!-- logo for regular state and mobile devices --> 13 <span class="logo-lg"><b>自</b>動化平台</span> 14 </a> 15 16 <!-- Header Navbar --> 17 <nav class="navbar navbar-static-top" role="navigation"> 18 <!-- Sidebar toggle button--> 19 <a href="#" class="sidebar-toggle" data-toggle="push-menu" role="button"> 20 <span class="sr-only">Toggle navigation</span> 21 </a> 22 <!-- Navbar Right Menu --> 23 <div class="navbar-custom-menu"> 24 <ul class="nav navbar-nav"> 25 <!-- User Account Menu --> 26 <li class="dropdown user user-menu"> 27 <!-- Menu Toggle Button --> 28 <a href="#" class="dropdown-toggle" data-toggle="dropdown"> 29 <!-- hidden-xs hides the username on small devices so only the image appears. --> 30 <i class="fa fa-user"></i> 31 <span class="hidden-xs">{{ username }}</span> 32 </a> 33 </li> 34 <li> 35 <a href="/logout"> 36 <i class="fa fa-sign-out"></i> 37 <span class="hidden-xs">登出</span> 38 </a> 39 </li> 40 <li> 41 <a href="/admin"> 42 <i class="fa fa-gears"></i> 43 <span class="hidden-xs">后台</span> 44 </a> 45 </li> 46 </ul> 47 </div> 48 </nav> 49 </header> 50 <!-- Left side column. contains the logo and sidebar --> 51 <aside class="main-sidebar"> 52 53 <!-- sidebar: style can be found in sidebar.less --> 54 <section class="sidebar"> 55 56 <!-- Sidebar Menu --> 57 <ul class="sidebar-menu" data-widget="tree"> 58 <li class="header">菜單</li> 59 <!-- Optionally, you can add icons to the links --> 60 <li class="active"> 61 <a href="#"><i class="fa fa-link"></i> <span>模板</span></a> 62 </li> 63 <li class="treeview"> 64 <a href="#"><i class="fa fa-link"></i> <span>接口模塊</span> 65 <span class="pull-right-container"> 66 <i class="fa fa-angle-left pull-right"></i> 67 </span> 68 </a> 69 <ul class="treeview-menu"> 70 {% for path in paths %} 71 <li><a href="/paths/{{ path.path_id }}">{{ path.path }}</a></li> 72 {% endfor %} 73 </ul> 74 </li> 75 <li> 76 <a href="xx"><i class="fa fa-link"></i> <span>禪道</span></a> 77 </li> 78 <li> 79 <a href="xx"><i class="fa fa-link"></i> <span>Jenkins</span></a> 80 </li> 81 </ul> 82 <!-- /.sidebar-menu --> 83 </section> 84 <!-- /.sidebar --> 85 </aside> 86 87 <!-- Content Wrapper. Contains page content --> 88 <div class="content-wrapper"> 89 {% block paths %} 90 {% endblock %} 91 </div> 92 <!-- /.content-wrapper --> 93 94 <!-- Control Sidebar --> 95 <aside class="control-sidebar control-sidebar-dark"> 96 <!-- Create the tabs --> 97 <ul class="nav nav-tabs nav-justified control-sidebar-tabs"> 98 <li class="active"><a href="#control-sidebar-home-tab" data-toggle="tab"><i class="fa fa-home"></i></a></li> 99 <li><a href="#control-sidebar-settings-tab" data-toggle="tab"><i class="fa fa-gears"></i></a></li> 100 </ul> 101 <!-- Tab panes --> 102 <div class="tab-content"> 103 <!-- Home tab content --> 104 <div class="tab-pane active" id="control-sidebar-home-tab"> 105 <h3 class="control-sidebar-heading">Recent Activity</h3> 106 <ul class="control-sidebar-menu"> 107 <li> 108 <a href="javascript:;"> 109 <i class="menu-icon fa fa-birthday-cake bg-red"></i> 110 111 <div class="menu-info"> 112 <h4 class="control-sidebar-subheading">Langdon's Birthday</h4> 113 114 <p>Will be 23 on April 24th</p> 115 </div> 116 </a> 117 </li> 118 </ul> 119 <!-- /.control-sidebar-menu --> 120 121 <h3 class="control-sidebar-heading">Tasks Progress</h3> 122 <ul class="control-sidebar-menu"> 123 <li> 124 <a href="javascript:;"> 125 <h4 class="control-sidebar-subheading"> 126 Custom Template Design 127 <span class="pull-right-container"> 128 <span class="label label-danger pull-right">70%</span> 129 </span> 130 </h4> 131 132 <div class="progress progress-xxs"> 133 <div class="progress-bar progress-bar-danger" style="width: 70%"></div> 134 </div> 135 </a> 136 </li> 137 </ul> 138 <!-- /.control-sidebar-menu --> 139 140 </div> 141 <!-- /.tab-pane --> 142 <!-- Stats tab content --> 143 <div class="tab-pane" id="control-sidebar-stats-tab">Stats Tab Content</div> 144 <!-- /.tab-pane --> 145 <!-- Settings tab content --> 146 <div class="tab-pane" id="control-sidebar-settings-tab"> 147 <form method="post"> 148 <h3 class="control-sidebar-heading">General Settings</h3> 149 150 <div class="form-group"> 151 <label class="control-sidebar-subheading"> 152 Report panel usage 153 <input type="checkbox" class="pull-right" checked> 154 </label> 155 156 <p> 157 Some information about this general settings option 158 </p> 159 </div> 160 <!-- /.form-group --> 161 </form> 162 </div> 163 <!-- /.tab-pane --> 164 </div> 165 </aside> 166 <!-- /.control-sidebar --> 167 <!-- Add the sidebar's background. This div must be placed 168 immediately after the control sidebar --> 169 <div class="control-sidebar-bg"></div> 170 </body> 171 {% endblock %}
4、views.py
1 # -*- coding: utf-8 -*- 2 from __future__ import unicode_literals 3 4 from django.shortcuts import render, render_to_response 5 from django.http import HttpResponse, HttpResponseRedirect, StreamingHttpResponse 6 from django.views.decorators.csrf import csrf_exempt 7 from django.template import RequestContext 8 from models import User, Path, File 9 from form import UserForm 10 11 import random 12 13 # Create your views here. 14 15 16 # 基礎頁面 17 def base(request): 18 return render(request, "base.html") 19 20 21 # 開始頁面 22 def starter(request): 23 return render(request, "starter.html") 24 25 26 # 首頁 27 def index(request): 28 # 判斷是否有session 29 username = request.session.get("username") 30 if username: 31 report_paths = Path.objects.all() 32 paths = [] 33 for x, y in enumerate(report_paths): 34 path = { 35 "path_id": x + 1, 36 "path": y.path 37 } 38 paths.append(path) 39 return render(request, "index.html", {"paths": paths, 40 "username": username}) 41 else: 42 # 如果沒有session,重定向到路由 /login/, 返回表單 43 uf = UserForm(request.POST) 44 return HttpResponseRedirect("/login/", {"uf": uf}) 45 46 47 # 登錄 48 @csrf_exempt 49 def login(request): 50 if request.method == "POST": 51 uf = UserForm(request.POST) 52 if uf.is_valid(): 53 email = uf.cleaned_data["email"] 54 password = uf.cleaned_data["password"] 55 user = User.objects.filter(email=email, password=password) 56 # print user[0].username 57 if user: 58 request.session["username"] = user[0].username 59 # 校驗通過,重定向到/index/ 60 return HttpResponseRedirect("/index/") 61 else: 62 uf = UserForm(request.POST) 63 return render(request, "login.html", {"uf": uf}) 64 else: 65 uf = UserForm(request.POST) 66 return render(request, "login.html", {"uf": uf}) 67 68 69 # 注銷 70 def logout(request): 71 del request.session["username"] # 刪除session 72 uf = UserForm(request.POST) 73 return HttpResponseRedirect("/login/", {"uf": uf})
5、啟動進入登錄頁面
6、登錄成功后:
代碼中加了一部分的注釋、繼續完善平台功能