06 Django-orm-多表操作

一 创建模型

实例:我们来假定下面这些概念,字段和关系

作者模型:一个作者有姓名和年龄。

作者详细模型:把作者的详情放到详情表,包含生日,手机号,家庭住址等信息。作者详情模型和作者模型之间是一对一的关系(one-to-one)

出版商模型:出版商有名称,所在城市以及email。

书籍模型: 书籍有书名和出版日期,一本书可能会有多个作者,一个作者也可以写多本书,所以作者和书籍的关系就是多对多的关联关系(many-to-many);一本书只应该由一个出版商出版,所以出版商和书籍是一对多关联关系(one-to-many)。

Book

   id    title   price  publish    

   1      php     100   人民出版社  
   2      python  200   老男孩出版社   
   3      go      100   人民出版社  
   4      java    300   人民出版社  


为了存储出版社的邮箱,地址,在第一个表后面加字段

Book

   id    title   price  publish    email    addr    

   1      php     100   人民出版社   111      北京
   2      python  200   老男孩出版社 222      上海
   3      go      100   人民出版社   111      北京
   4      java    300   人民出版社   111      北京
   
这样会有大量重复的数据,浪费空间

####################################################################################

一对多:一个出版社对应多本书(关联信息建在多的一方,也就是book表中)

Book

   id    title   price     publish_id   


   1      php     100         1
   2      python  200         1
   3      go      100         2  
   4      java    300         1


Publish

    id    name       email    addr    
     1    人民出版社   111      北京       
     2    沙河出版社   222      沙河



总结:一旦确定表关系是一对多:在多对应的表中创建关联字段(在多的表里创建关联字段)  ,publish_id


查询python这本书的出版社的邮箱(子查询)

   select publish_id from Book where title=“python”
   select email from Publish where id=1


####################################################################################


多对多:一本书有多个作者,一个作者出多本书

Book

   id    title   price     publish_id    


   1      php     100         1               
   2      python  200         1
   3      go      100         2  
   4      java    300         1



Author
         id  name  age   addr

         1    alex  34   beijing
         2    egon  55   nanjing



Book2Author

    id    book_id  author_id
     1       2         1
     2       2         2

     3       3         2

总结:一旦确定表关系是多对多:创建第三张关系表(创建中间表,中间表就三个字段,自己的id,书籍id和作者id) :
          
          id      book_id   author_id


# lqz出版过的书籍名称(子查询)

select id from Author where name='lqz'

select book_id from Book2Author where  author_id=1

select title from Book where id =book_id

####################################################################################


一对一:对作者详细信息的扩展(作者表和作者详情表)

Author
         id  name  age     ad_id(UNIQUE) 

         1    lqz  34       1     
         2    egon  55       2     


AuthorDetail

   id    addr      gender    tel   gf_name   author_id(UNIQUE)
    1   beijing    male      110   小花           1
    2   nanjing    male      911   杠娘           2


总结: 一旦确定是一对一的关系:在两张表中的任意一张表中建立关联字段+Unique


====================================


Publish  
Book
Author
AuthorDetail
Book2Author



CREATE TABLE publish(
                id INT PRIMARY KEY auto_increment ,
                name VARCHAR (20)
              );


CREATE TABLE book(
                id INT PRIMARY KEY auto_increment ,
                title VARCHAR (20),
                price DECIMAL (8,2),
                pub_date DATE ,
                publish_id INT ,
                FOREIGN KEY (publish_id) REFERENCES publish(id)
              );


CREATE TABLE authordetail(
                id INT PRIMARY KEY auto_increment ,
                tel VARCHAR (20)
              );

CREATE TABLE author(
                id INT PRIMARY KEY auto_increment ,
                name VARCHAR (20),
                age INT,
                authordetail_id INT UNIQUE ,
                FOREIGN KEY (authordetail_id) REFERENCES authordetail(id)
              );



CREATE  TABLE book2author(
       id INT PRIMARY KEY auto_increment ,
       book_id INT ,
       author_id INT ,
       FOREIGN KEY (book_id) REFERENCES book(id),
       FOREIGN KEY (author_id) REFERENCES author(id)
)

注意:关联字段与外键约束没有必然的联系(建管理字段是为了进行查询,建约束是为了不出现脏数据)

在Models创建如下模型

class Book(models.Model):
    nid = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=5, decimal_places=2)
    publish_date = models.DateField()
    # 阅读数
    # reat_num=models.IntegerField(default=0)
    # 评论数
    # commit_num=models.IntegerField(default=0)

    publish = models.ForeignKey(to='Publish',to_field='nid',on_delete=models.CASCADE)
    authors=models.ManyToManyField(to='Author')
    def __str__(self):
        return self.name


class Author(models.Model):
    nid = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    age = models.IntegerField()
    author_detail = models.OneToOneField(to='AuthorDatail',to_field='nid',unique=True,on_delete=models.CASCADE)


class AuthorDatail(models.Model):
    nid = models.AutoField(primary_key=True)
    telephone = models.BigIntegerField()
    birthday = models.DateField()
    addr = models.CharField(max_length=64)


class Publish(models.Model):
    nid = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    city = models.CharField(max_length=32)
    email = models.EmailField()

生成的表如下:

image-20200928222403872

注意事项:

  • 表的名称myapp_modelName,是根据 模型中的元数据自动生成的,也可以覆写为别的名称  
  • id 字段是自动添加的
  • 对于外键字段,Django 会在字段名上添加"_id" 来创建数据库中的列名
  • 这个例子中的CREATE TABLE SQL 语句使用PostgreSQL 语法格式,要注意的是Django 会根据settings 中指定的数据库类型来使用相应的SQL 语句。
  • 定义好模型之后,你需要告诉Django _使用_这些模型。你要做的就是修改配置文件中的INSTALL_APPSZ中设置,在其中添加models.py<
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值