zoukankan      html  css  js  c++  java
  • 一.4.序列化使用之机柜资源及序列化高级用法

     环境准备:创建app

    (python36env) [vagrant@CentOS7 apps]$ cd apps/

    (python36env) [vagrant@CentOS7 apps]$ django-admin startapp cabinet

    (1)激活注册settings.py:

    'cabinet.apps.CabinetConfig'

     (2)模型cabinet/models.py

    from django.db import models
    from apps.idcs.models import Idc

    class Cabinet(models.Model):
    #关联哪个机房且(一个机房有多个机柜)且foreignkey所在的模型是多,即指向的模型是一(Idc)
    idc = models.ForeignKey(Idc, verbose_name="所在机房",on_delete=models.CASCADE)
        name = models.CharField(max_length=255)

    def __str__(self):
    return self.name
    class Meta:
    db_table = "resources_cabinet"
    ordering = ["id"]
    (python36env) [vagrant@CentOS7 devops]$ python manage.py makemigrations cabinet
    (python36env) [vagrant@CentOS7 devops]$ python manage.py migrate

    (3)写序列化cabinet/serializers.py:

    from rest_framework import serializers
    from idcs.serializers import IdcSerializer
    from .models import Cabinet
    
    class CabinetSerializer(serializers.Serializer):
        #idc是关联字段关联Idc---序列化本身也是一字段类型,这里指定序列化为它的关键字段
        idc = IdcSerializer(many=False)
        name = serializers.CharField(required=True)

    (4)写视图cabinet/views.py:

    from rest_framework import viewsets
    from .models import Cabinet
    from .serializers import CabinetSerializer
    
    
    class CabinetViewset(viewsets.ModelViewSet):
        """
        retrieve:返回指定机柜信息
         list:返回指定机柜列表
         update:更新机柜信息
         destroy:删除机柜记录
         create:创建机柜记录
         partial_update:更新部分字段
        """
        queryset = Cabinet.objects.all()
        serializer_class = CabinetSerializer

    (5)写路由urls.py:

    from cabinet.views import CabinetViewset
    
    route.register("cabinet", CabinetViewset, basename="cabinet")

    为测试给它创建条数据:

    (python36env) [vagrant@CentOS7 devops]$ python manage.py shell

    In [1]: from idcs.models import Idc

    In [2]: idc = Idc.objects.get(pk=4)

    In [3]: from cabinet.models import Cabinet

    In [4]: c = Cabinet()

    In [5]: c.idc = idc

    In [6]: c.name = "test"

    In [7]: c.save()

     二.序列化高级用法

    上述效果中可知,问题一:它把序列化类的所有字段拿过来了,其实我想要的就只是id和name,问题二:在创建数据时它要求所有的字段数据提交且是必须提交

    (1)cabinet/serializers.py中:

    from rest_framework import serializers
    from idcs.serializers import IdcSerializer
    from .models import Idc
    from .models import Cabinet
    
    class CabinetSerializer(serializers.Serializer):
        #通过主键关联的类型--且当前的这条记录对应idc中是单条记录many指定,且要指定和谁关联queryset
        idc = serializers.PrimaryKeyRelatedField(many=False, queryset=Idc.objects.all())
        name = serializers.CharField(required=True)
    
        #此方法作用是把上面字段成员属性序列化成标准字典--可自定字段即格式类型
        def to_representation(self, instance):
            idc_obj = instance.idc
            ret = super(CabinetSerializer, self).to_representation(instance)
            ret["idc"] = {
                "id": idc_obj.id,
                "name": idc_obj.name
            }
            return ret
    
        #此方法是反序列化的第一步:它拿到的是提交过来的原始数据即QueryDict => request.GET,request.POST,body
        def to_internal_value(self, data):
            return super(CabinetSerializer, self).to_internal_value(data)
    
        #create方法要把实例传进去--创建数据
        def create(self, validated_data):
            print(validated_data)
            return Cabinet.objects.create(**validated_data)

    2.若上述文件中idc字段是只读的(即不能往idc字段提交数据不能被反序列化),那么就不需要关联关系,那就用如下方法

    from rest_framework import serializers
    from idcs.serializers import IdcSerializer
    from idcs.models import Idc
    from .models import Cabinet
    
    
    class CabinetSerializer(serializers.Serializer):
    #通过主键关联的类型--且当前的这条记录对应idc中是单条记录many指定,且要指定和谁关联queryset
        idc = serializers.PrimaryKeyRelatedField(many=False, queryset=Idc.objects.all())
        name = serializers.CharField(required=True)
    
        def to_representation(self, instance):
            idc_obj = instance.idc
            ret = super(CabinetSerializer, self).to_representation(instance)
            ret["idc"] = {
                "id": idc_obj.id,
                "name": idc_obj.name
            }
            return ret
    #此方法是反序列化的第一步:它拿到的是提交过来的原始数据即QueryDict => request.GET,request.POST,body
        def to_internal_value(self, data):
            """
            反序列化第一步:拿到的是提交过来的原始数据: QueryDict => request.GET, request.POST
            """
            print(data)
            return super(CabinetSerializer, self).to_internal_value(data)
     #create方法要把实例传进去--创建数据
        def create(self, validated_data):
            return Cabinet.objects.create(**validated_data)
  • 相关阅读:
    there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause
    使用Mybatis-Generator自动生成Dao、Model、Mapping相关文件
    ActiveMQ使用示例之Queue
    JMS基本概念之一
    @ActiveMQ简单介绍以及安装
    Spring中 @Autowired注解与@Resource注解的区别
    classpath: 和classpath*:的区别
    Mybatis整合Spring
    @MyBatis主键返回
    Intellij Idea @Autowired取消提示
  • 原文地址:https://www.cnblogs.com/dbslinux/p/13093158.html
Copyright © 2011-2022 走看看