Django的ContentType
Django进行数据化迁移的时候会生成一张django_content_type表,里面记录了各个App中的模型类.
有时候我们一张表要为多张表的一条记录保存多条记录(非简单的外键关系)
比如:
有两个不同的课程表,他们之中的每个课程都有着不同的价格策略(只为介绍ContentType)
from django.db import models # 普通课程列表 class DegreeCourse(models.Model): name = models.CharField(max_length=32) .... # 会员课程列表 class Course(models.Model): name = models.CharField(max_length=32) .... class PricePolicy(models.Model): content_type = models.CharField(max_length=32) # 保存库名 object_id = models.PositiveIntegerField() # 保存课程ID period = models.CharField(max_length=32) # 区分价格的条件 price = models.FloatField() # 价格
再或者多张表都有评论区,我们把评论存储在一张表
这时就可以通过外键关联ContentType来区分表
from django.db import models from django.contrib.contenttypes.models import ContentType class DegreeCourse(models.Model): name = models.CharField(max_length=32) class Course(models.Model): name = models.CharField(max_length=32) class PricePolicy(models.Model): # 这里 content_type = models.ForeignKey(ContentType) object_id = models.PositiveIntegerField() period = models.CharField(max_length=32) price = models.FloatField()
操作表
为PricePolicy添加一条记录
# 通过课程的ID和所在表在content_type表中的ID来新增一条记录 PricePolicy.objects.create(period='10',price=9.9,object_id=1,content_type_id=8)
修改PricePolicy类来简化操作
from django.contrib.contenttypes.fields import GenericForeignKey class PricePolicy(models.Model): content_type = models.ForeignKey(ContentType) object_id = models.PositiveIntegerField() # 不在数据库中生成,只用于帮助你做数据操作,通过上面两个字段找到一条记录 content_object = GenericForeignKey('content_type', 'object_id') period = models.CharField(max_length=32) price = models.FloatField()
添加
course_obj = Course.objects.get(id=1) models.PricePolicy.objects.create(period='30', price=29.9, content_object=course_obj)
课程来查找价格
# 方式一,找到课程对象,从价格表筛选 from app01.models import * obj = Course.objects.first() PricePolicy.objects.filter(content_type__app_label=obj._meta.app_label,content_type__model=obj._meta.model_name,object_id=obj.pk) <QuerySet [<PricePolicy: PricePolicy object>, <PricePolicy: PricePolicy object>, <PricePolicy: PricePolicy object>]> # 方式二,修改课程表from django.contrib.contenttypes.fields import GenericRelation class Course(models.Model): name = models.CharField(max_length=32) # 数据库不生成,只用于链表查询 policy_list = GenericRelation("PricePolicy") # 查询 obj.policy_list.all() <QuerySet [<PricePolicy: PricePolicy object>, <PricePolicy: PricePolicy object>, <PricePolicy: PricePolicy object>]>