外键关系的自动维护
- 原始提交的server数据
{
...
"manufacturer": "DELL",
"model_name": "R730"
...
}
-
server和manufacture&productmodel的关系
-
server如何验证manufacture&productmodel 实现他两自动维护的?
字段关系的自动维护
- 原始数据
{
...
"ip": "192.168.1.1",
"network": [
{
"name": "eth0",
"ips": [
{
"ip_addr": "10.1.1.1",
"netmask": "255.255.255.0"
}
],
"mac_address": "00-50-56-C0-00-10"
}
]
...
}
- 模型关系
- 希望实现提交server数据,可以自动维护network表和ip表.
并且实现数据一致.
我可能多次提交一份server数据,里面的数据不一致, 实现自动更新相关表.
class ServerAutoReportSerializer(serializers.Serializer):
"""
服务器同步序列化类
"""
ip = serializers.CharField(required=True)
hostname = serializers.CharField(required=True, max_length=20)
cpu = serializers.CharField(required=True, max_length=50)
mem = serializers.CharField(required=True, max_length=20)
disk = serializers.CharField(required=True, max_length=200)
os = serializers.CharField(required=True, max_length=50)
sn = serializers.CharField(required=True, max_length=50)
manufacturer = serializers.CharField(required=True)
model_name = serializers.CharField(required=True)
uuid = serializers.CharField(required=True, max_length=50)
# 网卡和ip模型
network = serializers.JSONField(required=True)
# 验证制造商
def validate_manufacturer(self, value):
try:
manufacturer_obj = Manufacturer.objects.get(vender_name__exact=value)
except Manufacturer.DoesNotExist:
manufacturer_obj = Manufacturer.objects.create(vender_name=value)
return manufacturer_obj
# 验证型号
def validate(self, attrs):
manufacturer_obj = attrs['manufacturer']
try:
attrs['model_name'] = manufacturer_obj.productmodel_set.get(model_name__exact=attrs['model_name'])
except ProductModel.DoesNotExist:
attrs['model_name'] = ProductModel.objects.create(model_name=attrs['model_name'], vender=manufacturer_obj)
return attrs
# 验证服务器
def create(self, validated_data):
sn = validated_data['sn']
uuid = validated_data['uuid']
try:
# 检测是否存在
## 虚拟机uuid
## 物理机sn
if sn == uuid or sn == '' or sn.startwith('vmware'):
server_obj = Server.objects.get(uuid__contains=uuid)
else:
server_obj = Server.objects.get(sn__contains=sn)
except Server.DoesNotExist:
# 不存在,则创建
return self.create_server(validated_data)
else:
# 存在则,更新
return self.update_server(server_obj, validated_data)
def create_server(self, validated_data):
network = validated_data.pop('network')
server_obj = Server.objects.create(**validated_data)
self.check_server_network_device(server_obj, network)
return self.obj
def check_server_network_device(self, server_obj, network):
current_device_queryset = []
for device in network:
try:
# 检测device是否存在
device_obj = server_obj.networkdevice_set.get(name__exact=device['name'])
except NetworkDevice.DoesNotExist:
# device不存在
device_obj = self.create_network_device(server_obj, device)
current_device_queryset.append(device_obj)
for device_obj in list(set(server_obj.networkdevice_set.all()) - set(current_device_queryset)):
device_obj.delete()
def update_server(self, instance, validated_data):
instance.ip = validated_data.get("ip", instance.ip)
instance.hostname = validated_data.get("hostname", instance.hostname)
instance.cpu = validated_data.get("cpu", instance.cpu)
instance.mem = validated_data.get("mem", instance.mem)
instance.disk = validated_data.get("disk", instance.disk)
instance.os = validated_data.get("os", instance.os)
instance.save()
self.check_server_network_device(instance, validated_data['network'])
return instance
def create_network_device(self, server_obj, device):
ips = device.pop('ips')
device['host'] = server_obj
device_obj = NetworkDevice.objects.create(**device)
self.check_ip(device_obj, ips)
return device_obj
def check_ip(self, device_obj, ifnets):
current_ip_queryset = []
for ifnet in ifnets:
try:
ifnet_obj = device_obj.ip_set.get(ip_addr_exact=ifnet['ip_addr'])
except:
ifnet_obj = self.create_ip(device_obj, ifnet)
current_ip_queryset.append(ifnet_obj)
for ifnet in list(set(device_obj.ip_set.all()) - set(current_ip_queryset)):
ifnet.delete()
def create_ip(self, network_obj, ifnet):
ifnet['device'] = network_obj
return IP.objects.create(**ifnet)
def to_representation(self, instance):
res = {
'ip': instance.ip,
'hostname': instance.hostname
}
return res
- 知识点: 代码逻辑
create:
try:
# 服务器是否存在
except:
# 不存在,创建服务器
self.create_server()
else:
# 存在, 更新服务器
self.update_server()
def create_server():
#创建服务器
#检查网卡
def check_network_device():
#创建网卡: 定义create_network
#检测ip
def check_ip()
#创建ip: 定义create_ip
- 知识点: 去重思想
提交的相对现有的:
现有的比提交的多了, 删除
先有的比提交的少了, 不做操作
for device_obj in list(set(server_obj.networkdevice_set.all()) - set(current_device_queryset)):
device_obj.delete()
productmodel的2种更新写法
通过系统的update
需要 productmode/1 PUT这种实现. 适用于前端和用户交互.
自己实现update, 这种就post方法实现 新增+更新.
适用于后端搜集数据
创建prodcutmodel条目时 1,通过manufacture验证productmodel唯一性 2,productmodel既有字段的更新写法
- 原始数据,第一次提交
{
"model_name": "mi8",
"vender": "xiaomi",
"nick_model_name": "xiaomi8888"
}
第二次提交, 我希望更新一下nick_model_name字段
{
"model_name": "mi8",
"vender": "xiaomi",
"nick_model_name": "xiaomi"
}
class ProductModelSerializer(serializers.Serializer): # 必须实现create: `create()` must be implemented.
model_name = serializers.CharField(max_length=20)
vender = serializers.CharField(max_length=20)
nick_model_name = serializers.CharField(max_length=40)
# 制造商验证
def validate_vender(self, value):
try:
# 制造商是否存在
manufacturer_obj = Manufacturer.objects.get(vender_name__exact=value)
except Manufacturer.DoesNotExist:
manufacturer_obj = Manufacturer.objects.create(vender_name=value)
return manufacturer_obj
def create(self, validated_data):
manufacturer_obj = validated_data['vender']
try:
# 型号是否存在
productmodel_obj = manufacturer_obj.productmodel_set.get(model_name__exact=validated_data['model_name'])
except ProductModel.DoesNotExist:
# productmodel不存在: 创建
productmodel_obj = self.create_productmodel(validated_data)
else:
# productmodel存在: 更新(这里更新这个obj的nick_model_name字段,一般外键不更新)
productmodel_obj = self.update_productmodel(productmodel_obj, validated_data)
return productmodel_obj
def create_productmodel(self, validated_data):
productmodel_obj = ProductModel.objects.create(**validated_data)
return productmodel_obj
def update_productmodel(self, instance, validated_data):
instance.model_name = validated_data.get('model_name', instance.model_name)
instance.nick_model_name = validated_data.get('nick_model_name', instance.nick_model_name)
instance.save()
return instance