Contenttypes是一个app,将Django中的所有定义的表定义在一张表中
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', # **** # 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', "app01.apps.App01Config", "rest_framework" ]

在这个表中最开始保存着每个app的名字和模型类的小写,两者拼接就是数据库中表的名字,如app01_student
使用场景
当一张表关联多张表的时候就可以很好的发挥这个组件的作用了,下面通过一个案例来展示
假如有以下两张表

我们希望学位表和课程表中的课程都有不同时间对应的的价格,我们可以很好的想到如下方法
为课程表和学位表再各自创建一个表,实现二者的关系,虽然功能上可以实现,但会产生很多的表

我们可以可改进如下
虽然表的数量减少了,但是会产生很多的NUll字段

 我们就可以使用contenttypes 表
 
代码展示
模型类
from django.db import models
# Create your models here.
from django.db import models
from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation
from django.contrib.contenttypes.models import ContentType
class DegreeCourse(models.Model):
    """学位课程"""
    name = models.CharField(max_length=128, unique=True)
class Course(models.Model):
    """课程"""
    name = models.CharField(max_length=128, unique=True)
class PricePolicy(models.Model):
    """价格与有课程效期表"""
    content_type_id = models.ForeignKey(ContentType, on_delete=models.CASCADE)
    object_id = models.PositiveIntegerField()
    time = models.CharField(verbose_name="时间段", max_length=32)
    price = models.IntegerField(verbose_name="价格")

添加数据
def func(request):
    models.PricePolicy.objects.create(
        content_type_id=9,  # 对应着django_content_type中 degreecourse表id
        object_id=1,  # degreecourse表中的id=1的对象
        time="3个月",
        price=100,
    )
    models.PricePolicy.objects.create(
        content_type_id=8,
        object_id=2,
        time="6个月",
        price=300
    )
但是我们还需要去contenttypes表中去寻找表的id和数据行的id,我们修改代码如下
模型类
from django.db import models
# Create your models here.
from django.db import models
from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation
from django.contrib.contenttypes.models import ContentType
class DegreeCourse(models.Model):
    """学位课程"""
    name = models.CharField(max_length=128, unique=True)
class Course(models.Model):
    """课程"""
    name = models.CharField(max_length=128, unique=True)
class PricePolicy(models.Model):
    """价格与有课程效期表"""
    content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
    object_id = models.PositiveIntegerField()
    # 在数据库中不会创建该字段
    content_type_object = GenericForeignKey("content_type", "object_id")
    time = models.CharField(verbose_name="时间段", max_length=32)
    price = models.IntegerField(verbose_name="价格")
添加数据
    models.PricePolicy.objects.create(
        content_type_object=models.DegreeCourse.objects.filter(name="linux").first(),
        time="3个月",
        price=100,
    )
 
查找数据
- 正向查询
for item in models.PricePolicy.objects.all(): print(item.time, item.price, item.content_type_object,item.content_type_object.name)结果
3个月 100 DegreeCourse object (1) python全栈 6个月 300 Course object (2) Django项目 3个月 100 DegreeCourse object (3) linux
 - 反向查询
需要将模型类代码修改为
from django.db import models # Create your models here. from django.db import models from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation from django.contrib.contenttypes.models import ContentType class DegreeCourse(models.Model): """学位课程""" name = models.CharField(max_length=128, unique=True) degree_price = GenericRelation(to="PricePolicy") class Course(models.Model): """课程""" name = models.CharField(max_length=128, unique=True) course_price = GenericRelation(to="PricePolicy") class PricePolicy(models.Model): """价格与有课程效期表""" content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE) object_id = models.PositiveIntegerField() # 在数据库中不会创建该字段 content_type_object = GenericForeignKey("content_type", "object_id") time = models.CharField(verbose_name="时间段", max_length=32) price = models.IntegerField(verbose_name="价格")查询代码
obj = models.DegreeCourse.objects.filter(name="linux").first() for item in obj.degree_price.all(): print(item.price, item.time) 
contenttype组件的设计可以帮助我们很好的应景一张表关联多张表,虽然操作简单,表的数量较少,但是却牺牲了查询效率
                
            
        
浙公网安备 33010602011771号