Hello,你們好!我是小安Sir!javascript
此次主要介紹Python的Django模塊,學會這個模塊,運維人員也能夠作簡單的小程序,好比,最近比較熱門的健康打卡系統?css
此次小安主要講自動化運維繫統,這對小安Sir來講,是一個很是重要的工程!由於工做中和生活中免不了一些繁瑣、須要總結、標準化的事情,那就找個契機搭建這個系統,整合自身資源,也是爲了持續不斷地更新自身技術!html
開始以前,要準備好如下技能和材料:前端
1.網頁模板,百度上找,要漂亮的,專業的。java
2.Pycharm專業版,請見小安Sir以往的推文。mysql
3.Python Django技能,能夠買本書掃盲。jquery
4.Mysql數據庫,度娘或買書。sql
只要肯下功夫,專研一個網頁模板,觸類旁通,搭建本身專屬系統不是夢。數據庫
ps : 小安學一些前端知識只是爲了更好地鞏固Django這門語言。django
自動化系列
磨刀之用戶註冊登錄
本文大綱
Attention
1. 網頁模板
2. Django基礎設置
3. Django APP部分
4. 演示
網頁模板
01
1.1 總體部分
小安Sir的前端水平有限,但將網頁改爲本身想要的樣子,這仍是沒問題滴(蜜汁自信)。爲了彌補時間和技術的不足,我特意從網上下載了一個比較漂亮的模板,正所謂愛漂亮之心,人皆有之。
若是本身寫一個網頁,額?看着這麼醜的界面,小安Sir實在沒心情把嘔心瀝血的代碼放上去。
上面都是瞎扯哈,網頁模板好處多多哈,有興趣的老鐵能夠搞一個閤眼緣的模板來玩玩哈。
先看看總體模板演示。
網頁模板
下面開始,小安Sir就直接貼改造後的html代碼了,若是你們在改造過程當中有什麼疑惑或者報錯的,歡迎加我微信或者後臺聯繫我喔!
1.2 登錄頁面
login.html
1{% load staticfiles %}
2<!DOCTYPE html>
3<html lang="en">
4<head>
5 <meta http-equiv="content-type" content="text/html; charset=UTF-8">
6 <meta charset="utf-8">
7 <title>Cloud Admin | Login</title>
8 <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1, user-scalable=no">
9 <meta name="description" content="">
10 <meta name="author" content="">
11 <link rel="stylesheet" type="text/css" href="{% static 'css/cloud-admin.css' %}" >
12 <link href="{% static 'font-awesome/css/font-awesome.min.css' %}" rel="stylesheet">
13 <!-- DATE RANGE PICKER -->
14 <link rel="stylesheet" type="text/css" href="{% static 'js/bootstrap-daterangepicker/daterangepicker-bs3.css' %}" />
15 <!-- UNIFORM -->
16 <link rel="stylesheet" type="text/css" href="{% static 'js/uniform/css/uniform.default.min.css' %}" />
17 <!-- ANIMATE -->
18 <link rel="stylesheet" type="text/css" href="{% static 'css/animatecss/animate.min.css' %}" />
19 <!-- FONTS -->
20</head>
21<body class="login">
22 <!-- PAGE -->
23 <!-- HEADER -->
24 <header>
25 <!-- NAV-BAR -->
26 <div class="container">
27 <div class="row">
28 <div class="col-md-4 col-md-offset-4">
29 <div id="logo">
30 <a href="{% url 'Dreaming:index' %}"><img src="{% static 'img/logo/logon_6.png' %}" height="40" alt="logo name" /></a>
31 </div>
32 </div>
33 </div>
34 </div>
35 <!--/NAV-BAR -->
36 </header>
37 <!--/HEADER -->
38 <!-- LOGIN -->
39 <div class="container">
40 <div class="row">
41 <div class="col-md-4 col-md-offset-4">
42 <div class="login-box-plain">
43 <h2 class="bigintro">Sign In</h2>
44 <div class="divide-40"></div>
45 <form role="form" action="." method="post">
46 {% if message %}
47 <div class="alert alert-warning">{{ message }}</div>
48 {% endif %}
49 {% csrf_token %}
50 <div class="form-group">
51 <label for="{{login_form.username.id_for_label}}">用戶</label>
52 <i class="fa fa-user"></i>
53 <input type="text" name='username' class="form-control" placeholder="Username" autofocus required>
54 </div>
55 <div class="form-group">
56 <label for="{{login_form.password.id_for_label}}">密碼</label>
57 <i class="fa fa-lock"></i>
58 <input type="password" name='password' class="form-control" placeholder="Password" autofocus required>
59 </div>
60 <div class="form-actions">
61 <button type="submit" class="btn btn-danger">登 陸</button>
62 </div>
63 </form>
64 <div class="login-helpers">
65
66 Don't have an account with us? <a href="{% url 'Dreaming:register' %}">Register now!</a>
67 </div>
68 </div>
69 </div>
70 </div>
71 </div>
72
73 <!--/PAGE -->
74 <!-- JAVASCRIPTS -->
75 <!-- Placed at the end of the document so the pages load faster -->
76 <!-- JQUERY -->
77 <script src="{% static 'js/jquery/jquery-2.0.3.min.js' %}"></script>
78 <!-- JQUERY UI-->
79 <script src="{% static 'js/jquery-ui-1.10.3.custom/js/jquery-ui-1.10.3.custom.min.js' %}"></script>
80 <!-- BOOTSTRAP -->
81 <script src="{% static 'bootstrap-dist/js/bootstrap.min.js' %}"></script>
82 <!-- UNIFORM -->
83 <script type="text/javascript" src="{% static 'js/uniform/jquery.uniform.min.js' %}"></script>
84 <!-- CUSTOM SCRIPT -->
85 <script src="{% static 'js/script.js' %}"></script>
86
87 <!-- /JAVASCRIPTS -->
88</body>
89</html>
主要修改了哪裏,才能讓模板適用於Django架構,請見下面表格。
注意:事實上還要修改不少,可是小安Sir以爲這對老鐵們來講,問題不大。
行 | 說明 |
30 | 指定網頁app的index連接,與app的urls.py相關。 |
45 |
制定表單,acthon=".",當前頁面。 |
46~48 |
網頁渲染,提醒報什麼錯誤。 |
49 |
{% csrf_token %},前段經過POST方式 提交數據,免受CSRF***,與表單內容一同被提交。 |
51 |
替換表單的label,獲得前端模板渲染的表單,並單獨實現 <input>元素。 |
61 |
提交表單。 |
1.3 註冊頁面
register.html
1{% load staticfiles %}
2<!DOCTYPE html>
3<html lang="en">
4<head>
5 <meta http-equiv="content-type" content="text/html; charset=UTF-8">
6 <meta charset="utf-8">
7 <title>Cloud Admin | Login</title>
8 <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1, user-scalable=no">
9 <meta name="description" content="">
10 <meta name="author" content="">
11 <link rel="stylesheet" type="text/css" href="{% static 'css/cloud-admin.css' %}" >
12 <link href="{% static 'font-awesome/css/font-awesome.min.css' %}" rel="stylesheet">
13 <!-- DATE RANGE PICKER -->
14 <link rel="stylesheet" type="text/css" href="{% static 'js/bootstrap-daterangepicker/daterangepicker-bs3.css' %}" />
15 <!-- UNIFORM -->
16 <link rel="stylesheet" type="text/css" href="{% static 'js/uniform/css/uniform.default.min.css' %}" />
17 <!-- ANIMATE -->
18 <link rel="stylesheet" type="text/css" href="{% static 'css/animatecss/animate.min.css' %}" />
19 <!-- FONTS -->
20</head>
21<body class="login">
22 <!-- PAGE -->
23 <!-- HEADER -->
24 <header>
25 <!-- NAV-BAR -->
26 <div class="container">
27 <div class="row">
28 <div class="col-md-4 col-md-offset-4">
29 <div id="logo">
30 <a href="{% url 'Dreaming:index' %}"><img src="{% static 'img/logo/logo-alt.png' %}" height="40" alt="logo name" /></a>
31 </div>
32 </div>
33 </div>
34 </div>
35 <!--/NAV-BAR -->
36 </header>
37 <!--/HEADER -->
38 <!-- REGISTER -->
39 <div class="container">
40 <div class="row">
41 <div class="col-md-4 col-md-offset-4">
42 <div class="login-box-plain">
43 <h2 class="bigintro">Register</h2>
44 <div class="divide-40"></div>
45 <form role="form" action="." method="post">
46 {% if message %}
47 <div class="alert alert-warning">{{ message }}</div>
48 {% endif %}
49 {% csrf_token %}
50 <div class="form-group">
51 <label for="{{register_form.username.id_for_label}}">Username</label>
52 <i class="fa fa-user"></i>
53 <input type="text" name='username' class="form-control" autofocus required>
54 </div>
55 <div class="form-group">
56 <label for="{{register_form.emailaddr.id_for_label}}">Email address</label>
57 <i class="fa fa-envelope"></i>
58 <input type="email" name='emailaddr' class="form-control" autofocus required>
59 </div>
60 <div class="form-group">
61 <label for="{{register_form.password.id_for_label}}">Password</label>
62 <i class="fa fa-lock"></i>
63 <input type="password" name='password' class="form-control" autofocus required>
64 </div>
65 <div class="form-group">
66 <label for="{{register_form.password2.id_for_label}}">Repeat Password</label>
67 <i class="fa fa-check-square-o"></i>
68 <input type="password" name='password2' class="form-control" autofocus required>
69 </div>
70 <div class="form-actions">
71 <button type="submit" class="btn btn-success">注 冊</button>
72 </div>
73 </form>
74 <div>
75 <a href="{% url 'Dreaming:login' %}" > Back to Login</a> <br>
76 </div>
77 </div>
78 </div>
79 </div>
80 </div>
81
82 <!--/PAGE -->
83 <!-- JAVASCRIPTS -->
84 <!-- Placed at the end of the document so the pages load faster -->
85 <!-- JQUERY -->
86 <script src="{% static 'js/jquery/jquery-2.0.3.min.js' %}"></script>
87 <!-- JQUERY UI-->
88 <script src="{% static 'js/jquery-ui-1.10.3.custom/js/jquery-ui-1.10.3.custom.min.js' %}"></script>
89 <!-- BOOTSTRAP -->
90 <script src="{% static 'bootstrap-dist/js/bootstrap.min.js' %}"></script>
91 <!-- UNIFORM -->
92 <script type="text/javascript" src="{% static 'js/uniform/jquery.uniform.min.js' %}"></script>
93 <!-- CUSTOM SCRIPT -->
94 <script src="{% static 'js/script.js' %}"></script>
95
96 <!-- /JAVASCRIPTS -->
97</body>
98</html>
註冊頁面,小安就再也不一一描述了,Label標籤要與<input>元素的命名一致,否則views.py的視圖函數會報沒法接收數據的錯誤。
Django基礎設置
02
2.1 建立項目和APP
略,請見小安Sir以前的推文(連接在最下方)。
2.2 配置settings.py
2.2.1 配置mysql數據庫
1import pymysql
2pymysql.install_as_MySQLdb()
3DATABASES = {
4 'default': {
5 'ENGINE': 'django.db.backends.mysql',
6 'NAME': 'Dreaming', # 數據庫名字
7 'USER': 'root', # 用戶名
8 'PASSWORD': 'mysql', # 密碼
9 'HOST': '192.168.117.30', # IP地址
10 'PORT': '3306', # 端口
11 }
12}
2.2.2 配置靜態目錄
1STATIC_URL = '/static/'
2STATICFILES_DIRS = [
3 os.path.join(BASE_DIR,'static'),
4]
2.3 配置urls.py
1# -*- coding: utf-8 -*-
2from django.contrib import admin
3from django.urls import path,include
4
5urlpatterns = [
6 path('admin/', admin.site.urls),
7 path('Dreaming/', include('Dreaming.urls')),
8]
Django App部分
03
3.1 urls.py
Dreaming這個APP的全部網址都在urls.py配置裏面,每一個網頁會用哪一個視圖函數,有什麼連接別名,都寫在下面,方便管理。
1# -*- coding: utf-8 -*-
2from django.urls import path
3from . import views
4
5app_name = "Dreaming"
6
7urlpatterns = [
8 path('<int:article_id>/', views.blog_article, name='blog_article'),
9 path('', views.index, name='index'),
10 path('sqlmon/', views.sql_mon,name='sqlmon'),
11 path('reboot/', views.reboot_info, name='reboot'),
12 path('login/', views.login, name='login'),
13 path('register/', views.register, name='register'),
14 path('no_ipaddress/', views.no_ipaddress, name='no_ipaddress'),
15 path('sliders_progress/', views.sliders_progress, name='sliders_progress'),
16 path('mys_cluster/', views.mys_cluster, name='mys_cluster'),
17]
3.2 models.py
編寫數據模型類,即定義表結構,不須要經過SQL語句直接跟數據庫打交道。不過這裏要注意,不要跟forms.py混淆,
1# -*- coding: utf-8 -*-
2# Create your models here.
3from django.db import models
4from django.utils import timezone
5
6class UserProfile(models.Model):
7 username = models.CharField(max_length=30, unique=True)
8 password = models.CharField(max_length=30)
9 emailaddr = models.EmailField(max_length=30, null=True)
10 sex = models.CharField(max_length=32, default='未知')
11 hobby = models.CharField(max_length=128,null=True)
12 company = models.CharField(max_length=128,null=True)
13 position = models.CharField(max_length=128,null=True)
14 c_time = models.DateTimeField(auto_now_add=True)
15
16 def __str__(self):
17 return self.username
18
19 class Meta:
20 ordering = ['c_time']
3.3 admin.py
至關於該項目的數據管理員了,這裏就很少說了,能夠參考以往的文章。
1# -*- coding: utf-8 -*-
2from django.contrib import admin
3from .models import UserProfile
4
5### 用戶相關
6class UserProfileAdmin(admin.ModelAdmin):
7 list_display = ("username","password","emailaddr","sex","hobby","company","position","c_time")
8admin.site.register(UserProfile,UserProfileAdmin)
3.4 forms.py
編寫表單類是必須的,有自定義的表單,還有來自models的。
1from django import forms
2from .models import UserProfile
3
4class LoginForm(forms.Form):
5 username = forms.CharField(widget=forms.TextInput())
6 password = forms.CharField(widget=forms.PasswordInput)
7
8class RegistrationForm(forms.ModelForm):
9 username = forms.CharField(widget=forms.TextInput())
10 password = forms.CharField(label="Password",widget=forms.PasswordInput)
11 password2 = forms.CharField(label="Repeat Password",widget=forms.PasswordInput)
12
13 class Meta:
14 model = UserProfile
15 fields= ["emailaddr"]
行 |
說明 |
2 |
導入models的數據模型。 |
4 |
建立LoginForm表單類(未綁定實例),提交表單後不會對數據庫表進行改變。 |
8 |
將RegistrationForm表單中數據寫入數據庫表,就要讓表單類繼承ModelForm類。 |
13~15 |
fields,表單選用數據庫表的部分字段。 |
2.4 views.py
業務邏輯層,包含存取模型及調用相應模板的相關邏輯,是模型M和模板T之間的橋樑。在Django獲得用戶的請求後,根據url映射關係到調用相應的視圖,視圖則調用和處理有關的數據。
基本上業務邏輯處理都在views.py實現,也就是說可能要導N多包。
1# -*- coding: utf-8 -*-
2# Create your views here.
3
4from django.shortcuts import render,redirect,render_to_response
5from Dreaming import models
6from django.template.loader import get_template
7from django.http import HttpResponse
8
9from .forms import LoginForm ### 用戶登陸表單
10from .forms import RegistrationForm ### 用戶註冊表單
11
12import os
13import sys
14
15def index(request):
16 return render(request,"Cloud/index.html") # pass
17
18def login(request):
19 if request.method == "POST":
20 login_form = LoginForm(request.POST)
21 if login_form.is_valid():
22 username = login_form.cleaned_data['username']
23 password = login_form.cleaned_data['password']
24 try:
25 user = models.UserProfile.objects.get(username=username)
26 if user.password == password:
27 return render(request, 'Cloud/index.html')
28 else:
29 message = "密碼不正確!"
30 except:
31 message = "用戶不存在!"
32 return render(request, 'Cloud/login.html',locals())
33 else:
34 login_form = LoginForm()
35 return render(request,'Cloud/login.html')
36
37def register(request):
38 if request.method == "POST":
39 register_form = RegistrationForm(request.POST)
40 if register_form.is_valid():
41 new_user = register_form.save(commit=False)
42 username = register_form.cleaned_data['username']
43 emailaddr = register_form.cleaned_data['emailaddr']
44 password = register_form.cleaned_data['password']
45 password2 = register_form.cleaned_data['password2']
46 exist_user = models.UserProfile.objects.filter(username=username)
47 if exist_user:
48 message = "用戶已經存在,請從新選擇用戶名!"
49 return render(request, 'Cloud/register.html', locals())
50 else:
51 if password != password2:
52 message = "兩次輸入的密碼不一樣!"
53 return render(request, 'Cloud/register.html', locals())
54 else:
55 new_user.username = username
56 new_user.password = password
57 new_user.emailaddr = emailaddr
58 new_user.save()
59 return redirect('Dreaming:login')
60 else:
61 register_form = RegistrationForm()
62 return render(request, 'Cloud/register.html', locals())
行 |
說明 |
4 | render(request, )是後者的快捷方式,render_to_reponse()將數據渲染到指定模板。redirect跳轉url頁面。 |
10-11 |
import 表單類 |
17 | login視圖函數,處理前端提交登錄的數據,視圖函數必須使用request做爲第一個參數。 |
18 |
request.method是HttpRequest對象的一個經常使用屬性,本次前端瀏覽器向服務器提交表單內容(類字典對象),採用POST方法。 |
19 |
創建綁定實例。 |
20 |
驗證傳入的數據是否合法,是否符合表單類屬性要求。True爲符合,False爲不符合。 |
21-22 |
cleaned_data,以字典形式返回實例具體數據(前端輸入的用戶名、密碼),若傳入數據不合法,則cleaned_data結果沒法顯示。 |
24-26 |
從數據庫的表過濾username字段的值,並返回對象(含該行全部字段信息),若是存在,且對象密碼與前端輸入的密碼相等,則返回app的index頁面。 |
28-31 |
渲染,若是密碼不對,網頁會顯示報錯信息(自定義顯示信息)。 |
40 |
commit=False,數據還未保存到數據庫,只是生成了一個數據對象。 |
54-56 |
由於表單返回的鍵值,與數據庫表中的字段並不是一一對應,含密碼驗證,故逐一指定字段的值。 |
57 |
保存到數據庫中。 |
演示
04
4.1 註冊已經存在用戶報錯
4.2 註冊密碼不一致
4.3 用戶註冊成功
4.4 用戶登錄報錯
4.5 用戶成功登錄