ORM创建表与表之间的关系(外键)
引子:
我们先用一个案例来捋一下表与表之间的关系 然后再通过代码实现。
book书籍表:
1 水浒传 10000
2 西游记 20000
3 三国演义 30000
4 红楼梦 40000
author作者表:
1 gary 18
2 jack 20
publish出版社表:
1 新华出版社 北京
2 西方出版社 东京
authordetail作者详情表:
1 xxxxx
2 xxxxx
关系网:
1、一本书只能由一个出版社出版(占用版权) 而 一个出版社可以出多部书籍
# 所以书表和出版社表为一对多的关系 外键建议建在多的哪一方(book)
2、一本书可以由多个作者联合创作,一个作者也可以创作多本书
# 所以书籍表与作者表为多对多的关系,多对多的关系则需要另外一张表建立关系
id book_id author_id
1 2 1
2 1 1
3 1 2
4 3 2
# 即:作者1创建了两本书1 2,书1由作者1和2联合创建,作者2创建了1和3两本书
3、作者与作者详情表肯定是一对一的关系
# models.py
from django.db import models
# Create your models here.
class book(models.Model):
title = models.CharField(max_length=32,verbose_name ='书名')
price = models.DecimalField(max_digits=8,decimal_places=2,verbose_name ='价格')
# 总共8位小数点站两位
'''
外键关系:图书和出版社为一对多的关系,所以建在多的一方 外键建在书表里
'''
publish = models.ForeignKey(to='Publish')
# 注意:如果主键字段不为id的话,需要指定主键字段名(to='nid...')
'''
图书和作者是多对多的关系 外键字段建在任意一方即可 推荐建在查询频率较高的一方
'''
# 这是一个虚拟字段,主要是告诉orm这两个表是多对多的关系,让orm建立第三张关系表
authors = models.ManyToManyField(to='Author')
# 出版社表
class Publish(models.Model):
name = models.CharField(max_length=32,verbose_name ='出版社名字')
addr = models.CharField(max_length=32,verbose_name ='出版社地址')
# 作者表
class Author(models.Model):
name = models.CharField(max_length=32,verbose_name ='作者名')
age = models.IntegerField(verbose_name ='作者年龄')
'''
作者与作者详情为一对一表关系,外键建在任意一方都可以,推荐建立再查询频率高的表
'''
author_detail =models.OneToOneField(to='Authordetail')
# 作者详情表
class Authordetail(models.Model):
phone = models.BigIntegerField(verbose_name ='作者电话') # 通常情况下存储数字类型比较多的时候使用BigIntegerField
addr = models.CharField(max_length=32,verbose_name ='作者地址')
总结:
# 如果字段对应的是ForeignKey ,OneToOneField 那么orm会自动在字段后面加_id
# 如果自己加了_id 那么orm一样会继续再加一个_id
# 在django1.x版本中外键默认都是级联更新级联删除的
补充:
1、在使用to='关联表名' 创建外键的时候,如果不加''引号关联表名必须出现在上方
eg:
class User:
models.ForeignKey(to='Publish') # 这样关联表在下方不报错
models.ForeignKey(to=Publish) # 报错 这样的写法关联表必须出现在上方
class Publish:
pass
外键字段及参数补充:
1、unique = True # 可添加约束条件 唯一
# 在使用ForeignKey()创建外键字段的时候,为一对多的表关系,但是我们知道一对一的表关系就是在外键字段添加一个唯一的约束条件,那么就相当于:
ForeignKey(unique=True) === OneToOneField()
# 但是在使用这种方式创建一对一表关系的时候,orm会有一个提示信息,orm推荐你使用的是OneToOneField()的方式来创建一对一的表关系,但是前者以可以使用
2、db_index
如果db_index=True 则代表着为此字段设置索引
3、to_field
设置要关联的表的字段,(默认不写关联的就是另外一张的主键字段)
eg:
to_field='name' # 和关联表的name字段添加关联
4、on_delete
当删除关联表中的数据时,当前表与其关联的行为。 # (django1.X无需使用)
# django2.X及以上版本,需要我们自己指定外键字段的级联更新,级联删除。