django 一对多关系

前几篇文章在记录ForeignKey时,其实已经实现一对多的关系,这篇文章来详细记录下。

应用场景:

文章和作者的关系。一篇文章只能有一个作者,但是一个作者可以有多篇文章。文章和作者的关系就是典型的多对一的关系。

实现一对多关系就是通过 ForeignKey来实现:

1、首先通过ForeignKey来关联User表中的数据(下边案例我们关联的是id为1的数据,一个user用户(可以把user理解为一个作者)可以对应多篇文章);

2、第一次关联完之后,第二次我们想再次关联User表中id为1的数据时,应该:把User表中id为1的数据先取出来,然后再次关联,详细代码如下;

# 模型
class User(models.Model):
    username = models.CharField(max_length=50)
    password = models.CharField(max_length=50)
    class Meta:
        db_table = 'User'
class Article(models.Model):
    title = models.CharField(max_length=100)
    content = models.TextField()
    author = models.ForeignKey('User', on_delete=models.CASCADE)
    class Meta:
        db_table = 'Article'
def index(res):
    # 第一次关联
    user = User(username='lxc', password='123456')
    user.save()
    article = Article(title='测试标题', content='测试内容')
    article.author = user
    article.save()
    return 'success'
def index(res):
    # 第二次关联,直接把User表中 id为1的数据取出,然后再次关联
    user = User.objects.get(pk=1)
    article = Article(title='测试1', content='测试内容1')
    article.author = user
    article.save()
    return 'success'

效果如下:

这样就形成一个一对多的关系(User表中id为1的数据,关联了2篇文章)。

 

获取一个作者下的所有的文章:

小编目前已知的有三种方式:

1、方法一

以上边案例为例,取出User表中id为1对应的所有文章数据,使用filter  过滤出author字段为User表中的id为1的数据,有点绕,但是也很好理解,User表中的id为1的作者对应在Article表中有2条数据:

from apps.test_three.models import User, Article
def index(res):
    article = Article.objects.filter(author=User.objects.get(pk=1))
    print(article)
    return 'success'

2、方法二

使用外键的表名_set  属性

这里有个小知识点,先看完代码:

def index(res):
    user = User.objects.get(pk=1)
    all_articles = user.article_set.all()
    print(all_articles) 
    # <QuerySet [<Article: Article object (1)>, <Article: Article object (3)>]>
    render(res, 'test_html.html')

在django中,如果这个模型被其它模型使用外键的方式引用,那么django会自动给这个模型添加一个属性,这个属性的名字为:引用的模型名称小写形式_set 。上边Article模型引用了User模型,所以User模型会被django添加一个属性为:article_set,返回的也是一个QuerySet,也可使用all方法获取全部文章,或者使用first获取第一篇文章。

3、方法三

如果以上两种方法都不和你胃口,还有第三种方式:

在引用字段的参数中,添加 related_name='自定义名称' 为关联名称的意思,添加完之后,如果想取User模型下的某个id对应的多篇文章,用法跟方法二一样,来体验下:

class User(models.Model):
    username = models.CharField(max_length=50)
    password = models.CharField(max_length=50)
    class Meta:
        db_table = 'User'
class Article(models.Model):
    title = models.CharField(max_length=100)
    content = models.TextField()
    author = models.ForeignKey('User', on_delete=models.CASCADE, related_name='articles') # 指定为articles
    class Meta:
        db_table = 'Article'

把User表中id为1对应的文章数据全部取出来,效果与方法二一样:

def index(res):
    user = User.objects.get(pk=1)
    all_articles = user.articles.all() # 使用关联名称 articles来取数据
    print(all_articles)
    # <QuerySet [<Article: Article object (1)>, <Article: Article object (3)>]>
    return render(res, 'test_html.html')

tips:

1、使用方法三 related_name 来自定义关联名称时,django将不在会自动给你生成一个 使用外键的表名_set  的属性了,代替它的是方法三中的自定义名称!!!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值