一.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)
原文地址:https://www.cnblogs.com/dbslinux/p/13093158.html