• Django之ORM多表关系创建


    ORM模型多表逻辑创建:

    以图书和作者关系模型为例:

    models.py

    from django.db import models

    '''

    一本书只能被一个出版社出版; 一个出版社可以出版多本书;

    一个作者可以写多本书; 一个作者唯一对应自己的信息描述

    一本书可以有多个作者

    id不指定,orm自动创建字段为id的主键: id=models.AutoField(primary_key=True)

    '''

     

       

    # 出版社表

    class Publish(models.Model):

        publish_name = models.CharField(max_length=40)

        publish_addr = models.CharField(max_length=48)

      

     

    # 书籍表(与出版社多对一,与作者多对对)

    class Book(models.Model):

        book_name = models.CharField(max_length=40)

        book_price = models.DecimalField(max_digits=6, decimal_places=2)

     

        # 参数to外键指向的类(references表),to_filed外键关联条件(on字段)

        book_publisher = models.ForeignKey(to='Publish', to_field='id'# 外键多对一,默认级联删除,表中字段默认加了_id(book_publisher_id)

      

        '''

        #关联id字段,可以不写,默认就是关联主键

        # book_publisher=models.ForeignKey(to='Publish')

           

        # 关联类(表)可以不用关键字to指定,直接写默认会找到(通过字符串反射)

        # book_publisher=models.ForeignKey('Publish')   

       

        #可取消级联,前提必须设置该字段允许为空

        book_publisher = models.ForeignKey(to='Publish', to_field='id', null=True, on_delete=models.SET_NULL)

        或者直接设置:db_constraint= False也可设置不级联的效果

     

     

        '''

        author = models.ManyToManyField(to='Author'# 书籍和作者多对多,自动生成一个新表,字段有默认id,两个类名小写加_id,默认表名为:类名小写+_属性名(book_book_author,下文会讲到手动创建这张表的两种方法 

     

      

    # 作者信息表

    class AuthorDetail(models.Model):

        author_telephone = models.IntegerField(max_length=11)

        author_addr = models.CharField(max_length=48)

        author_more = models.CharField(max_length=100)

        

     

    # 作者表(与作者信息表一对一,与书籍表多对多)

    class Author(models.Model):

        author_name = models.CharField(max_length=12)

        author_birth = models.DateField()

        author_detail = models.OneToOneField('AuthorDetail',)  # 外键一对一(sql中的foreign key + unique

      

           Tool>Run manage.py Task:makemigrations-->migrate

           

    多对多关系第三张表创建:

    以上多对多关系的书籍作者信息表是在书籍中设置多对多ManyToManyField属性系统自动创建的,还有其他两种手动创建的方式:

    1)手动创建方式一

    from django.db import models

    class Book(models.Model):

        book_name = models.CharField(max_length=40)

    class Author(models.Model):

        author_name = models.CharField(max_length=40)

    # 手动创建第三张表

    class Book_Author(models.Model):

        book = models.ForeignKey(to='Book')

        author = models.ForeignKey(to='Author')

        class Meta:

            unique_together = ('book', 'author') 

     

    2)手动创建方式二(手动创建第三张表,无法使用orm提供的addremoveclearset方法,但在第三张表有额外信息是常用)

    from django.db import models

    class Book(models.Model):

        book_name = models.CharField(max_length=40)

        # ManyToManyField设置属性关联,指定第三张表

        author=models.ManyToManyField(to='Author',through='Book_Author',through_fields=('book','author'))

    class Author(models.Model):

        author_name = models.CharField(max_length=40)

    # 手动创建第三张表

    class Book_Author(models.Model):

        book=models.ForeignKey(to='Book')

        author=models.ForeignKey(to='Author')

        class Meta:

            unique_together=('book','author')

     

    3)自动创建(第三张表自动创建只含有三字段,可以使用orm提供的方法) 

    from django.db import models

    class Book(models.Model):

        book_name = models.CharField(max_length=40)

        # ManyToManyField设置属性关联,自动创建第三张表

        author=models.ManyToManyField(to='Author')

    class Author(models.Model):

        author_name = models.CharField(max_length=40)

    orm自动创建的第三张表可以直接使用orm提供的addremoveclearset方法,手动创建的第三张表不行。

     

     

    关系表创建使用的类和参数:

    1)一对一:models.OneToOneField()

    to

    设置要关联的表名(类)

    to='Author'

    to_field

    设置要关联的表字段(类属性)

    to_field='id' 

    on_delete

    ForeignKey字段级联删除(默认)

    on_delete=models.SET_NULL
    (取消级联,前提该字段null=True

     

    2)多对一:models.ForeignKey()

    to

    设置要关联的表

    to_field

    设置要关联的表的字段

    related_name

    反向操作时,使用的字段名,用于代替原反向查询时的'表名_set'

    related_query_name

    反向查询操作时,使用的连接前缀,用于替换表名

    on_delete

    当删除关联表中的数据时,当前表与其关联的行的行为

     

    3)多对多:models.ManyToManyField()

        to

    设置要关联的表

        related_name

    ForeignKey字段

        related_query_name

    ForeignKey字段。

        through

    在使用ManyToManyField字段时,Django将自动生成一张表来管理多对多的关联关系。但我们也可以手动创建第三张表来管理多对多关系,此时就需要通过through来指定第三张表的表名

        through_fields

     设置关联的字段(两张关联表的类名小写元组)

        db_table

     默认创建第三张表时,数据库中表的名称。           

     

    创建表时的元信息:

    ORM对应的类里面包含另一个Meta类(上述手动创建第三张表),而Meta类封装了一些数据库的信息。主要字段如下:

    db_table

    ORM在数据库中的表名默认是 app_类名,可以通过db_table可以重写表名。db_table = 'book_model'

    index_together

    联合索引。

    unique_together   

    联合唯一索引

    ordering 

    指定默认按什么字段排序。   ordering = ['pub_date',]    只有设置了该属性,我们查询到的结果才可以被reverse(),否则是能对排序了的结果进行反转(order_by()方法排序过的数据)

     

    关系表级联删除on_delete

    on_delete当删除关联表中的数据时,当前表与其关联的行的行为 

    models.CASCADE

    删除关联数据,与之关联也删除

    models.DO_NOTHING

    删除关联数据,引发错误IntegrityError

    models.PROTECT

    删除关联数据,引发错误ProtectedError

    models.SET_NULL

    删除关联数据,与之关联的值设置为null(前提FK字段需要设置为可空)

    models.SET_DEFAULT

    删除关联数据,与之关联的值设置为默认值(前提FK字段需要设置默认值)

    models.SET

    删除关联数据,
        a.
    与之关联的值设置为指定值,设置:models.SET()
        b.
    与之关联的值设置为可执行对象的返回值,设置:models.SET(可执行对象)

     

     

  • 相关阅读:
    去掉FALSH背景的代码
    问一个比较傻瓜的问题关于 this.TextBox1.Visible = true;
    网页防止复制 下载 另存为的JS
    [转] left join/right join/inner join操作演示
    VS2003新起项目步骤
    我专严新闻小偷之心得与大家交流
    ACCESS数据库里SQL语句的3个表联合,和SQL有很大差别
    vs2005常用快捷键
    NoSql中的CAP分类【转载】
    epoll用法【整理】
  • 原文地址:https://www.cnblogs.com/open-yang/p/11222298.html
Copyright © 2020-2023  润新知