1. 外键关系
例子:每个 Blog 里有很多 Entry,每个 Entry 只对应一个 Blog
这时,多的方(Entry)就要设置外键到少的方(Blog)
2. 关联表的相互访问
2.1. 从 “多方” 访问
2.1.1. 访问 Entry 关联的 Blog
>>> e = Entry.objects.get(id=2)
>>> e.blog # 返回关联的Blog对象
如果要修改 e.blog 关联的对象,之后必须 save()
2.1.2. 缓存 Entry 关联的所有一对多关系
再次查询时就不用读取数据库了。
e = Entry.objects.select_related()
2.2. 从 “一方” 访问
2.2.1. 访问 Blog 对应的 Entry
>>> b = Blog.objects.get(id=1)
>>> b.entry_set.all() # entry_set
>>> b.entry_set.count() # 总数
通过 _set
访问关联对象集
2.2.2. 关联对象集的其他方法
2.2.2.1. create(**kwargs)
创建一个新的对象,将它保存并放在关联的对象集中。同时返回新创建的对象
2.2.2.2. add(obj1, obj2, …)
添加指定的模型对象到关联的对象集中
2.2.2.3. remove(obj1, obj2, …)
从关联的对象集中删除指定的模型对象
2.2.2.4. clear()
清空关联的对象集
3. 跨关系查询
3.1. 从 “多方” 查询
3.1.1. 查询 Blog id 为 3 的所有 Entry
>>> Entry.objects.filter(blog__id=3)
>>> Entry.objects.filter(blog__pk=3)
>>> Entry.objects.filter(blog=b) # 使用对象实例
>>> Entry.objects.filter(blog=b.id) # 使用实例的id
>>> Entry.objects.filter(blog=5) # 直接使用id
这五种方式都是可以的
3.1.2. 查询 Blog name 为 Beatles 的所有 Entry
Entry.objects.filter(blog__name='Beatles')
返回哪个对象,就用哪个对象的 ModelName.objects.filter()
3.2. 从 “一方” 查询
3.2.1. 查询 Entry headline 包括 Lennon 的所有 Blog
Blog.objects.filter(entry__headline__contains='Lemmon')
3.2.2. 查询 Entry headline 包括 Lennon 且 pub_date 是 2008 的所有 Blog
Blog.objects.filter(entry__headline__contains='Lennon', entry__pub_date__year=2008)
把它分为两个 filter().filter() 就成 OR 了,所以,对于 OR 最好使用Q查询
3.2.3. 查询不包含 Entry headline 包括 Lennon 的和 pub_date 是 2008年的所有 Blog
Blog.objects.exclude(entry__headline__contains='Lennon', entry__pub_date__year=2008,)
OR,太迷糊用Q查询
3.2.4. 查询不包含 Entry headline 包括 Lennon 且 pub_date 是 2008 的所有 Blog
Blog.objects.exclude(
entry=Entry.objects.filter(
headline__contains='Lennon',
pub_date__year=2008,
),
)
AND,太迷糊用 Q查询