Python自動化運維之改造網頁模板

開始以前,要準備好如下技能和材料:javascript

1.網頁模板,百度上找,要漂亮的,專業的。css

2.Pycharm專業版,請見小安Sir以往的推文。html

3.Python Django技能,能夠買本書掃盲。前端

4.Mysql數據庫,度娘或買書。java


只要肯下功夫,專研一個網頁模板,觸類旁通,搭建本身專屬系統不是夢。mysql

ps : 小安學一些前端知識只是爲了更好地鞏固Django這門語言。jquery

自動化系列
sql







磨刀之用戶註冊登錄數據庫

本文大綱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 用戶成功登錄

圖片


圖片

還等什麼,抄傢伙啊!

圖片

——————我是安老師下期預告的分割線——————

"安老師,你這用戶登錄還告訴別人密碼錯誤啊,別人不黑死你啊?"。

"只是演示,無傷大雅!應該把時間花在解決痛點上,而不是爲了好看而好看哈!

下期分享什麼好呢?一鍵部署mysql集羣、一鍵生成Oracle全部重啓項仍是本次的報錯彙總呢?敬請期待!"

相關文章
相關標籤/搜索