表关系:
一对多:
- 应用场景:比如文章和作者之间的关系。一个文章只能由一个作者编写,但是一个作者可以写多篇文章。文章和作者之间的关系就是典型的多对一的关系。
- 实现方式:一对多或者多对一,都是通过
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='zhiliao',password='111111')
# 要先保存到数据库中
author.save()
article.author = author
article.save()
并且以后如果想要获取某个用户下所有的文章,可以通过article_set
来实现。示例代码如下:
user = User.objects.first()
# 获取第一个用户写的所有文章
articles = user.article_set.all()
for article in articles:
print(article)
并且如果想要将文章添加到某个分类中。可以使用一下的方式:
category = Category.objects.first()
article = Article(title='bbb',content='vvv')
article.author = FrontUser.objects.first()
category.article_set.add(article,bulk=False)
- 使用
bulk=False
,那么Django会自动的保存article,而不需要在添加到category之前先保存article。 - 或者是另外一种解决方式是,在添加到
category.article_set
中之前,先将article
保存到数据库中。但是如果article.category
不能为空,那么就产生一种死循环了,article没有category
不能保存,而将article添加到cateogry.artile_set
中,又需要article之前是已经存储到数据库中的。 - 如果是上面的那种需求,建议使用
bulk=False
的解决方案。
一对一:
- 在Django中一对一是通过
models.OneToOneField
来实现的。这个OneToOneField
其实本质上就是一个外键,只不过这个外键有一个唯一约束(unique key)
,来实现一对一。 - 以后如果想要反向引用,那么是通过引用的模型的名字转换为小写的形式进行访问。比如以下模型:
class FrontUser(models.Model): username = models.CharField(max_length=200) class UserExtension(models.Model): school = models.CharField(max_length=100) user = models.OneToOneField("FrontUser",on_delete=models.CASCADE) # 通过userextension来访问UserExtension对象 user = FrontUser.objects.first() print(user.userextension)
UserExtension
的对象,可以通过user
来访问到对应的user对象。并且FrontUser
对象可以使用userextension
来访问对应的UserExtension
对象。
如果不想使用Django默认的引用属性名字。那么可以在OneToOneField
中添加一个related_name
参数。示例代码如下:
那么以后就class FrontUser(models.Model): username = models.CharField(max_length=200) class UserExtension(models.Model): school = models.CharField(max_length=100) user = models.OneToOneField("FrontUser",on_delete=models.CASCADE,related_name='extension') # 通过extension来访问到UserExtension对象 user = FrontUser.objects.first() print(user.extension)
FrontUser
的对象就可以通过extension
属性来访问到对应的UserExtension
对象。
多对多:
-
应用场景:比如文章和标签的关系。一篇文章可以有多个标签,一个标签可以被多个文章所引用。因此标签和文章的关系是典型的多对多的关系。
-
实现方式:
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
两张表的主键。
网友评论