• 多表操作


    基表

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

    设置基表

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

    class BaseModel(models.Model):
        is_delete = models.BooleanField(default=False)
        created_time = models.DateTimeField(auto_now_add=True)
    
    <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Meta</span>:</span>
        <span class="hljs-comment"># 基表,为抽象表,是专门用来被继承,提供公有字段的,自身不会完成数据库迁移</span>
        abstract = <span class="hljs-keyword">True</span></code></pre>
    

    外键字段属性

    前提,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:名字不能与外键名同名
  • 相关阅读:
    事件委托应用:在父控件中创建子控件,并接收值
    填充树节点
    JAVA Eclipse如何安装Swing
    JAVA Eclipse开发Android如何设置滚动条最大值最小值
    JAVA Eclipse开发Android如何让屏幕保持为竖直或水平状态
    JAVA Eclipse开发Android如何让超出界面的部分自动显示滚动条
    JAVA Eclipse开发Android程序如何自定义图标
    JAVA Eclipse开发Android程序会经常闪退是怎么回事
    JAVA Eclipse的Android文件结构是怎么样的
    JAVA Eclipse的Android的进程和生命周期是什么
  • 原文地址:https://www.cnblogs.com/jinhongquan/p/12121403.html
Copyright © 2020-2023  润新知