CMDB_基础模型(增删改查)

栏目: Python · 发布时间: 5年前

内容简介:地址:数据注册:

一、写在前面:

先排除样式,主要是看代码逻辑!基于django_form!

1.1、设计表,在models中定义好字段;

models.py

# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models
from django import forms
# Create your models here.

##采用models方式创建一个 <资产管理> 数据库表和字段

class Disk(models.Model):
    '''磁盘'''
    path = models.CharField(max_length=64, blank=True, null=True, verbose_name='挂载路径')
    size = models.CharField(max_length=16, blank=True, null=True, verbose_name='磁盘大小/G')
    remarks = models.CharField(max_length=2048, blank=True, null=True, verbose_name='备注')
    def __str__(self):
        return self.size
    class Meta:
        verbose_name_plural = "磁盘表"



class Region(models.Model):
    name = models.CharField(max_length=64,blank=True,null=True,verbose_name='区域')
    def __str__(self):
        return self.name
    class Meta:
        verbose_name_plural = "区域表"


class Host(models.Model):
    hostname = models.CharField(max_length=64, blank=True, null=True, verbose_name='阿里云主机名')
    ecsname = models.CharField(max_length=64, blank=True, null=True, verbose_name='阿里云实例ID')
    logining = models.ManyToManyField(to='Login', blank=True, null=True, verbose_name='授权用户')
    login_port = models.CharField(max_length=16, default='22', blank=True, null=True, verbose_name='ssh登录端口')
    cpu = models.CharField(max_length=8, blank=True, null=True, verbose_name='CPU')
    mem = models.CharField(max_length=8, blank=True, null=True, verbose_name='内存/G')
    speed = models.CharField(max_length=8, blank=True, default='5', null=True, verbose_name='带宽/M')
    disks = models.ManyToManyField(to='Disk', blank=True, null=True, verbose_name='磁盘')
    network = models.CharField(max_length=32, blank=True, null=True, verbose_name='IP')
    sn = models.CharField(max_length=64, blank=True, null=True, verbose_name='sn')
    kernel = models.CharField(max_length=64, blank=True, null=True, verbose_name='系统内核')  # 内核+版本号
    source = models.ForeignKey(to='Source', blank=True, null=True, verbose_name='来源类型')
    region = models.ForeignKey(to='Region', blank=True, null=True, verbose_name='所属区域')
    state_choices = (
        (1, 'Running'),
        (2, '下线'),
        (3, '关机'),
        (4, '删除'),
        (5, '故障'),
    )
    state = models.SmallIntegerField(verbose_name='主机状态', choices=state_choices, blank=True, null=True, )

    def __str__(self):
        return self.network


    class Meta:
        verbose_name_plural = "主机表"



class Login(models.Model):
    '''登录相关'''
    login_name = models.CharField(max_length=16, default='root', verbose_name='登录用户名')
    login_pwd= models.CharField(max_length=64, blank=True, null=True, verbose_name='登录密码')
    auth=models.CharField(max_length=8,blank=True, null=True, verbose_name='具有权限')
    def __str__(self):
        return self.login_name
    class Meta:
        verbose_name_plural = "主机用户表"


class Source(models.Model):
    '''来源:阿里云、物理机(某机房等)'''
    name = models.CharField(max_length=16, blank=True, null=True, verbose_name='来源')
    def __str__(self):
        return self.name

    class Meta:
        verbose_name_plural = "主机来源表"

1.2、创建对应的表:

python manage.py makemigrations  
python manage.py migrate

并创建一个superuser:
python manage.py createsuperuser

1.3、当然为了方便,我们可以登入后台管理界面添加:

地址: http://127.0.0.1:8000/admin/

数据注册:

admin.py

# Register your models here.

from django.contrib import admin
from host import models


class host(admin.ModelAdmin):
    list_display = ['hostname', 'ecsname', 'cpu', 'mem', 'network', 'source', 'region', 'state']

