首页 > 其他分享 >17.django中的Contenttypes

17.django中的Contenttypes

时间:2023-02-27 22:01:23浏览次数:41  
标签:name 17 models object django content Contenttypes id

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

标签:name,17,models,object,django,content,Contenttypes,id
From: https://www.cnblogs.com/victor1234/p/17162049.html

相关文章

  • 【题解】P3747 [六省联考 2017] 相逢是问候
    思维难度作为一道省选题还是有待商榷,但是代码确实挺恶心的。记一下这种有关无穷层幂嵌套(无穷幂塔)的套路。思路扩展欧拉定理+线段树。首先看到不断嵌套幂并且模数较大......
  • Django中配置文件的详细解读
    Django中配置文件的详细解读importos.pathfrompathlibimportPath#Buildpathsinsidetheprojectlikethis:BASE_DIR/'subdir'.#1.项目的根目录#/User......
  • django项目环境搭建相关
    目录1.电脑pip换源2-虚拟环境的搭建3-项目后台(luffy项目)4-luffy后台配置5-luffy数据库6-user模块User表.md1.电脑pip换源pip安装源"""1、采用国内源,加速下载模块的速......
  • django多表查询
      注意事项: 表的名称myapp_modelName,是根据模型中的元数据自动生成的,也可以覆写为别的名称 id 字段是自动添加的 对于外键字段,Django会在字段名上添加"......
  • django配置文件
    frompathlibimportPathimportosimportsys#项目根路径#我们就是要让小路飞路径作为项目根路径BASE_DIR=Path(__file__).resolve().parent.parent#项目根......
  • 16.Django的信号
    Django中的信号就是字面意思,当发送某个信号的时候,就会触发一个或者多个函数的执行,例如,当我们每次发送短信的时候,我们可能需要将验证码保存在redis中,同时需要记录在log中,此......
  • Luffy后台Django项目创建
    一、准备环境1.创建luffy项目虚拟环境mkvirtualenvluffy2.安装项目基础依赖#1.安装Djangopipinstalldjango==3.2.2#2.安装djangorestframeworkpipinstalldja......
  • Error downloading packages: glibc-2.17-326.el7_9.i686: [Errno 5]
     001、yum安装软件出现如下报错  002、其中的一个原因是python的版本造成的,即将系统默认调用的python有python2改用了python3,而yum命令兼容的python版本是python......
  • 917~920 异步提交表单,Servlet,Dao,Servlic代码实现
    异步提交表单在此使用异步提交表单是为了获取服务器响应的数据。因为我们前台使用的是html作为视图层,不能够直接从servlet相关的域对象获取值,只能通过ajax获......
  • 题解 CF1776F【Train Splitting】
    题意:有一个\(n\)点\(m\)边简单无向连通图,请用若干(至少为\(2\))种颜色对每条边染色,使得:对于每种颜色,仅由该颜色的边组成的生成子图不连通。对于每两种颜色,仅由该颜色......