表关系
表之间的关系都是通过外键来进行关联的。而表之间的关系
一对多
-
应用场景:比如文章和作者之间的关系。一个文章只能由一个作者编写,但是一个作者可以写多篇文章。文章和作者之间的关系就是典型的多对一的关系。
-
实现方式:一对多或者多对一,都是通过
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
两张表的主键。