6. 通用关系查询
当编写一个tags模块, 用于记录某一项数据是否被标记了
没有必要专门为每一种类型的记录专门定义一个tags模块, 而是可以通过一个通用的tags模块来完成
即视频, 文章, 产品, 等等全部由该模块来进行标记记录, 即便这些数据分属于不同的子app
此时便可以通过generic relationships
来完成
这一功能基于django的ContentType
模块
1
2
3
4
5
INSTALLED_APPS = [
# ...
'django.contrib.contenttypes',
# ...
]
django会为所有的model生成一个唯一的content_type, 储存在django_content_type
表中
要获取特定model的content_type
1
2
3
4
5
6
7
8
from django.shortcuts import render
from django.contrib.contenttypes.models import ContentType
def index(request):
# 基于模型类直接获取其content type
content_type = ContentType.objects.get_for_model(Product)
return render(request, 'tags.html')
对应的SQL
1
2
3
4
5
6
SELECT `django_content_type`.`id`,
`django_content_type`.`app_label`,
`django_content_type`.`model`
FROM `django_content_type`
WHERE (`django_content_type`.`app_label` = 'store' AND `django_content_type`.`model` = 'product')
LIMIT 21
通过content_type
进行数据查询
1
2
3
query_set = TaggedItem.objects\
.select_related('tag')\
.filter(content_type=content_type, object_id=1)
本文由作者按照 CC BY 4.0 进行授权