外键关系的自动维护

  • 原始提交的server数据
  1. {
  2. ...
  3. "manufacturer": "DELL",
  4. "model_name": "R730"
  5. ...
  6. }
  • server和manufacture&productmodel的关系

  • server如何验证manufacture&productmodel 实现他两自动维护的?

字段关系的自动维护

  • 原始数据
  1. {
  2. ...
  3. "ip": "192.168.1.1",
  4. "network": [
  5. {
  6. "name": "eth0",
  7. "ips": [
  8. {
  9. "ip_addr": "10.1.1.1",
  10. "netmask": "255.255.255.0"
  11. }
  12. ],
  13. "mac_address": "00-50-56-C0-00-10"
  14. }
  15. ]
  16. ...
  17. }
  • 模型关系

  • 希望实现提交server数据,可以自动维护network表和ip表.

    并且实现数据一致.

我可能多次提交一份server数据,里面的数据不一致, 实现自动更新相关表.

  1. class ServerAutoReportSerializer(serializers.Serializer):
  2. """
  3. 服务器同步序列化类
  4. """
  5. ip = serializers.CharField(required=True)
  6. hostname = serializers.CharField(required=True, max_length=20)
  7. cpu = serializers.CharField(required=True, max_length=50)
  8. mem = serializers.CharField(required=True, max_length=20)
  9. disk = serializers.CharField(required=True, max_length=200)
  10. os = serializers.CharField(required=True, max_length=50)
  11. sn = serializers.CharField(required=True, max_length=50)
  12. manufacturer = serializers.CharField(required=True)
  13. model_name = serializers.CharField(required=True)
  14. uuid = serializers.CharField(required=True, max_length=50)
  15. # 网卡和ip模型
  16. network = serializers.JSONField(required=True)
  17. # 验证制造商
  18. def validate_manufacturer(self, value):
  19. try:
  20. manufacturer_obj = Manufacturer.objects.get(vender_name__exact=value)
  21. except Manufacturer.DoesNotExist:
  22. manufacturer_obj = Manufacturer.objects.create(vender_name=value)
  23. return manufacturer_obj
  24. # 验证型号
  25. def validate(self, attrs):
  26. manufacturer_obj = attrs['manufacturer']
  27. try:
  28. attrs['model_name'] = manufacturer_obj.productmodel_set.get(model_name__exact=attrs['model_name'])
  29. except ProductModel.DoesNotExist:
  30. attrs['model_name'] = ProductModel.objects.create(model_name=attrs['model_name'], vender=manufacturer_obj)
  31. return attrs
  32. # 验证服务器
  33. def create(self, validated_data):
  34. sn = validated_data['sn']
  35. uuid = validated_data['uuid']
  36. try:
  37. # 检测是否存在
  38. ## 虚拟机uuid
  39. ## 物理机sn
  40. if sn == uuid or sn == '' or sn.startwith('vmware'):
  41. server_obj = Server.objects.get(uuid__contains=uuid)
  42. else:
  43. server_obj = Server.objects.get(sn__contains=sn)
  44. except Server.DoesNotExist:
  45. # 不存在,则创建
  46. return self.create_server(validated_data)
  47. else:
  48. # 存在则,更新
  49. return self.update_server(server_obj, validated_data)
  50. def create_server(self, validated_data):
  51. network = validated_data.pop('network')
  52. server_obj = Server.objects.create(**validated_data)
  53. self.check_server_network_device(server_obj, network)
  54. return self.obj
  55. def check_server_network_device(self, server_obj, network):
  56. current_device_queryset = []
  57. for device in network:
  58. try:
  59. # 检测device是否存在
  60. device_obj = server_obj.networkdevice_set.get(name__exact=device['name'])
  61. except NetworkDevice.DoesNotExist:
  62. # device不存在
  63. device_obj = self.create_network_device(server_obj, device)
  64. current_device_queryset.append(device_obj)
  65. for device_obj in list(set(server_obj.networkdevice_set.all()) - set(current_device_queryset)):
  66. device_obj.delete()
  67. def update_server(self, instance, validated_data):
  68. instance.ip = validated_data.get("ip", instance.ip)
  69. instance.hostname = validated_data.get("hostname", instance.hostname)
  70. instance.cpu = validated_data.get("cpu", instance.cpu)
  71. instance.mem = validated_data.get("mem", instance.mem)
  72. instance.disk = validated_data.get("disk", instance.disk)
  73. instance.os = validated_data.get("os", instance.os)
  74. instance.save()
  75. self.check_server_network_device(instance, validated_data['network'])
  76. return instance
  77. def create_network_device(self, server_obj, device):
  78. ips = device.pop('ips')
  79. device['host'] = server_obj
  80. device_obj = NetworkDevice.objects.create(**device)
  81. self.check_ip(device_obj, ips)
  82. return device_obj
  83. def check_ip(self, device_obj, ifnets):
  84. current_ip_queryset = []
  85. for ifnet in ifnets:
  86. try:
  87. ifnet_obj = device_obj.ip_set.get(ip_addr_exact=ifnet['ip_addr'])
  88. except:
  89. ifnet_obj = self.create_ip(device_obj, ifnet)
  90. current_ip_queryset.append(ifnet_obj)
  91. for ifnet in list(set(device_obj.ip_set.all()) - set(current_ip_queryset)):
  92. ifnet.delete()
  93. def create_ip(self, network_obj, ifnet):
  94. ifnet['device'] = network_obj
  95. return IP.objects.create(**ifnet)
  96. def to_representation(self, instance):
  97. res = {
  98. 'ip': instance.ip,
  99. 'hostname': instance.hostname
  100. }
  101. return res
  • 知识点: 代码逻辑
  1. create:
  2. try:
  3. # 服务器是否存在
  4. except:
  5. # 不存在,创建服务器
  6. self.create_server()
  7. else:
  8. # 存在, 更新服务器
  9. self.update_server()
  10. def create_server():
  11. #创建服务器
  12. #检查网卡
  13. def check_network_device():
  14. #创建网卡: 定义create_network
  15. #检测ip
  16. def check_ip()
  17. #创建ip: 定义create_ip
  • 知识点: 去重思想
  1. 提交的相对现有的:
  2. 现有的比提交的多了, 删除
  3. 先有的比提交的少了, 不做操作
  4. for device_obj in list(set(server_obj.networkdevice_set.all()) - set(current_device_queryset)):
  5. device_obj.delete()