class Disk(admin.ModelAdmin):
    list_display = ['path', 'size', 'remarks']

class Region(admin.ModelAdmin):
    list_display = ['name']

class Login(admin.ModelAdmin):
    list_display = ['login_name', 'auth']

class Source(admin.ModelAdmin):
    list_display = ['name']

admin.site.register(models.Host, host)
admin.site.register(models.Disk, Disk)
admin.site.register(models.Region, Region)
admin.site.register(models.Login, Login)
admin.site.register(models.Source, Source)

CMDB_基础模型(增删改查)

二、设计路由

2.1、创建了我们的应用, 就需要引用我们应用中urls.py (自己创建!)

from django.contrib import admin
from django.conf.urls import url,include

urlpatterns = [
    url('admin/', admin.site.urls),
    url(r'^host/', include('host.urls')),
]

2.2、新建一个host, 然后新建一个urls.py

from django.conf.urls import url,include
from django.contrib import admin
from host import views

urlpatterns = [
    url(r'list$', views.List.as_view()),
    url(r'edit/(\d+)/', views.Update.as_view()),
    url(r'add$', views.Add.as_view()),
    url(r'del', views.Del.as_view()),
]

2.3、利用Form表单来在前端展现数据:

这里我们创建一个跟应用app同级的目录,utils,并且创建 form_class.py:

from django.forms import fields
from django.forms import widgets
from django.forms import Form
from host import models

class HostForm(Form):
	hostname = fields.CharField(
		required=True,      #规定该字段不能为空
		# error_messages={'required': '不可以为空'},
		widget=widgets.TextInput(attrs={'class': 'form-control'})
	)

	ecsname = fields.CharField(
		required=True,
		# error_messages = {'required': '不可以为空'},
		widget = widgets.TextInput(attrs={'class': 'form-control'})
	)

	cpu = fields.CharField(
		required=True,
		# error_messages = {'required': '不可以为空', 'invalid':'输入不合法'},
		widget = widgets.TextInput(attrs={'class': 'form-control'})
	)

	mem = fields.CharField(
		required=True,
		# error_messages = {'required': '不可以为空', 'invalid':'输入不合法'},
		widget = widgets.TextInput(attrs={'class': 'form-control'})
	)

	speed = fields.CharField(
		required=True,
		# error_messages = {'required': '不可以为空', 'invalid':'输入不合法'},
		widget = widgets.TextInput(attrs={'class': 'form-control'})
	)

	network = fields.CharField(
		required=True,
		# error_messages = {'required': '不可以为空', 'invalid':'输入不合法'},
		widget = widgets.TextInput(attrs={'class': 'form-control'})
	)

	source_id = fields.ChoiceField(
		required=True,
		# error_messages = {'required': '不可以为空', 'invalid':'输入不合法'},
		choices=[],     ##下拉框
		widget = widgets.Select(attrs={'class': 'form-control'})
	)

	region_id = fields.ChoiceField(
		required=True,
		# error_messages = {'required': '不可以为空', 'invalid':'输入不合法'},
		choices=[],
		widget = widgets.Select(attrs={'class': 'form-control'})
	)

	def __init__(self, *args, **kwargs):      ##每次都默认执行初始化,保证在数据库拿到的数据是最新的;
		super(HostForm, self).__init__(*args, **kwargs)
		self.fields['source_id'].choices=models.Source.objects.values_list('id', 'name')
		self.fields['region_id'].choices=models.Region.objects.values_list('id', 'name')

注解:

每个字段默认就是required=True;

字段没有自定义error_messages的值时,默认值是英文的错误提示;自定义的error_messages值中可以有多个错误信息提示,"required"是在该字段为空是提示,"invalid"是在该字段有值,但是值无效时提示,如邮箱或IP地址不对;

widgets插件,给Form生成的标签添加class等属性

三、增删改查

views.py

