通过以下两篇文章:
我们知道模型类之间可能存在的一种关系为一对多,即:两个模型类A
,B
分别迁移生成的数据表table_a
,table_b
,其中的记录存在这样的关系:
table_a
中的一条记录唯一关联table_b
中的一条记录;table_b
中的记录可以被table_a
中的多条记录关联。
此时,此时模型类A
简称多类,模型类B
成为一类,本文将以文章【Django入门】——通过模型类查询MySQL数据库基本操作中的案例数据如下两种查询方式:
- 通过多类(一类)对象查询一类(多类)对象;
- 通过多类(一类)查询一类(多类)。
一、模型对象关联查询
1. 多类查一类
由多类对象查询具有关联关系的一类对象时的语法为:
多类对象.关联属性
。
例如:在HeroInfo
和BookInfo
中,BookInfo
为一类,而HeroInfo
为多类,多类中有一个关联属性hero_book
,则通过HeroInfo
的对象查询对应的BookInfo
对象的方式为:
>>> from booktest.models import BookInfo, HeroInfo
>>> for hero in HeroInfo.objects.all():
... print(hero.hero_book.book_title)
...
射雕英雄传
...
天龙八部
...
笑傲江湖
...
雪山飞狐
...
2. 一类查多类
由一类对象查询具有关联关系的多类对象时的语法为:
一类对象.多类名小写_set.all()
。
例如:在HeroInfo
和BookInfo
中,BookInfo
为一类,而HeroInfo
为多类,则通过BookInfo
的对象查询对应的HeroInfo
对象的方式为:
>>> books = BookInfo.objects.all()
>>> for book in books:
... for hero in book.heroinfo_set.all():
... print(hero.hero_name)
...
郭靖
黄蓉
黄药师
...
二、模型类关联查询
1. 一类查多类
查询方式为:
一类名.objects.filter(多类名小写__多类属性名__条件名)
。
例如:要求查询图书信息表,要求查询出的图书记录所关联的英雄描述包含’八’。
>>> from booktest.models import BookInfo, HeroInfo
>>> books = BookInfo.objects.filter(heroinfo__hero_desc__contains='八')
>>> books
<QuerySet [<BookInfo: BookInfo object (1)>, <BookInfo: BookInfo object (2)>]>
>>> for book in books:
... print('英雄描述信息包含"八"的图书名称为:', book.book_title)
... for hero in book.heroinfo_set.all():
... print(hero.hero_name, '的描述信息为:', hero.hero_desc)
... print('-' * 25)
...
英雄描述信息包含"八"的图书名称为: 射雕英雄传
郭靖 的描述信息为: 降龙十八掌
黄蓉 的描述信息为: 打狗棍法
黄药师 的描述信息为: 弹指神通
欧阳锋 的描述信息为: 蛤蟆功
梅超风 的描述信息为: 九阴白骨爪
-------------------------
英雄描述信息包含"八"的图书名称为: 天龙八部
乔峰 的描述信息为: 降龙十八掌
段誉 的描述信息为: 六脉神剑
虚竹 的描述信息为: 天山六阳掌
王语嫣 的描述信息为: 神仙姐姐
-------------------------
2. 多类查一类
查询方式为:
多类名.objects.filter(关联属性__一类属性名__条件名)
。
例如:查询英雄信息数据表中所有关联书名为"天龙八部"的英雄记录。
>>> for hero in HeroInfo.objects.filter(hero_book__book_title='天龙八部'):
... print(hero.hero_name)
...
乔峰
段誉
虚竹
王语嫣
实际上,对于通过上述这种方式进行关联查询,有如下结论:
- 通过模型类实现关联查询时,要查的最终数据在哪一个数据表中,就需要通过那个数据表对应的模型类来查询;
- 写关联查询条件时,如果模型类中没有关系属性(即一类),则条件需要写对应类的小写名,如果类中有关系属性,则直接写关系属性。