drf-外键字段设置及子序列化
Posted 1012zlb
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了drf-外键字段设置及子序列化相关的知识,希望对你有一定的参考价值。
基表
- 基表只提供公有字段, 不参与数据库迁移
- 在基表下的配置类
class Meta:
中设置:abstract = True
, 表明该表为抽象表, 不参与数据库迁移
Copy# 基表
class Base(models.Model):
is_delete = models.BooleanField(default=False)
created_time = models.DateTimeField(auto_now=True)
class Meta:
# 表明该表为抽象表, 只提供公有字段, 不参与数据库迁移
abstract = True
外键字段参数
db_constraint 数据库关联#
- 断关联:
db_constraint=False
, 既数据库中不会建立外键关系, Django在代码层面上实现两表关联 - 优点
- 不会影响连表查询操作效率
- 可以提升连表增删改效率
- 易于后期数据库表的重构
- 缺点
- 数据库本身没有连表检测, 容易出现脏数据 (需要通过严格的逻辑避免, 必要时管理脏数据)
Copyclass Book(Base):
name = models.CharField(max_length=64)
price = models.DecimalField(max_digits=6, decimal_places=2)
press = models.ForeignKey(to='Press', related_name='books', db_constraint=False, on_delete=models.SET_NULL, null=True)
authors = models.ManyToManyField(to='Author', related_name='books', db_constraint=False)
class Press(Base):
name = models.CharField(max_length=64)
addr = models.CharField(max_length=64)
class Author(Base):
name = models.CharField(max_length=64)
# 逻辑不合理
# author_detail = models.OneToOneField(to='AuthorDetail')
class AuthorDetail(Base):
mobile = models.CharField(max_length=64)
author = models.OneToOneField(to=Author, related_name='detail', db_constraint=False, on_delete=models.CASCADE)
related_name: 反向查询辅助名#
Copy"""
在外键字段中设置related_name:
1.为反向查询的辅助字段名(正向查询按字段属性, 反向查询按related_name)
2.related_name可以作为字段名参加序列化类中的fields设置
"""
on_delete 级联关系#
Copy"""
A表依赖B表, b记录删除,
on_delete=models.CASCADE a记录也会被删除
on_delete=models.DO_NOTHING a记录对应外键字段不受影响
on_delete=models.SET_DEFAULT, default=1 a记录对应外键字段变为默认值
on_delete=models.SET_NULL, null=True a记录对应外键字段变为null
注:多对多外键字段不能修改级联关系, 默认是 on_delete=models.CASCADE
"""
子序列化
- 只能在序列化类中使用
- 子序列化的字段名必须是外键字段(正向反向都可以, 包括related_name)
- 子序列化字段关联多条数据时, 需要明确 many=True
- 子序列化是单向的, 原因很简单, 一个位置在上, 一个位置在下
Copyclass BookModelSerializer(serializers.ModelSerializer):
class Meta:
model = models.Book
fields = ['name']
class PressModelSerializer(serializers.ModelSerializer):
# 子序列化字段
books = BookMethodSerializer(many=True)
class Meta:
model = models.Press
fields = ['name', 'addr', 'books']
Copy# 使用子序列化的返回结果
{
"status": 0,
"msg": "ok",
"result": [
{
"name": "东方出版社",
"addr": "上海",
"books": [
{
"name": "三体"
},
{
"name": "球状闪电"
}
]
},
{
"name": "北方出版社",
"addr": "北京",
"books": [
{
"name": "今日简史"
}
]
}
]
}
-----------------------------------------------------------------------------------------------------
# 未使用子序列化的返回结果
{
"status": 0,
"msg": "ok",
"result": [
{
"name": "东方出版社",
"addr": "上海",
"books": [
1,
3
]
},
{
"name": "北方出版社",
"addr": "北京",
"books": [
2
]
}
]
}
以上是关于drf-外键字段设置及子序列化的主要内容,如果未能解决你的问题,请参考以下文章
drf序列化高级自定义只读只写序列化覆盖字段二次封装Response数据库查询优化(断关联)十大接口视图家族自动补全图片链接