zoukankan      html  css  js  c++  java
  • 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:名字不能与外键名同名
  • 相关阅读:
    第一次博客作业
    自我介绍
    第一次个人编程作业
    第一次博客作业
    第一次个人编程作业
    第一次博客作业
    Alpha冲刺
    Alpha冲刺 (2/10)
    Alpha 冲刺 (1/10)
    福大软工 · 第七次作业
  • 原文地址:https://www.cnblogs.com/agsol/p/12117089.html
Copyright © 2011-2022 走看看