[django]梳理drf知识点2
外键关系的自动维护
- 原始提交的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的更多相关文章
- [django]梳理drf知识点
要实现的功能 idc_list/ get 列出所有 post 创建一个idc idc_detail/1/ get 获取一个idc put 修改一个idc delete 删除一个idc 一般url是这样 ...
- Django的DRF序列化方法
安装rest_framework -- pip install djangorestframework -- 注册rest_framework序列化 -- Python--json -- 第一版 用v ...
- 写写Django中DRF框架概述以及序列化器对象serializer的构造方法以及使用
写写Django中DRF框架概述以及序列化器对象serializer的构造方法以及使用 一.了解什么是DRF DRF: Django REST framework Django REST framew ...
- django框架-DRF工程之权限功能
1.相对于flask,原生而言django,DRF做的则更加的合理化,想要给予用户相应的权限,首先需要在settings中进行配置 REST_FRAMEWORK = { 'DEAFAULT_PERMI ...
- Django与drf 源码视图解析
0902自我总结 Django 与drf 源码视图解析 一.原生Django CBV 源码分析:View """ 1)as_view()是入口,得到view函数地址 2) ...
- Django之DRF源码分析(二)---数据校验部分
Django之DRF源码分析(二)---数据校验部分 is_valid() 源码 def is_valid(self, raise_exception=False): assert not hasat ...
- [django]drf知识点梳理-搜索
什么是搜索? 譬如http://127.0.0.1:8000/User/?username=maotai-0 可以检索出想要的. 自己实现原始的搜索 重写下get_queryset方法 class U ...
- [django]drf知识点梳理-权限
用户 - 权限 - 资源 (拥有) (绑定) django权限机制能够约束用户行为,控制页面的显示内容,也能使API更加安全和灵活:用好权限机制,能让系统更加强大和健壮 django权限控制 Djan ...
- [django]drf知识点梳理-分页
msyql分页 limit offset https://www.cnblogs.com/iiiiiher/articles/8846194.html django自己实现分页 https://www ...
随机推荐
- centos6安装mysql8 shell脚本
下载mysql安装包: wget https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-8.0.11-linux-glibc2.12-x86-64.t ...
- Java基础语法<八> 继承 多态 抽象 反射
1.超类和子类 超类和子类 父类与子类 多态: 一个对象变量可以指示多种实际类型的现象称为多态 一个变量可以引用父类对象,也可以引用其子类对象,这就是多态. 不能将一个超类的引用赋给子类变量,因为调用 ...
- textarea 固定大小,滚动条,限制拖动,文字对齐
取值:$("#ID").val(); 控制大小:加width,height限制(style="width:100px;height:200px;");或row, ...
- CentOS7 下安装mysql历程
一.成功他妈的经历 背景(废话不用看):自己对Linux不是很熟悉,说难听点就是门都没有么到!基于这近年大数据之类的热闹话题,自己就想学习一下!开始下的是Minimal ISO这个版本,Vbox5虚拟 ...
- asp.net 访问页面访问统计实现
0x00.背景: 1.用户访问网站所有页面就将访问统计数加1 ,按每月存放. 2.站点并没有用到母版面来实现,所有各个页面都很独立. 3.网站是很早这前的网站,尽量省改动以前的代码.按理说我们应该做一 ...
- 浏览器下载Excel,直接打开显示乱码...
情景: 浏览器中点击下载文件有两个选项:[打开][下载] [打开]之后,提示["文件.xlsx"的文件格式和扩展名不匹配.文件可能已损坏或不安全.除非您信任其来源,否则请勿打开.是 ...
- {MySQL数据库初识}一 数据库概述 二 MySQL介绍 三 MySQL的下载安装、简单应用及目录介绍 四 root用户密码设置及忘记密码的解决方案 五 修改字符集编码 六 初识sql语句
MySQL数据库初识 MySQL数据库 本节目录 一 数据库概述 二 MySQL介绍 三 MySQL的下载安装.简单应用及目录介绍 四 root用户密码设置及忘记密码的解决方案 五 修改字符集编码 六 ...
- CH 2101 - 可达性统计 - [BFS拓扑排序+bitset状压]
题目链接:传送门 描述 给定一张N个点M条边的有向无环图,分别统计从每个点出发能够到达的点的数量.N,M≤30000. 输入格式 第一行两个整数N,M,接下来M行每行两个整数x,y,表示从x到y的一条 ...
- [No000010A]Git3/9-创建版本库
什么是版本库呢?版本库又名仓库,英文名repository,你可以简单理解成一个目录,这个目录里面的所有文件都可以被Git管理起来,每个文件的修改.删除,Git都能跟踪,以便任何时刻都可以追踪历史,或 ...
- zookeeper的Java客户端API
zookeeper作为一个分布式服务框架,主要用来解决分布式数据一致性问题,对多种语言提供了API.这里主要记录下JAVA客户端API的使用. 1.创建会话 客户端可以通过创建一个ZooKeeper实 ...