表关系
表之间的关系都是通过外键来进行关联的。而表之间的关系
一对多
- 应用场景:比如文章和作者之间的关系。一个文章只能由一个作者编写,但是一个作者可以写多篇文章。文章和作者之间的关系就是典型的多对一的关系。
- 实现方式:一对多或者多对一,都是通过
ForeignKey
来实现的。 在多的那边设置 以文章和作者的案例进行讲解。
class User(models.Model):
username = models.CharField(max_length=20)
password = models.CharField(max_length=100)
class Article(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
author = models.ForeignKey("User",on_delete=models.CASCADE)
那么以后在给
Article
对象指定author
,就可以使用以下代码来完成:article = Article(title='abc',content='123')
author = User(username='van',password='111111')
# 要先保存到数据库中
author.save()
article.author = author
article.save()
并且以后如果想要获取某个用户下所有的文章,可以通过
article_set
来实现。article_set
这是在被引用外键的模型下Django
自动创建的一个属性,如果这个名字不喜欢,可以在引用外键函数中指定参数related_name = "xxxx"
示例代码如下:# article_set示例
user = User.objects.first()
# 获取第一个用户写的所有文章
articles = user.article_set.all()
for article in articles:
print(article)
bulk=False
# 用被引用外键的实例来保存引用外键的实例
u = User.object.first()
article = Article(title="bbb", content = "ccc")
article.author = User.objects.first()
u.article_set.add(article. bulk=False) #bulk=False
- 使用
bulk=False
,那么Django
会自动保存article,而无需article.save()
- 注意的是:
- 如果不用
bulk=False
,需要在执行add()
前先aricle.save()
,但是如果article.category
被设置为空,会造成死锁(article实例保存需要user实例,user实例的article_set添加需要article实例) - 如果是该情景,建议
bulk=False
- 如果不用
一对一
- 应用场景:比如一个用户表和一个用户信息表。在实际网站中,可能需要保存用户的许多信息,但是有些信息是不经常用的。如果把所有信息都存放到一张表中可能会影响查询效率,因此可以把用户的一些不常用的信息存放到另外一张表中我们叫做
UserExtension
。但是用户表User
和用户信息表UserExtension
就是典型的一对一了。 - 如果想要反向引用,那么是通过引用的模型的名字转换小写的形式进行访问。
实现方式:
Django
为一对一提供了一个专门的Field
叫做OneToOneField
来实现一对一操作。示例代码如下:class User(models.Model):
username = models.CharField(max_length=20)
password = models.CharField(max_length=100)
# 这里有一个全小写的userextension属性,可以在引用参数使用related_name="xxx"更改
# 可以User.userextension获得对象
class UserExtension(models.Model):
birthday = models.DateTimeField(null=True)
school = models.CharField(blank=True,max_length=50)
user = models.OneToOneField("User", on_delete=models.CASCADE)
在
UserExtension
模型上增加了一个一对一的关系映射。其实底层是在UserExtension
这个表上增加了一个user_id
,来和user
表进行关联,并且这个外键数据在表中必须是唯一的,来保证一对一。
多对多
- 应用场景:比如文章和标签的关系。一篇文章可以有多个标签,一个标签可以被多个文章所引用。因此标签和文章的关系是典型的多对多的关系。
实现方式:
Django
为这种多对多的实现提供了专门的Field
。叫做ManyToManyField
。还示例代码如下:class Article(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
tags = models.ManyToManyField("Tag",related_name="articles")
class Tag(models.Model):
name = models.CharField(max_length=50)
在数据库层面,实际上
Django
是为这种多对多的关系建立了一个中间表。这个中间表分别定义了两个外键,引用到article
和tag
两张表的主键。