Django模型层之多表操作(一)

创建模型

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

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

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

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

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

Book

   id    title   price  publish    
     php     100   人民出版社  
     python  200   北京出版社   
     go      100   人民出版社  
     java    300   上海出版社  


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

Book

   id    title   price  publish    email    addr    
     php     100   人民出版社   111      北京
     python  200   北京出版社 222      北京
     go      100   人民出版社   111      北京
     java    300   上海出版社   111      上海
   
这样会有大量重复的数据,浪费空间


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


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

Book

   id    title   price     publish_id   
     php     100         1
     python  200         1
     go      100         2  
     java    300         1


Publish

    id    name       email    addr    
   人民出版社   111      北京       
   上海出版社   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    
     php     100         1               
     python  200         1
     go      100         2  
     java    300         1



Author
         id  name  age   addr
   alex  34   beijing
   egon  55   nanjing



Book2Author

    id    book_id  author_id
      2         1
      2         2
      3         2

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


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

select id from Author where name='Alex'

select book_id from Book2Author where  author_id=1

select title from Book where id =book_id

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


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

Author
         id  name  age     ad_id(UNIQUE) 
   alex  34       1     
   egon  55       2     


AuthorDetail

   id    addr      gender    tel   gf_name   author_id(UNIQUE)
  beijing    male      110   小花           1
  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)
)

分析如下

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

2、在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.png

注意事项:

  • 表的名称myapp_modelName,是根据 模型中的元数据自动生成的,也可以覆写为别的名称

  • id字段是自动添加的

  • 对于外键字段,Django 会在字段名上添加"_id" 来创建数据库中的列名
    这个例子中的CREATE TABLE SQL 语句使用PostgreSQL 语法格式,要注意的是Django 会根据settings 中指定的数据库类型来使用相应的SQL 语句。

  • 定义好模型之后,你需要告诉Django 使用这些模型。你要做的就是修改配置文件中的INSTALL_APPSZ中设置,在其中添加models.py所在应用的名称。
    外键字段 ForeignKey 有一个 null=True 的设置(它允许外键接受空值 NULL),你可以赋给它空值 None 。

你可能感兴趣的:(Django模型层之多表操作(一))