Django2.0-db(5)-表关系

表关系

表之间的关系都是通过外键来进行关联的。而表之间的关系

一对多

  1. 应用场景:比如文章和作者之间的关系。一个文章只能由一个作者编写,但是一个作者可以写多篇文章。文章和作者之间的关系就是典型的多对一的关系。

  2. 实现方式:一对多或者多对一,都是通过ForeignKey来实现的。 在多的那边设置

  3. 以文章和作者的案例进行讲解。

     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

一对一

  1. 应用场景:比如一个用户表和一个用户信息表。在实际网站中,可能需要保存用户的许多信息,但是有些信息是不经常用的。如果把所有信息都存放到一张表中可能会影响查询效率,因此可以把用户的一些不常用的信息存放到另外一张表中我们叫做UserExtension。但是用户表User和用户信息表UserExtension就是典型的一对一了。

  2. 如果想要反向引用,那么是通过引用的模型的名字转换小写的形式进行访问。

  3. 实现方式: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表进行关联,并且这个外键数据在表中必须是唯一的,来保证一对一。

多对多

  1. 应用场景:比如文章和标签的关系。一篇文章可以有多个标签,一个标签可以被多个文章所引用。因此标签和文章的关系是典型的多对多的关系。

  2. 实现方式: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是为这种多对多的关系建立了一个中间表。这个中间表分别定义了两个外键,引用到articletag 两张表的主键。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值