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