随笔 - 111  文章 - 0 评论 - 2 阅读 - 16465
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

 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 表

 

 

 

代码展示

模型类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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="价格")

 

 

添加数据

1
2
3
4
5
6
7
8
9
10
11
12
13
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,我们修改代码如下

模型类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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="价格")

 添加数据

1
2
3
4
5
models.PricePolicy.objects.create(
    content_type_object=models.DegreeCourse.objects.filter(name="linux").first(),
    time="3个月",
    price=100,
)

 

 

 

 

查找数据

  • 正向查询
    1
    2
    for item in models.PricePolicy.objects.all():
        print(item.time, item.price, item.content_type_object,item.content_type_object.name)

    结果

    1
    2
    3
    3个月 100 DegreeCourse object (1) python全栈
    6个月 300 Course object (2) Django项目
    3个月 100 DegreeCourse object (3) linux

     

  • 反向查询
    需要将模型类代码修改为
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    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="价格")

    查询代码

    1
    2
    3
    obj = models.DegreeCourse.objects.filter(name="linux").first()
        for item in obj.degree_price.all():
            print(item.price, item.time)

     

contenttype组件的设计可以帮助我们很好的应景一张表关联多张表,虽然操作简单,表的数量较少,但是却牺牲了查询效率

posted on   阿明明  阅读(52)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
点击右上角即可分享
微信分享提示