汇总对比理解Django数据库模型表关联的三种方法:OneToOneFiled()【一对一】、ForeignKey【一对多】、ManyToManyField()【多对多】
在理解本篇博文前建议大家先看一看我之前写的博文:https://blog.csdn.net/wenhao_ir/article/details/131542371从这篇博文可以对关联的整个具体的过程有个具体的了解。
在数据表进行关联操作时,Django提供了三种关联操作,即:
①使用方法 models.OneToOneField()实现一对一的关联;
②使用方法 models.ForeignKey()实现一对多的关联;
③使用方法 models.ManyToManyField()实现多对多的关联。
为了理解这三种关系,假设有下面的两个模型和四条数据。
两个模型:
Author 和 Post
四条数据:
author1 | post1 |
---|---|
author2 | post2 |
对于一对一的关联,很好理解,就是一张表中的某条数据只能与另一张表中的某条数据相关联。
示例如下:
from django.db import models
class Author(models.Model):
name = models.CharField(max_length=100)
# Other fields of the Author model
def __str__(self):
return self.name
class Post(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
# Other fields of the Post model
author = models.OneToOneField(Author, on_delete=models.CASCADE)
def __str__(self):
return self.title
在上述示例中,通过在Post中使用方法OneToOneField(),使每篇帖子都与一个作者关联。
由于是一对于的关联,所以如果 post1 关联了 author1,那么author1就不能与post2关联了。
如果此时想要让post1 关联 post2,那么可以像下面这样做:
# 解除author1与post1的关联
author1.post.delete()
# 建立author1与post2的新关联
post2 = Post(title='Another Post', content='This is another post.', author=author1)
post2.save()
同样,换一个方向来看,一旦post1与author1关联后,那么post1也不能与author2关联了。 如下图所示:
如果需要将post1
与author2
关联,需要先解除post1
与author1
的关联,然后再与author2
建立新的关联。以下是解除关联的示例代码:
# 解除post1与author1的关联
post1.author = None
post1.save()
# 建立post1与author2的新关联
post1.author = author2
post1.save()
通过将post1.author
设置为None
,我们可以解除post1
与author1
的关联。然后,我们可以将post1.author
设置为author2
,从而与author2
建立新的关联。
对于ForeignKey【一对多】的详细操作过程,我已经在博文https://blog.csdn.net/wenhao_ir/article/details/131542371中写得很清楚了。
这里重点解释什么叫“一对多”。
示例代码如下:
from django.db import models
# Create your models here.
class Author(models.Model):
name = models.CharField(max_length=100)
def __str__(self):
return self.name
class Post(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
author = models.ForeignKey(Author, on_delete=models.CASCADE)
def __str__(self):
return self.title
在上面的代码情况下,模型Post通过方法ForeignKey()关联到模型Author,Post为“一对多”中的“多”,Author为一对多”中的“一”。
在ForeignKey方法的情况下,即一对多的情况下,当post1、post2与author1关联后,就不能再与author2关联了。 如下图所示:
上面的红线表示post1、post2与author1关联,一旦post1、post2与author1关联后,就不能再与author2关联了。所以上面的两条蓝色的线我都打了叉。
也就是说一个post一旦与某个author关联,那么它就不能再与别的author关联了,但是相应的author还能与别的post关联。这就是谓的一对多的关系。
示例代码如下:
from django.db import models
class Author(models.Model):
name = models.CharField(max_length=100)
# Other fields of the Author model
def __str__(self):
return self.name
class Post(models.Model):
title = models.CharField(max_length=100)
content = models.TextField()
authors = models.ManyToManyField(Author)
# Other fields of the Post model
def __str__(self):
return self.title
在上面的两个模型中,通过下面这条语句将两个模型进行多对多的关联:
authors = models.ManyToManyField(Author)
在这种情况下,post1与author1关联后,仍可以与author2关联,即post的author可以有多个,比如这里的post1的author可以为author1与author2。
而多个post也可以与同一个author关联,即一个author可以有多个post。比如这里的post1与author1关联后,post2也还可以与author2关联,这样就实现了author1有post1和post2,即一个author可以有多个post。
通过上面的关联,就实现了一篇post可以有多个author,而一个author也可以有多个post。这就是所谓的多对多关系。如下图所示:
以下是示例代码,展示如何使用多对多关联:
# 创建两个Author对象
author1 = Author(name='John Doe')
author1.save()
author2 = Author(name='Jane Smith')
author2.save()
# 创建一个Post对象并将其与两个Author关联
post = Post(title='Hello World', content='This is my post.')
post.save()
post.authors.add(author1, author2)
# 访问与Post关联的Author
print(post.authors.all()) # 输出:[, ]
# 访问与Author关联的Post
print(author1.post_set.all()) # 输出:[]
print(author2.post_set.all()) # 输出:[]
在上面的示例中,我们创建了两个 Author
对象:author1
和 author2
。然后,我们创建了一个 Post
对象 post
,并通过 post.authors.add()
将其与两个 Author
对象关联。
通过 post.authors.all()
,我们可以访问与 post
相关联的所有 Author
对象。
同时,我们也可以通过 author1.post_set.all()
和 author2.post_set.all()
访问与 author1
和 author2
相关联的所有 Post
对象。
从上面的多对多关联的操作上我们可以看出,“多对多关联”是在模型对象创建好后,再进行关联操作,而“一对一”、“多对一”的关联操作都是在在模型对象创建时就指定关联关系。