BaseModel基表 models.py
# 基表
class BaseModel(models.Model):
is_delete = models.BooleanField(default=False) #默认不是删除,数据库中是0/1
create_time = models.DateField(auto_now_add=True)
# 作为基表的model不能在数据库中形成对应的表,设置abstract = True
class Meta:
abstract = True #声明该表只是一个抽象表不出现在数据库中
继承基表 models.py
# 书籍表
class Book(BaseModel):
name = models.CharField(max_length=64)
price = models.DecimalField(max_digits=5, decimal_places=2)
img = models.ImageField(upload_to='img', default='img/default.jpg')
# 关联出版社表
publish = models.ForeignKey(
to='Publish', # 关联publish表
db_constraint=False, #断关联(断开Book表和Publish表的关联,方便删数据,虽然断开了关联但是还能正常使用
related_name='books', # 反向查询字段:publish_obj.books就能查出当前出版社出版的所有书籍
on_delete=models.DO_NOTHING, # 设置连表操作关系
)
# 关联作者表
authors = models.ManyToManyField(
to='Author',
db_constraint=False, #断开关联
related_name='books' #反向查询字段
)
class Meta:
db_table = 'book'
verbose_name = '书籍'
verbose_name_plural = verbose_name
def __str__(self):
return self.name
# 出版社表
class Publish(BaseModel):
name = models.CharField(max_length=64)
address = models.CharField(max_length=64)
class Meta:
db_table = 'publish'
verbose_name = '出版社'
verbose_name_plural = verbose_name
def __str__(self):
return self.name
# 作者表
class Author(BaseModel):
name = models.CharField(max_length=64)
age = models.IntegerField()
class Meta:
db_table = 'author'
verbose_name = '作者'
verbose_name_plural = verbose_name
def __str__(self):
return self.name
# 作者详情表
class AuthorDetail(BaseModel):
mobile = models.CharField(max_length=11)
author = models.OneToOneField(
to='Author',
db_constraint=False,
related_name='detail',
on_delete=models.CASCADE)
class Meta:
db_table = 'author_detail'
verbose_name = '作者详情'
verbose_name_plural = verbose_name
def __str__(self):
return '%s的详情' % self.author.name
多表关系断联 db_constraint=False
1、外键位置:
一对多关系 —— 外键放在多的一方
一对一关系 —— 从逻辑正反向考虑
- 如作者表与作者详情表,作者删除级联作者详情也删除,详情删除作者依旧存在,所以建议外键在详情表中
多对多关系 —— 外键在关系表中
2、ORM正向方向连表查找:
正向:通过外键字段 eg: author_detial_obj.author
- 外键设置在作者详情表,在作者详情表中查询作者直接.author就可以
反向:通过设置反向查询related_name的值 eg: author_obj.detail
- 外键没有设置在作者表中,在作者表中通过设置反向查询.detail查询作者详情
3、连表操作关系:(外键在作者详情表中)
- 作者删除,详情级联 —— on_delete=models.CASCADE # 跟着一起删除
- 作者删除,详情置空 —— on_delete=models.SET_NULL #外键字段清空
- 作者删除,详情重置 —— on_delete=models.SET_DEFAULT
- 作者删除,详情不动 —— on_delete=models.DO_NOTHING
4、外键关联字段的参数
-
ManyToManyField不能设置on_delete
-
OneToOneField、ForeignKey必须设置on_delete
-
Django1.x系统默认级联,但是Django2.X必须手动明确
作者详情表
author = models.OneToOneField(
to='Author', #和作者表关联
db_constraint=False, #范查询,作者表直接查作者详情表的电话号码,可以直接author_obj.detail.mobile
related_name='detail', #断关联
on_delete=models.CASCADE
)
图书表
# 关联出版社表
publish = models.ForeignKey(
to='Publish', # 关联publish表
db_constraint=False, #断关联(断开Book表和Publish表的关联,方便删数据,虽然断开了关联但是还能正常使用
related_name='books', # 反向查询字段:publish_obj.books就能查出当前出版社出版的所有书籍
on_delete=models.DO_NOTHING, # 设置连表操作关系
)
# 关联作者表
authors = models.ManyToManyField(
to='Author',
db_constraint=False,
related_name='books'
)