• [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
    
    
  • 相关阅读:
    [转帖]活用Quartus II内置模板,快速输入HDL代码、TimeQuset束缚及tcl语句等
    [笔记] FPGA的发展
    [转帖]状态机的编码
    [笔记]Altera中DDR3设计
    [笔记]Test Plan的编写 及 程序开头注释
    [HDOJ2457]DNA repair
    [HDOJ2355]The Sidewinder Sleeps Tonite
    [HDOJ2825]Wireless Password
    [HDOJ2222]Keywords Search
    [HDOJ2454]Degree Sequence of Graph G
  • 原文地址:https://www.cnblogs.com/iiiiiher/p/9921613.html
Copyright © 2020-2023  润新知