from django.shortcuts import render, HttpResponse, redirect
from host import models
from django.views import View
from django.forms import Form
from django.forms import fields
from django.forms import widgets
from utils import form_class


# Create your views here.


class List(View):
	def post(self, request, *args, **kwargs):
		pass

	def get(self, request, *args, **kwargs):
		host_list = models.Host.objects.all()
		return render(request, 'host.html', locals())


class Add(View):
	def post(self, request, *args, **kwargs):
		form = form_class.HostForm(data=request.POST)
		# print(request.POST)
		if form.is_valid():
			print(form.cleaned_data)
			models.Host.objects.create(**form.cleaned_data)
			return redirect('/host/list')
		else:
			print(form.errors)
			return render(request, 'add.html', locals())

	def get(self, request, *args, **kwargs):
		form = form_class.HostForm()
		return render(request, 'add.html', locals())


class Del(View):
	def post(self, request, *args, **kwargs):
		pass

	def get(self, request, *args, **kwargs):
		get_id = int(request.GET.get('id'))
		models.Host.objects.filter(id=get_id).delete()
		return redirect('/host/list')


class Update(View):

	def post(self, request, pk):    ##request 后面的值 pk 是 url传入的值,类似于 ->url 里 host.id 
		# print(pk)
		form = form_class.HostForm(data=request.POST)      # 将前端获取的数据传入到forms.UserForm类,实例化得到一个包含字段值的表单对象form
		if form.is_valid():      ##is_valid()得到一个布尔值,即判断传入的字段值是否全部有效
			print(form.cleaned_data)
			models.Host.objects.filter(id=pk).update(**form.cleaned_data)    ##直接插入数据库,form字段必须与models中定义的一致
			return redirect('/host/list')
		else:
			print(form.errors)
			return render(request, 'edit.html', locals())

	def get(self, request, pk):
		# get_id = request.GET.get('id')
		obj = models.Host.objects.filter(id=pk).first()
		form = form_class.HostForm(
			initial={
				'hostname': obj.hostname,
				'ecsname': obj.ecsname,
				'cpu': obj.cpu,
				'mem': obj.mem,
				'speed': obj.speed,
				'network': obj.network,
				'source_id': obj.source_id,
				'region_id': obj.region_id,
			}
		)
		return render(request, 'edit.html', locals())

注解:

form.is_valid()方法得到一个布尔值,判断从前端得到表单数据是全部有效;

form.cleaned_data得到全部验证有效的数据,是一个字典类型,如:{'username': 'admin', 'ip': '1.1.1.1', 'usertype_id': '3', 'email': '555@qq.com', 'password': 'admin'},字典中的key对应UserForm类中的每个字段名;

form.errors验证有误的错误提示信息,与错误字段一一对应,如:form.errors.user可以得到user字段的全部错误信息,是一个列表类型,form.errors.user[0]得到user字段的第一个错误信息。form.errors.email[0]得到email字段的第一个错误信息;

四、前端展示

