drf多表操作

Posted agsol

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了drf多表操作相关的知识,希望对你有一定的参考价值。

基表

基表,是抽i想表,数据迁移的时候不会创建基表,仅作为models文件中为其他表服务的虚拟基表.

设置基表

需要在基表中配置类中加abstract=True

class BaseModel(models.Model):
    is_delete = models.BooleanField(default=False)
    created_time = models.DateTimeField(auto_now_add=True)

    class Meta:
        # 基表,为抽象表,是专门用来被继承,提供公有字段的,自身不会完成数据库迁移
        abstract = True

外键字段属性

前提,db_constraint为true

on_delete属性

django1中默认on_delete是model.CASCADE级联删除

设置级联删除的数据在数据库中无法手动删除,但是可以通过orm语句删除.

设定了当被关联表被删除时,主表此外键相对应数据如何变化

设:A为主表,B为被关联表

on_delete:model.CASCADE

默认值,级联删除

一旦外键设置db_constraint,级联失效

on_delete:model.DO_MOTHING

外键不会被级联

敌不动我不动,敌动我害不动

on_delete:model.SET_DEFAULT

删除B记录,A中外键字段被设置为default,必须配合default属性使用

on_delete:model.SET_NULL

删除B记录,A中外键字段被设置null,必须配合null=True属性使用

on_delete:model.PROTECT

保护模式,使用该选项,删除的时候,会抛ProtectedError错误

on_delete:model.SET()

自定义一个值,该值当然只能是对应的实例了

**官方案例**
def get_sentinel_user():
    return get_user_model().objects.get_or_create(username='deleted')[0]

class MyModel(models.Model):
    user = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.SET(get_sentinel_user),
    )
注意:

on_delete属性只能设置在外键字段中(ForeignKey,或者OneToOneField,OneToOneField继承了ForeignKey),因为全自动ManyToManyField是通过第三章表实现,所以两表并无直接联系,可以通过半自动或手动设置关联.

设置反向查询(即从被关联表查询主表),返回queryset对象

publish = Publish.objects.filter(pk=1).first()
books = publish.books.all().first()  #type:Book
print(books.name,2)
print(type(books))
>>>
西游记 2
<class 'api.models.Book'>

设置related_name后依旧可以使用原生反向跨表查询,但是注意这个时候原表的字段已经改名为related_name="xxx"中的xxx

book = Publish.objects.filter(books__pk=1).first() #注意这里要使用books进行反向查询,原表名小写book已经无效.
print(book.name,'1')
>>>
北京 1

db_constraint属性

在外键中控制两关联表之间的联系,默认值为True表示关联,设置False表示断开关联.

class Book(BaseModel):
    name = models.CharField(max_length=64)
    price = models.DecimalField(max_digits=10, decimal_places=2)
    publish = models.ForeignKey(to='Publish', related_name='books', db_constraint=False, on_delete=models.DO_NOTHING, null=True)
    authors = models.ManyToManyField(to='Author', related_name='books', db_constraint=False)

深度查询

外键字段默认显示的是外键值(int类型),不会自动进行深度查询

深度查询方法:
  1. 子序列化:必须有子序列化类配合,不能反序列化
  2. 配置depth:自动进行关联表所有字段的深度查询,数据无法自定义
  3. 插拔式@propety:名字不能与外键名同名

以上是关于drf多表操作的主要内容,如果未能解决你的问题,请参考以下文章

drf中的序列化家族

drf 多表

drf-多表-ModelSerialize-序列化-反序列化

多对多表的增删改查与drf的分页

0018 基于DRF框架开发(多表增删改的实现)

Django DRF序列化器或视图中的多表过滤