productmodel的2种更新写法

通过系统的update

需要 productmode/1 PUT这种实现. 适用于前端和用户交互.

自己实现update, 这种就post方法实现 新增+更新.

适用于后端搜集数据

创建prodcutmodel条目时 1,通过manufacture验证productmodel唯一性 2,productmodel既有字段的更新写法

  • 原始数据,第一次提交
  1. {
  2. "model_name": "mi8",
  3. "vender": "xiaomi",
  4. "nick_model_name": "xiaomi8888"
  5. }

第二次提交, 我希望更新一下nick_model_name字段

  1. {
  2. "model_name": "mi8",
  3. "vender": "xiaomi",
  4. "nick_model_name": "xiaomi"
  5. }
  1. class ProductModelSerializer(serializers.Serializer): # 必须实现create: `create()` must be implemented.
  2. model_name = serializers.CharField(max_length=20)
  3. vender = serializers.CharField(max_length=20)
  4. nick_model_name = serializers.CharField(max_length=40)
  5. # 制造商验证
  6. def validate_vender(self, value):
  7. try:
  8. # 制造商是否存在
  9. manufacturer_obj = Manufacturer.objects.get(vender_name__exact=value)
  10. except Manufacturer.DoesNotExist:
  11. manufacturer_obj = Manufacturer.objects.create(vender_name=value)
  12. return manufacturer_obj
  13. def create(self, validated_data):
  14. manufacturer_obj = validated_data['vender']
  15. try:
  16. # 型号是否存在
  17. productmodel_obj = manufacturer_obj.productmodel_set.get(model_name__exact=validated_data['model_name'])
  18. except ProductModel.DoesNotExist:
  19. # productmodel不存在: 创建
  20. productmodel_obj = self.create_productmodel(validated_data)
  21. else:
  22. # productmodel存在: 更新(这里更新这个obj的nick_model_name字段,一般外键不更新)
  23. productmodel_obj = self.update_productmodel(productmodel_obj, validated_data)
  24. return productmodel_obj
  25. def create_productmodel(self, validated_data):
  26. productmodel_obj = ProductModel.objects.create(**validated_data)
  27. return productmodel_obj
  28. def update_productmodel(self, instance, validated_data):
  29. instance.model_name = validated_data.get('model_name', instance.model_name)
  30. instance.nick_model_name = validated_data.get('nick_model_name', instance.nick_model_name)
  31. instance.save()
  32. 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. 【消灭代办】第2周 - 数组判断、开发工具、transform:matrix、Grid

    2018.11.19代办一:[数组判断] 代办描述: 怎么判断一个数组是数组呢?其实这个也是一个常考的题目 关键考点: 1.js中对象类型判断的几种方法 2.数组的知识和灵活运用 解决方案s: 篇幅过 ...

  2. http方式访问svn

    接下来做一下svn的http访问 首先,说一下,svn的http访问时依赖apache的dav_svn模块,然后赋予www-data访问权限,进行版本控制 我的服务器环境Ubuntu16.04 准备工 ...

  3. 夺冠概率|2012年蓝桥杯B组题解析第九题-fishers

    (17')夺冠概率 足球比赛具有一定程度的偶然性,弱队也有战胜强队的可能. 假设有甲.乙.丙.丁四个球队.根据他们过去比赛的成绩,得出每个队与另一个队对阵时取胜的概率表: 甲 乙 丙 丁 甲 - 0. ...

  4. hdparm命令(转)

    转自:http://man.linuxde.net/hdparm hdparm命令提供了一个命令行的接口用于读取和设置IDE或SCSI硬盘参数. 语法 hdparm(选项)(参数) 选项 -a< ...

  5. IDEA入门

    刚开始用IDEA会有很多不习惯 项目报错: Project build error: Non-resolvable parent POM for com.ks:my-springboot1:0.0.1 ...

  6. opencv中 int main(int argc,char* argv[])详解

    opencv中  int main(int argc,char* argv[])详解 argc是命令行总的参数个数     argv[]是argc个参数,其中第0个参数是程序的全名,以后的参数     ...

  7. 洛谷试炼场-简单数学问题-P1403 [AHOI2005]-因数

    洛谷试炼场-简单数学问题 P1403 [AHOI2005]约数研究 Description 科学家们在Samuel星球上的探险得到了丰富的能源储备,这使得空间站中大型计算机"Samuel I ...

  8. 深入理解无穷级数和的定义(the sum of the series)

    Given an infinite sequence (a1, a2, a3, ...), a series is informally the form of adding all those te ...

  9. lame音频编码注意的点

    1.注意每次编码的PCM数据不能太短,如果太短编码函数长期返回-1这样的错误,将导致编码器彻底失效程序奔溃的问题,经测试32000在3200下稳定,大概1/10码率是没有问题的,具体请自行查询或调试 ...

  10. php新加扩展模块

    记录下在已经编译安装的PHP上面增加扩展模块,下面以安装mbstring.so为例 1.进入PHP源码文件中的mbstring文件夹,一般都是在ext目录 cd php-5.5.29/ext/mbst ...