[root@sdns DjangoProject]# cd apps/
[root@sdns apps]# django-admin startapp cabinet
INSTALLED_APPS = [
'cabinet.apps.CabinetConfig',
]
模型
from django.db import models
from idcs.models import Idc
# Create your models here.
# 机柜
class Cabinet(models.Model):
idc = models.ForeignKey(Idc,on_delete=models.CASCADE,verbose_name="所在机房",default='')
name = models.CharField("机柜名称",max_length=255)
def __str__(self):
return self.name
class Meta:
db_table= 'resources_cabinet'
ordering = ["id"]
路由
# 导入子模块的视图
from idcs.views import IdcViewSet
from users.views import UserViewSet
from cabinet.views import CabinetViewSet
# 注册
route = DefaultRouter()
route.register("idcs",IdcViewSet,basename="idcs")
route.register("users",UserViewSet,basename="users")
route.register("cabinet",CabinetViewSet,basename="cabinet")
视图
from .models import Cabinet
from .serializers import CabinetSerializer
from rest_framework import viewsets
class CabinetViewSet(viewsets.ModelViewSet):
"""
retrieve:
返回指定机柜信息
List:
返回机柜列表
Update:
更新机柜信息
destory:
删除机柜记录
create:
创建机柜记录
partial_update:
更新部分字段
"""
queryset = Cabinet.objects.all()
serializer_class = CabinetSerializer
模拟造数
>>> from idcs.models import Idc
>>> idc = Idc.objects.get(pk=4)
>>> from cabinet.models import Cabinet
>>> c = Cabinet()
>>> c.idc = idc
>>> c.name = "test"
>>> c.save()
序列化(重点)
from typing_extensions import Required
from rest_framework import serializers
from .models import Cabinet
from idcs.serializers import IdcSerializer
from idcs.models import Idc
from cabinet.models import Cabinet
class CabinetSerializer(serializers.Serializer):
#idc = IdcSerializer() # 如果这样写,序列化时,页面会将idc所有字段展示
# 主键关联,many=False表示关联的对方是一条记录也就是一对多。如果是True则是多,也就是多对多
# queryset 表示关联的内容
# 如果仅仅写成这样,它只会返回主键,此时需要用上to_representation
idc = serializers.PrimaryKeyRelatedField(many=False, queryset=Idc.objects.all())
name = serializers.CharField(required=True,)
# 重写方法,并不是所有字段都必须显示到前端,也并不是所有返回值都要反序列化到数据库。以业务为准而不是表,通过下面的方法实现
def to_representation(self, instance):
# 这个instance就是当前实例对象cabinet.models.Cabinet instance.idc: idcs.models.Idc
idc_obj = instance.idc
ret = super(CabinetSerializer, self).to_representation(instance)
# 自定义添加不存在的字段显示也是这处理
# ret["test"]="aaa"
ret["idc"] = {
"id": idc_obj.id,
"name": idc_obj.name,
}
return ret
反序列化
# 反序列化
def to_internal_value(self, data):
"""
反序列化第一个步:拿到的是提交过来的原始数据: qureydict : request.POST,request.GET 。
拿到data后,就返回到上面代码,例如name = serializers.CharField(required=True,) 进行验证。
再进行字段验证,和对象表级别验证<后面讲>。然后再到create方法
例如一共十个字段,有些字段是默认值的,就可以在这处理
"""
print(data)
return super().to_internal_value(data)
def create(self, validated_data):
#raise serializers.ValidationError("create error") # 模拟错误上传
return Cabinet.objects.create(**validated_data)
to_representation:转json(序列化)的最后一个步骤。
to_internal_value : 反序列化的第一个步骤。
如果需要处理的字段是只读不能被反序列化的字段。例如外键。 可以进行简化
# 序列化简写
name = serializers.CharField(required=True)
idc = serializers.SerializerMethodField()
def get_idc(self,obj):
print(obj)
return {
"id":obj.id,
"name":obj.name,
}
注意: 这个方法有坑,了解,因为它对应的方法不能反序列化