【Django】模型类一对多外键related_name关键字的使用

1.场景

图书馆要整理书籍,一本书里会出现多个人物,现有两个表,一个是book,一个是hero,分别记录书本 信息和人物信息。比如说《神雕侠侣》这本书里有杨过、小龙女、郭襄等人物,这是属于一(book)对多(hero)问题,我们可以把关系存在多的一方,即把外键存在hero表里

2.模型类
class BookInfo(models.Model):
    """图书信息:演示一对多,一方"""
    btitle = models.CharField(max_length=20, verbose_name='书名')
    bpub_date = models.DateField(verbose_name='发布日期')
    bread = models.IntegerField(default=0, verbose_name='阅读量')
    bcomment = models.IntegerField(default=0, verbose_name='评论量')
    is_delete = models.BooleanField(default=False, verbose_name='逻辑删除')

    class Meta:
        db_table = 'tb_books'  # 自定义数据库表名

    def __str__(self):
        return self.btitle # 输出该模型数据对象时,只输出书名


class HeroInfo(models.Model):
    """人物信息:演示一对多,多方"""
    # 确定性别字段的取值范围
    GENDER_CHOICES = ((0, 'female'),(1, 'male'))
    # 添加外键是BookInfo
    hbook = models.ForeignKey(BookInfo, on_delete=models.CASCADE, verbose_name='人物所属图书')
    hname = models.CharField(max_length=20, verbose_name='人名')
    hgender = models.SmallIntegerField(choices=GENDER_CHOICES, default=0, verbose_name='性别')
    hcomment = models.CharField(max_length=200, null=True, verbose_name='描述信息')
    is_delete = models.BooleanField(default=False, verbose_name='逻辑删除')

    class Meta:
        db_table = 'tb_heros'

    def __str__(self):
        return self.hname
2.1 由一到多(查询一本书里所有的人物)

先找到某一本书,然后根据它的模型类小写加“_set.all()”获取所有子集

b = BookInfo.objects.get(id=1)  # 找到某一本书
b.heroinfo_set.all()  # 模型类小写+“_set.all()”
2.2 由多到一(查询一个人物属于哪本书)

先找到某个人,然后直接取相应的外键字段

h = HeroInfo.objects.get(id=1)  # 找到某个人
h.hbook  # 之前定义的外键字段
3.related_name

上面的由一取多的方法是通过模型类小写加“_set”获取所有子集,我们还可以使用自定义的方法取值,即指定related_name

class BookInfo(models.Model):
	...

class HeroInfo(models.Model):
    """人物信息:演示一对多,多方"""
    # 确定性别字段的取值范围
    GENDER_CHOICES = ((0, 'female'),(1, 'male'))
    # 添加外键是BookInfo
    hbook = models.ForeignKey(BookInfo,related_name='subs' on_delete=models.CASCADE, verbose_name='人物所属图书')
	...

我们把之前的模型类加上了related_name字段,现在可以就可以使用related_name去取子集了

b = BookInfo.objects.get(id=1)  # 找到某一本书
# b.heroinfo_set.all()  # 模型类小写+“_set.all()”  原来的写法
b.subs.all()  # 模型类小写+“_set.all()”
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冰冷的希望

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值