外键关系的自动维护

  • 原始提交的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

[django]梳理drf知识点2的更多相关文章

  1. [django]梳理drf知识点

    要实现的功能 idc_list/ get 列出所有 post 创建一个idc idc_detail/1/ get 获取一个idc put 修改一个idc delete 删除一个idc 一般url是这样 ...

  2. Django的DRF序列化方法

    安装rest_framework -- pip install djangorestframework -- 注册rest_framework序列化 -- Python--json -- 第一版 用v ...

  3. 写写Django中DRF框架概述以及序列化器对象serializer的构造方法以及使用

    写写Django中DRF框架概述以及序列化器对象serializer的构造方法以及使用 一.了解什么是DRF DRF: Django REST framework Django REST framew ...

  4. django框架-DRF工程之权限功能

    1.相对于flask,原生而言django,DRF做的则更加的合理化,想要给予用户相应的权限,首先需要在settings中进行配置 REST_FRAMEWORK = { 'DEAFAULT_PERMI ...

  5. Django与drf 源码视图解析

    0902自我总结 Django 与drf 源码视图解析 一.原生Django CBV 源码分析:View """ 1)as_view()是入口,得到view函数地址 2) ...

  6. Django之DRF源码分析(二)---数据校验部分

    Django之DRF源码分析(二)---数据校验部分 is_valid() 源码 def is_valid(self, raise_exception=False): assert not hasat ...

  7. [django]drf知识点梳理-搜索

    什么是搜索? 譬如http://127.0.0.1:8000/User/?username=maotai-0 可以检索出想要的. 自己实现原始的搜索 重写下get_queryset方法 class U ...

  8. [django]drf知识点梳理-权限

    用户 - 权限 - 资源 (拥有) (绑定) django权限机制能够约束用户行为,控制页面的显示内容,也能使API更加安全和灵活:用好权限机制,能让系统更加强大和健壮 django权限控制 Djan ...

  9. [django]drf知识点梳理-分页

    msyql分页 limit offset https://www.cnblogs.com/iiiiiher/articles/8846194.html django自己实现分页 https://www ...

随机推荐

  1. SafetyNet Attestation API

    https://developer.android.google.cn/training/safetynet/attestation#verify-compat-check  SafetyNet At ...

  2. TestLink汉化操作

    实验环境版本 xampp-windows-x64-7.3.2-0-VC15-installer + testlink-1.9.19 汉化操作如下 打开testlink的配置文件F:\xampp\htd ...

  3. 思科交换机根据mac地址限制主机

    思科交换机可以根据客户端mac地址限制访问 查看对应IP的mac地址及vlan show arp | in 10.1.62.188 进入设置模式 configure terminal mac addr ...

  4. 单链表实现n(n≥20)的阶乘

    n(n≥20)的阶乘 基本要求 数据的表示和存储: 累积运算的中间结果和最终的计算结果的数据类型要求是整型--这是问题本身的要求. 试设计合适的存储结构,要求每个元素或结点最多存储数据的3位数值. 数 ...

  5. centos 下部署django nginx+uwsgi

    为了建立一个工作站,也是麻烦了.... 感谢该博主: https://www.cnblogs.com/levelksk/p/7921066.html 1.安装centos 后首先安装python,下载 ...

  6. Transfrom笔记

    1.在不是以左上角为缩放点进行缩放时,其实比例不能为0,因为0将导致缩放可能出现动画效果不可控,务必选取0.1等较小值来变化

  7. 通用网关接口 ruby perl web页面 文本处理 脚本语言

    小结: 1.只要可以对标准输入输出进行操作,那么无论任何语言都可以编写CGI程序. <代码的未来> 在Ruby诞生的1993年,互联网还没有现在这样普及,因此Ruby也不是一开始就面向We ...

  8. 转:SAX解析的characters方法被多次调用

    原文地址:https://blog.csdn.net/liuxiaoddd/article/details/28885177 android SAX解析的characters方法被多次调用 同理 试用 ...

  9. LeetCode 908 Smallest Range I 解题报告

    题目要求 Given an array A of integers, for each integer A[i] we may choose any x with -K <= x <= K ...

  10. vue项目中 如何让外部引入的js模块 的this值 指向vue实例

    当前是vue项目,想在tool.js(工具模块)中封装一个跳转页面的方法, goToUrl(name,query){ if(query){ if(query.addressCode){ vueObje ...