Django REST framwork-05-序列化关系
Posted shark_西瓜甜
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Django REST framwork-05-序列化关系相关的知识,希望对你有一定的参考价值。
文章目录
示例 Model
# 资产表
class Asset(models.Model):
"""
资产信息表,所有资产公共信息(交换机,服务器,防火墙等)
"""
# objects = AssetManager()
device_type_choices = (
('1', '服务器'),
('2', '路由器'),
('3', '交换机'),
('4', '防火墙'),
)
device_status_choices = (
(1, '上架'),
(2, '在线'),
(3, '离线'),
(4, '下架'),
)
device_type_id = models.CharField(choices=device_type_choices, default='1', max_length=1)
device_status_id = models.IntegerField(choices=device_status_choices, default=1)
latest_date = models.DateField(verbose_name='更新时间', null=True, blank=True)
create_at = models.DateTimeField(verbose_name='创建时间', auto_now_add=True)
# 服务器表
class Server(models.Model):
"""服务器信息"""
asset = models.OneToOneField('Asset',
verbose_name='对应资产', null=True, blank=True,
on_delete=models.SET_NULL)
hostname = models.CharField(verbose_name='主机名', max_length=128, unique=True)
manage_ip = models.GenericIPAddressField(verbose_name='管理 IP', null=True, blank=True)
# 硬盘表
class Disk(models.Model):
"""
硬盘信息
"""
slot = models.CharField(verbose_name='插槽位', max_length=8)
model = models.CharField(verbose_name='磁盘型号', max_length=32)
capacity = models.FloatField(verbose_name='磁盘容量GB')
pd_type = models.CharField(verbose_name='接口类型', max_length=32)
server_obj = models.ForeignKey(Server, related_name='disk',
verbose_name='所属服务器', on_delete=models.CASCADE)
OneToOneField
一对一
通常情况下,会在页面上展示所有的资产信息列表。
此时往往希望点击某一个资产数据,会跳转到对应的资产信息。
这时做好的做法是使用HyperlinkedRelatedField
对关系字段进行序列化。
HyperlinkedRelatedField
可以用于使用超链接表示关系的目标。
就是说可以使用一个 URI 来表示关系目标,具体看下面的图。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6PjsIuWo-1624289203405)(evernotecid://BBD579E0-7127-4377-8E81-47BEA574FA91/appyinxiangcom/25594833/ENResource/p543)]
serializers
from rest_framework import serializers
from cmdb.models import Asset, Server
class AssetSerializer(serializers.ModelSerializer):
# 添加关系字段
server = serializers.HyperlinkedRelatedField(
many=False, read_only=True,
view_name='api:server-detail'
)
class Meta:
model = Asset
fields = ["device_type_id", "device_status_id",
"latest_date", "create_at", "server"]
class ServerSerializer(serializers.ModelSerializer):
class Meta:
model = Server
fields = ['asset','hostname', 'manage_ip',]
many=False
一对一关系时需要设置为False
, 这是默认值,但建议显示传递(易读)。
read_only=True
只用于展示,不支持修改
AssetSerializer
中添加的server
关系字段是在Server
model 中related_name
指定的用于反向查询的字段名。
view_name
必须的参数,用于路由的反解(reverse), 假如序列化的路由不是在项目的根路由中注册的,这个view_name
的值需要添加上 app 的路由名称空间的名字。例如,在 api 应用中注册路由,view_name
的值应该是 ‘api:disk-detail’
ForeignKey
多对一
嵌套关系的序列化
考虑这样一个情况, 前端页面展示了 服务器 的列表,由于关于服务器的信息太多,并且还涉及到一台服务器会有多块硬盘等。
所以在一张表的一行数据表示一台服务器的所有数据显然不太合适。
此时使用 多对一个 关系就是很好的解决方案。
那希望点击一个服务器时候,会跳转到一个专门展示服务器信息的详情页面。这个页面专门用于展示这个服务器的基本信息和硬盘、内存等信息。也就是说,需要在一个页面上展示服务器表的本身的数据,还有夸表查询到的多对一关系的数据。
此种情况就可以使用 嵌套关系的序列化
serializers
from rest_framework import serializers
from cmdb.models import Disk, Server
# 定义序列化 多方 的序列化器
class DiskSerializer(serializers.ModelSerializer):
class Meta:
model = Disk
fields = "__all__"
# 定义序列化 一方 的序列化器
class ServerSerializer(serializers.ModelSerializer):
# 对关系字段进行序列化
disk = DiskSerializer(many=True)
class Meta:
model = Server
fields = ['asset','hostname', 'manage_ip', 'disk']
many=True
用于 多对一关系
disk
是在Disk
model中使用related_name
定义的用于反向查找的字段名。
多对多
和多对一是一样的操作
以上是关于Django REST framwork-05-序列化关系的主要内容,如果未能解决你的问题,请参考以下文章
python Django Rest_Framework框架 模型类序列化器(ModelSerializer)详解(图文并茂版)
python Django Rest_Framework框架 模型类序列化器(ModelSerializer)详解(图文并茂版)
18-Django REST framework-使用Django开发REST 接口
带有 django-rest-auth 和 django-rest-knox 的 AttributeError - 令牌序列化器