host.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>主机</title>
</head>
<body>

 <div class="container">
        <table class="table table-bordered table-hover" id="table" border="1">
            <thead>
            <tr>
                <th style="text-align: center">序 号</th>
                <th style="text-align: center">主机名</th>
                <th style="text-align: center">实例ID</th>
                <th style="text-align: center">CPU</th>
                <th style="text-align: center">内存/G</th>
                <th style="text-align: center">带宽/M</th>
                <th style="text-align: center">IP</th>
                <th style="text-align: center">来源类型</th>
                <th style="text-align: center">所属区域</th>
                <th style="text-align: center">状态</th>
                <th style="text-align: center">操 作</th>
            </tr>
            </thead>

            <tbody>
            {% for host in host_list %}
                <tr>
                    <td style="text-align: center">{{ forloop.counter }}</td>
                    <td style="text-align: center">{{ host.hostname }}</td>
                    <td style="text-align: center">{{ host.ecsname }}</td>
                    <td style="text-align: center">{{ host.cpu }}</td>
                    <td style="text-align: center">{{ host.mem }}</td>
                    <td style="text-align: center">{{ host.speed }}</td>
{#                    <td style="text-align: center"><a href="/search/?mem={{ item.mem_info }}">{{ item.mem_info }}</a>#}
{#                    </td>#}
                    <td style="text-align: center">{{ host.network }}</td>
                    <td style="text-align: center">{{ host.source.name }}</td>
                    <td style="text-align: center">{{ host.region.name }}</td>
                    <td style="text-align: center">{{ host.get_state_display }}</td>
                    <td style="text-align: center">
                        <a href="/host/del?id={{ host.id }}">删除</a> | <!--a标签是GET请求-->
                        <a href="/host/edit/{{ host.id }}">编辑</a> |
                        <a href="/host/add">增加</a>
                    </td>
                </tr>
            {% endfor %}
            </tbody>
        </table>
</body>
</html>

add.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>ADD</title>
</head>
<body>


<form class="form-horizontal" method="post" novalidate role="form">
    {% csrf_token %}
    <p id="hostname">阿里云主机:{{ form.hostname }} {{ form.errors.hostname.0 }}</p>
    <p id="ecsname">阿里云实例id:{{ form.ecsname }} {{ form.errors.ecsname.0 }}</p>
    <p id="cpu">CPU:{{ form.cpu }} {{ form.errors.cpu.0 }}</p>
    <p id="mem">内存:{{ form.mem }} {{ form.errors.mem.0 }}</p>
    <p id="speed">带宽/M:{{ form.speed }} {{ form.errors.speed.0 }}</p>
    <p id="network">IP:{{ form.network }} {{ form.errors.network.0 }}</p>
    <p id="source">来源类型:{{ form.source_id }} {{ form.errors.source_id.0 }}</p>
    <p id="region">所属区域:{{ form.region_id }} {{ form.errors.region_id.0 }}</p>

    <input type="submit" value="提 交">

</form>

</body>
</html>

edit.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<form class="form-horizontal" method="post" novalidate role="form">
    {% csrf_token %}
    <p id="hostname">阿里云主机:{{ form.hostname }} {{ form.errors.hostname.0 }}</p>
    <p id="ecsname">阿里云实例id:{{ form.ecsname }} {{ form.errors.ecsname.0 }}</p>
    <p id="cpu">CPU:{{ form.cpu }}</p>
    <p id="mem">内存:{{ form.mem }}</p>
    <p id="speed">带宽/M:{{ form.speed }}</p>
    <p id="network">IP:{{ form.network }}</p>
    <p id="source">来源类型:{{ form.source_id }}</p>
    <p id="region">所属区域:{{ form.region_id }}</p>

    <input type="submit" value="提 交">

</form>
</body>
</html>

五、前端展示测试:

数据库中数据展示:

CMDB_基础模型(增删改查)

增加数据:

CMDB_基础模型(增删改查)

修改:

CMDB_基础模型(增删改查)


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

八年级数学(华东师大版)-解题升级-解题快速反应一本通(新课标)

八年级数学(华东师大版)-解题升级-解题快速反应一本通(新课标)

孙丽敏等编 / 吉林教育出版社 / 2004-6 / 10.0

本书将与知识点、重点、难点和考点有关的典型题做全析全解,是具有解题题典性质的助学读物。但本书又优于解题题典,不仅展示解题过程,更详细地提供了解题思考过程和切入点的选择方法,教方法导引思路的功能更强。 学生要提高解题能力,必须具备两个条件:一是打好基础,二是能够运动所学知识分析问题和解决问题。本书用例题解析解说知识点、重点、难点和考点,同时提供解题思考过程,在打基础中激活能力,在解题实......一起来看看 《八年级数学(华东师大版)-解题升级-解题快速反应一本通(新课标)》 这本书的介绍吧!

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具