Python自动化运维之前端部署Mysql架构(二)
Hello,大家好!我是小安Sir,上一篇推文给老铁们展示了下自动化运维系统的样板,那么这一期就来讲讲如何实现的!
已经忘了的老铁们可以点击下方的链接。上一篇推文链接如下:
这个自动化运维系统应该来说是非常简单,只要理解Django框架、基本的Python知识以及简单的前端知识,是没问题的。
小安Sir比较懒,经常会忘记自己写的代码,最近在系统学习mysql数据库。
要不是老铁催我,支持我,我真没啥动力写!接下来还会推多几篇,后续会推一些付费图文,里有详细的源代码和视频,绝对物有所值。
正文开始:
Python自动化运维
前端部署Mysql架构二
本文大纲
Attention
1. 前端展示
2. models.py 数据模型
3. forms.py 表单
4. views.py 程序逻辑
5. 效果展示
前端展示
01
1.1 页面展示
1.2 html页面代码
在templates/Cloud的目录下,新建一个网页,编辑 mys_install.html 页面。
关键代码
1 <div class="box-body big">
2 <style>.textCetent{text-align:center;}</style>
3 <h3 class="form-title " >请输入主机和数据库的相关信息...</h3>
4 <div class="separator"></div>
5 <form class="form-horizontal" role="form" action="." method="post">{% csrf_token %}
6
7 <div class="form-group">
8 <label for="{{ mys_install_form.db_ipaddr.id_for_label }}" class="col-sm-2 control-label">IP地址</label>
9 <input type="text" class="form-control" name="db_ipaddr" style="width:1000px;" placeholder="请输入IP地址">
10 </div>
11
12 <div class="form-group">
13 <label for="{{ mys_install_form.db_port.id_for_label }}" class="col-sm-2 control-label">端口</label>
14 <input type="text" class="form-control" name="db_port" style="width:1000px;" placeholder="请输入端口">
15 </div>
16
17 <div class="separator"></div>
18 <div class="form-group">
19 <label class="col-sm-2 control-label">操作系统</label>
20 <div class="col-sm-8">
21 <div class="row">
22 <div class="col-lg-6">
23 <div class="input-group">
24 <label for="{{ mys_install_form.os_user.id_for_label }}" class="input-group-addon" type="button"> OS用户名</label>
25 <input type="text" class="form-control" name="os_user">
26 </div>
27 </div>
28 <div class="col-lg-6">
29 <div class="input-group">
30 <label for="{{ mys_install_form.os_passwd.id_for_label }}" class="input-group-addon" type="button">OS密码</label>
31 <input type="password" class="form-control" name="os_passwd">
32 </div>
33 </div>
34 </div>
35 </div>
36 </div>
37
38 <div class="separator"></div>
39
40 <div class="form-group">
41 <label class="col-sm-2 control-label">数据库</label>
42 <div class="col-sm-8">
43 <div class="row">
44 <div class="col-lg-6">
45 <div class="input-group">
46 <label for="{{ mys_install_form.app_name.id_for_label }}" class="input-group-addon" type="button"> 业务简称 </label>
47 <input type="text" class="form-control" name="app_name">
48 </div>
49 </div>
50 <div class="col-lg-6">
51 <div class="input-group">
52 <label for="{{ mys_install_form.innodb_mem.id_for_label }}" class="input-group-addon" type="button">DB缓存</label>
53 <input type="text" class="form-control" name="innodb_mem" placeholder="请输入Innodb缓存 (MB) ">
54 </div>
55 </div>
56 </div>
57 </div>
58 </div>
59
60 <div class="form-group">
61 <label class="col-sm-2 control-label"> </label>
62 <div class="col-sm-8">
63 <div class="row">
64 <div class="col-lg-6">
65 <div class="input-group">
66 <label for="{{ mys_install_form.db_charset.id_for_label }}" class="input-group-addon" type="button" >DB字符集</label>
67 <input type="text" class="form-control" name="db_charset">
68 </div>
69 </div>
70 <div class="col-lg-6">
71 <div class="input-group">
72 <label for="{{ mys_install_form.db_passwd.id_for_label }}" class="input-group-addon" type="button">DB密码</label>
73 <input type="password" class="form-control" name="db_passwd">
74 </div>
75 </div>
76 </div>
77 </div>
78 </div>
79
80
81 <div class="form-group">
82 <label for="{{ mys_install_form.install_type.id_for_label }}" class="col-sm-2 control-label">请选择安装类型 </label>
83 <div class="col-md-3 " >
84 {{ mys_install_form.install_type }}
85 </div>
86 </div>
87 <div class="form-group">
88 <label for="{{ mys_install_form.db_type.id_for_label }}" class="col-sm-2 control-label">请选择数据库版本</label>
89 <div class="col-md-3">
90 {{ mys_install_form.db_type }}
91 <!-- <div class="divide-10"></div> 上下栏目距离 -->
92 </div>
93 </div>
94
95 <div class="form-group">
96 <label for="{{ mys_install_form.pub_date.id_for_label }}" class="col-sm-2 control-label"> 日期</label>
97 <div class="col-md-3" >
98 {{ mys_install_form.pub_date }}
99 </div>
100 </div>
101
102 <div class="divide-10"></div>
103 <div class="form-group">
104 <label class="col-sm-2 control-label">添加任务列表</label>
105 <div class="col-sm-9">
106 <button type="submit" class="btn btn-success btn-lg">提交任务</button>
107 </div>
108 </div>
109
110 <div class="form-group" >
111 <label class="col-sm-2 control-label">重置当前任务</label>
112 <div class="col-sm-9">
113 <button type="reset" class="btn btn-purple btn-lg">Reset</button>
114 </div>
115 </div>
116
117 </form>
118 </div>
119 </div>
120 </div>
121 </div>
122 <!-- SAMPLE -->
123 </div>
124 <!-- /SAMPLE -->
125 </div>
126 </div>
127 <!-- /FORMS -->
行 | |
5 | 制定表单,acthon=".",当前页面。 |
5 | {% csrf_token %},前段通过POST方式 提交数据,免受CSRF攻击,与表单内容一同被提交。 |
7 | form-group,表单。 |
8 | mys_install_form.db_ipaddr.id_for_label , 来自于views.py的 mys_install函数,mys_install函数需要forms的 MysInstallForm表单,该表单函数需要models.py的Mys_Install_Profile函数。每个html的表单,均如此类推。 |
9 | <input>里面的name一定要有,否则无法对号入座。 |
84 | mys_install_form.install_type , mys_install_form来自于views.py的函数,install_type是安装类型。 |
90 | mys_install_form.db_type , mys_install_form来自于views.py的函数,db_type是数据库版本。 |
106 | 提交表单。 |
113 | 重置表单。 |
弄清楚第8点的逻辑,这是一个反向思维,由前端推到后端如何实现,这是承上启下的关键。
接下来,我们使用正向思维,一个个攻克。
models.py 数据模型
02
2.1 构造数据模型
编辑models.py,添加Mys_Install_Profile函数。
1class Mys_Install_Profile(models.Model):
2 #ipaddress = models.GenericIPAddressField() ### more ip cant input
3 db_ipaddr = models.CharField(max_length=100)
4 db_port = models.CharField(max_length=50)
5 os_user = models.CharField(max_length=30)
6 os_passwd = models.CharField(max_length=100)
7 app_name = models.CharField(max_length=30)
8 innodb_mem = models.CharField(max_length=30)
9 db_charset = models.CharField(max_length=30)
10 db_passwd = models.CharField(max_length=30)
11 install_type = models.CharField(max_length=100)
12 db_type = models.CharField(max_length=100)
13 pub_date = models.DateTimeField(default=timezone.now) # pub_date # auto_now=True
14 zh_install_type = models.CharField(max_length=100,null=True,default='')
15 zh_db_type = models.CharField(max_length=100,null=True,default='')
16 class Meta:
17 ordering = ("-pub_date",)
18
19 def __str__(self):
20 return self.db_ipaddr
行 | |
2 | models模块也有自己IP字段,但这里为了避免更多错误尝试,先直接选用字符串代替。 |
6 | os_password也是字符串,如果要在前端显示为"*",那么就要html页面将input标签的type改为"password"。 |
13 | 使用日期类型,需要导入timezone模块, from django.utils import timezone。 |
16-17 | 在admin管理界面,使用日期排序。 |
将以上数据模型同步到数据库中,这也是整个应用程序中最简单的一步。
1python manage.py migrate
forms.py 表单
03
1.4 根据model模块制造表单
编辑views.py,导入model模块
1from .models import Mys_Install_Profile
编辑MysInstallForm函数,这里直接使用model模块的字段,并且对于install_type和db_type进行改造,使之能在前端显示。
1class MysInstallForm(forms.ModelForm):
2
3 install_type_list = ((1,'首次安装'),(2,'新增安装'),(3,'还原重装'),(4,'删库跑路'),)
4 db_type_list = ((1,'Mysql 5.7.30'),(2,'Mysql 8.0'),)
5 install_type = forms.CharField(initial=1,widget=forms.RadioSelect(choices=install_type_list))
6 db_type = forms.CharField(widget=forms.Select(choices=db_type_list))
7 class Meta:
8 model = Mys_Install_Profile
9 fields= ["db_ipaddr","db_port","os_user","os_passwd","app_name","innodb_mem","db_charset","db_passwd","pub_date"]
10
11 def __init__(self, *args, **kwargs):
12 super(MysInstallForm, self).__init__(*args, **kwargs)
13 for field_name in self.base_fields:
14 #print(field_name) ### 刷出FORM名字
15
16 field = self.fields[field_name]
17 if field_name != 'install_type':
18 field.widget.attrs.update({"class": "form-control"})
19 else:
20 field.widget.attrs.update({"class": "uniform"})
21
22 def zh_ins_type(self):
23 zh_ins_tylt = []
24 cd = self.cleaned_data ### 返回选项的代码数字为字符串,与这里的自定义选项int类型不同。
25 print("CD:",cd)
26 for type in self.install_type_list:
27 if str(type[0]) == cd['install_type']:
28 print(type[0],type[1])
29 #zh_install_type = type[1]
30 zh_ins_tylt.append(type[1])
31 for type in self.db_type_list:
32 if str(type[0]) == cd['db_type']:
33 print(type[0],type[1])
34 #zh_db_type = type[1]
35 zh_ins_tylt.append(type[1])
36 print(zh_ins_tylt)
37 return zh_ins_tylt
行 | |
1 | forms.ModelForm是forms里面常用的类,如果要将表单的数据写入数据库表里面或者修改值,则让表单类继承ModelForm类;如果提交不会对数据库操作,比如只是验证之类的,则使用Form类。 |
3-4 | 在表单内相关字段重新定义两个变量。 |
5 | 部署类型,inital=1,即前端显示默认选中首次安装,但是数据库层面仅仅是记录数值,故在该MysInstallForM类里面还需要定义zh_ins_type来根据数值换取对应的中文。 |
6 | 安装Mysql数据库版本,默认在前端显示5.7.30,其数值对应的中文与第5点相同。 |
17 | install_type有点奇特,可能是radioselect类型有点不一样,反正要用"uniform",如果不用,选项很大,非常丑陋!前端高手请跳过。 |
22-37 | zh_ins_type就是为了识别前端的数字,来到后端如何将数字和中文匹配起来。 |
views.py 程序逻辑
04
4.1 逻辑层 views.py 处理表单
编辑views.py 导入 forms 表单
1from .forms import MysInstallForm ### mysql数据库安装
新增mys_install 请求函数。
1def mys_install(request):
2 iplist = ['192.168.117.100', '192.168.117.50', '192.168.117.60', '192.168.117.30']
3 if request.method == "POST":
4 mys_install_form = MysInstallForm(request.POST)
5 #print(mys_install_form)
6 if mys_install_form.is_valid():
7 zh_ins_tylt = mys_install_form.zh_ins_type()
8 print(zh_ins_tylt)
9 new_mys_install = mys_install_form.save(commit=False)
10 inp_ip = mys_install_form.cleaned_data['db_ipaddr']
11 install_type = mys_install_form.cleaned_data['install_type'] ### 表单需要更新进去到数据库里面
12 db_type = mys_install_form.cleaned_data['db_type']
13 inp_iplist = re.split(",| ", inp_ip)
14 print(inp_iplist)
15 if set(inp_iplist).issubset(set(iplist)):
16 new_mys_install.install_type = install_type
17 new_mys_install.db_type = db_type
18
19 ### 选项中文字符串
20 new_mys_install.zh_install_type = zh_ins_tylt[0]
21 new_mys_install.zh_db_type = zh_ins_tylt[1]
22
23 new_mys_install.save()
24 dict_Mys_Install = mys_install_form.cleaned_data
25 print(dict_Mys_Install)
26 return redirect('Dreaming:mys_tasktab') ### 提交指向任务列表
27 else:
28 # return HttpResponse("This machine is not under maintenance!!!")
29 return render(request, "Cloud/no_ipaddress.html", {'not_exist_ip': inp_ip})
30 else:
31 return HttpResponse("Sorry! Incorrect information.")
32 else:
33 mys_install_form = MysInstallForm()
34 return render(request, "Cloud/mys_install.html", {'mys_install_form': mys_install_form})
行 | |
2 | models模块也有自己IP字段,但这里为了避免更多错误尝试,先直接选用字符串代替。 |
6-7 20-21 | 检验表单之后,就将install_type和db_type的中文描述传入zh_ins_tylt数组。 |
13-15 | 将post进来的IP看看是否符合这个几个IP地址。以后改善方向可以往网段,或者定义哪些可使用和不可使用的IP地址。 |
16-17 | 在admin管理界面,使用日期排序。 |
23,26 | 表单里的所有值、install_type、db_type准备就绪后,就可以保存到数据库中,并跳转到任务列表当中。 |
27,30,34 | 各种不顺利,就让else函数去报错和返回吧! |
效果展示
05
感谢阅读!!!
——————我是安老师下期预告的分割线——————
> 最近小安Sir在系统学习mysql数据库,相信可以为python自动化运维带来更好的标准化流程,敬请期待!
> 下期主要分享:如何使用javascript代码对系统栏目进行增删改查!
注意:仅供学习参考,切勿用于商业用途,
如有需要,请购买正版!
往期回顾
Python自动化实战一 | 网页模板改造
Python切割文件教程一 | 我的“大马士革命刀"
Python切割文件教程二 | 我的“大马士革命刀"不Like补刀
Django博客教程一 | Django架构介绍
Django博客教程二 | Django入门版博客
Django博客教程三 | Django进阶版博客数据篇
Django博客教程四 | Django进阶版博客网页篇
Python
自动化运维
长按识别左侧二维码,
关注Python自动化运维喔~