• django之contenttype


    1、contenttype:在django中将models.py文件的表结构写好后,通过makemigrations和migrate两条命令进行数据库迁移后,在数据库中会自动生成一个django_content_type表。

    2、contenttype表的字段:

    id:id;

    app_label:新的model所对应的app应用名称;

    model:model的名称   即app应用中的model.py所对应的新增的表结构(类名)。

    3、contenttype表的作用:每当我们创建了一个新的model并执行数据库迁移后,ContentType表中就会自动新增一条记录。比如我在应用api的models.py中创建表class Course(models.Model): pass。从数据库查看ContentType表会相应的增加一条数据 id:--, app_label:api, model:course。

    4、应用场景:当出现一张表的数据要与多张表的数据关联的时候使用,

      示例:现有两种课程(按不同标准收费的课程),每种课程对应多种收费方式,首先想到的是创建一张课程表,然后创建一张收费标准表让他们相关联,这种方法可行但存在缺陷;

    表单创建:

    from django.db import models
    
    
    # 课程种类  轻课和学位课
    class Course(models.Model):
        id = models.AutoField(primary_key=True)
        name = models.CharField(max_length=32)
        course_type = models.CharField(max_length=32, default='轻课')
    
    
    class PricePolicy(models.Model):
        id = models.AutoField(primary_key=True)
        # 轻课的授课周期  不同周期收费不同
        period = models.CharField(max_length=32, null=True)
        # 学位课的授课方式  面授和网课收费不同
        degree_type = models.CharField(max_length=32, null=True)
        price = models.DecimalField(max_digits=8, decimal_places=2)
        course = models.ForeignKey(to=Course)
    View Code

    数据插入:

    import os
    if __name__ == '__main__':
        from django.core.wsgi import get_wsgi_application
    
        os.environ.setdefault("DJANGO_SETTINGS_MODULE", "luffy_bac.settings")
    
        application = get_wsgi_application()
    
        from api import models
    
        c1 = models.Course.objects.create(name='django', course_type='轻课')
        c2 = models.Course.objects.create(name='linux', course_type='轻课')
        c3 = models.Course.objects.create(name='python', course_type='学位课')
        c4 = models.Course.objects.create(name='go', course_type='学位课')
    
        models.PricePolicy.objects.create(period='10', price=19.9, course=c1)
        models.PricePolicy.objects.create(period='20', price=29.9, course=c1)
        models.PricePolicy.objects.create(period='30', price=49.9, course=c1)
        models.PricePolicy.objects.create(period='10', price=19.9, course=c2)
        models.PricePolicy.objects.create(period='20', price=69.9, course=c2)
        models.PricePolicy.objects.create(period='30', price=79.9, course=c2)
        models.PricePolicy.objects.create(degree_type='面授', price=28888.8, course=c3)
        models.PricePolicy.objects.create(degree_type='网课', price=18888.8, course=c3)
        models.PricePolicy.objects.create(degree_type='面授', price=20000.2, course=c4)
        models.PricePolicy.objects.create(degree_type='网课', price=10000.2, course=c4)
    View Code

     api_course                                                                       

         

    api_pricepolicy 

                       

    查询:

    # 查询django课程信息的所有价格策略
        course = models.Course.objects.get(pk=1)
        # policy_list 就是django这门课所有的价格策略对象
        policy_list = course.pricepolicy_set.all()
        for policy in policy_list:
            print(policy.price)
    View Code

    不难发现此种建标方案当出现需要添加新的课程类配合新的收费标准时,需要在pricepolicy中增加新的字段,需要修改表结构。

    ---》使用contenttype可以避免:

     eg:表单的创建

    from django.db import models
    from django.contrib.contenttypes.models import ContentType
    from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation
    class Course(models.Model):
    
        id=models.AutoField(primary_key=True)
        name=models.CharField(max_length=32)
    
        #其他字段
    
        # 不会在数据库中生成字段,只用于数据库操作
        policy = GenericRelation(to='PricePolicy')
    
    
    class DegreeCourse(models.Model):
    
        id=models.AutoField(primary_key=True)
        name=models.CharField(max_length=32)
        # 它自己的字段
        policy = GenericRelation(to='PricePolicy')
    
    
    class LiteCourse(models.Model):
    
        id=models.AutoField(primary_key=True)
        name=models.CharField(max_length=32)
        # 它自己的字段
        policy = GenericRelation(to='PricePolicy')
    
    
    class PricePolicy(models.Model):
        id=models.AutoField(primary_key=True)
        period=models.IntegerField()
        price=models.DecimalField(max_digits=8,decimal_places=2)
    
        object_id=models.IntegerField()
    
        # table_id=models.IntegerField()
        #不要加引号
        content_type=models.ForeignKey(to=ContentType,null=True)
    
    
        # 引入一个字段,不会在数据库中创建,只用来做数据库操作
        # content_obj = GenericForeignKey('content_type','object_id')
        content_obj = GenericForeignKey()
    
    
    
        # 为django免费课,添加三个价格策略
    View Code

     查询操作:

    import os
    
    if __name__ == '__main__':
        os.environ.setdefault("DJANGO_SETTINGS_MODULE", "luffy_city.settings")
        import django
    
        django.setup()
    
        from api import models
        from django.contrib.contenttypes import models as co_model
    
        # contenttype提供的快速插入的方法
        #
        # course = models.Course.objects.get(pk=1)
        # ret=models.PricePolicy.objects.create(period=30, price=199.9,content_obj=course)
    
        #为学位课,添加一个价格策略
        # degree_course=models.DegreeCourse.objects.get(pk=1)
        # ret = models.PricePolicy.objects.create(period=180, price=28888, content_obj=degree_course)
    
        # 查询所有价格策略,并且显示对应的课程名称
        # price_policy_list=models.PricePolicy.objects.all()
        # for price_policy in price_policy_list:
        #     print(type(price_policy.content_obj))
        #     print(price_policy.content_obj.name)
    
        # 查询django课程信息的所有价格策略
        # course=models.Course.objects.get(pk=1)
        # #policy_list 就是django这门课所有的价格策略对象
        # policy_list=course.policy.all()
        # for policy in policy_list:
        #     print(policy.price)
    
        # 查询python全栈开发的所有价格策略
        # degree_course=models.DegreeCourse.objects.get(pk=1)
        # policy_list=degree_course.policy.all()
        # for policy in policy_list:
        #     print(policy.price)
    View Code
  • 相关阅读:
    vs错误集合及解决方案
    使用内存映射文件进行EXE、DLL通信(非MFC)
    visual studio使用小技巧(以vs2012为例)
    GetModuleHandle(NULL)获取当前DLL模块基址?
    格式化输出中的%s和%S的陷阱
    关于字符编码
    远程附加调试服务的方法
    结构体内包含位段,其数据内存分布
    微信个人公众号开发-java
    Docker-常用基建的安装与部署
  • 原文地址:https://www.cnblogs.com/peng-zhao/p/10651561.html
Copyright © 2020-2023  润新知