Python自动化运维之改造网页模板
ir
Hello,大家好!我是小安Sir!
这次主要介绍Python的Django模块,学会这个模块,运维人员也可以做简单的小程序,比如,最近比较热门的健康打卡系统?
这次小安主要讲自动化运维系统,这对小安Sir来说,是一个非常重要的工程!因为工作中和生活中免不了一些繁琐、需要总结、标准化的事情,那就找个契机搭建这个系统,整合自身资源,也是为了持续不断地更新自身技术!
开始之前,要准备好以下技能和材料:
1.网页模板,百度上找,要漂亮的,专业的。
2.Pycharm专业版,请见小安Sir以往的推文。
3.Python Django技能,可以买本书扫盲。
4.Mysql数据库,度娘或买书。
只要肯下功夫,专研一个网页模板,举一反三,搭建自己专属系统不是梦。
ps : 小安学一些前端知识只是为了更好地巩固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所有重启项还是本次的报错汇总呢?敬请期待!"
如有侵权,请联系删除,谢谢!
往期回顾
Python切割文件教程一 | 我的“大马士革命刀"
Python切割文件教程二 | 我的“大马士革命刀"不Like补刀
Django博客教程一 | Django架构介绍
Django博客教程二 | Django入门版博客
Django博客教程三 | Django进阶版博客数据篇
Django博客教程四 | Django进阶版博客网页篇
Python
自动化运维
长按识别左侧二维码,
关注Python自动化运维喔~