zoukankan      html  css  js  c++  java
  • Django的ContentType框架django_conent_type

    Django包含了一个conenttype应用程序,记录了Django项目中安装的所有模型,为当前项目所有基于Django驱动的model提供了更高层次的抽象接口。

    一、概述

    ContentTypes应用程序的核心是 django.contrib.contenttypes.models.ContentType:

    @python_2_unicode_compatible
    class ContentType(models.Model):
        app_label = models.CharField(max_length=100)
        model = models.CharField(_('python model class name'), max_length=100)
        objects = ContentTypeManager()
    
        class Meta:
            verbose_name = _('content type')
            verbose_name_plural = _('content types')
            db_table = 'django_content_type'
            unique_together = (('app_label', 'model'),)
    
        def __str__(self):
            return self.name

    当我们不创建任何model的情况下就迁移数据库,就会发现在数据表中有名为django_content_type的表

    二、安装ContentTypes框架

     默认会在setting.py的INSTALL_APP中,如果不小心删除,可通过以下命令生成:

    django-admin startprojectINSTALLED_APPS
    django.contrib.contenttypes'INSTALLED_APPS

    三、ContentType模型

    每个实例ContentType都有两个字段,它们唯一地描述了已安装的模型:

    app_label:模型所属的应用程序名

    model:模型类的名称

    name:人类可读的内容类型名称,这取自verbose_name模型的属性

    四、ContentType的应用

    这里提供一个场景,比如网上商城,会有各种各样的优惠券,比如通用优惠券,在数据库中,我们通过外键将优惠券和不同品类的商品表关联起来。

        id          name                 学位课程        专题课程
        1        通用优惠券                 null             null
        2        JavaEE限时免费              1               null
        3        人工智能优惠券              null              1
        4        Python全栈优惠券            2               null
        5        Flask源码解读              null              3    

    这样做的弊端就是:

    1. 随着课程的不断增加, 优惠券表中 字段会不断的增加
    2. 对于每一个优惠券字段,不相关的都为null,消耗空间资源

     通过使用ContentTypes应用中提供的特殊字段GeniricForeignKey.我们可以很好的解决这个问题

    django_content_type:

    id     app_label        model
    1 admin logentry
    2 auth permission
    3 auth group
    4 auth user
    5 contenttypes contenttype
    6 sessions session
    7 course academiccourse
    8 course specialcourse
    9 course coupon

    1. 在优惠券中定义一个ForerignKey字段,

    并关联到django_content_type表。
    通常这个字段命名为“content_type”
    2. 在model中定义PositiveIntegerField字段
    用来存储关联表中的主键
    通常这个字段名为object_id
    3. 在model中定义GenericForeignKey字段
    传入上述两个字段名
    class Coupon(models.Model):
            """
            优惠券
            """
            #优惠券名
            name =  models.CharField(max_length=32)
            #指向contenttype
            content_type = models.ForeignKey(to=ContentType)
            #关联表中的字段
            object_id = models.PositiveIntegerField()
            content_object=GenericForeignKey("content_type","object_id")
    创建记录和查询
    1. 创建优惠券
    django = models.AcademicCourse.objects.filter(name="Django开发").first()
    coupon = models.Coupon.objects.create(name="Django免费体验",content_object=django)
    coupon = models.Coupon.objects.create(name="JavaEE减2000",content_type_id=9,object_id=1)

    2.查询优惠券(id=1)绑定了哪些商品
    首先查出id=1的优惠券
    coupon_obj = models.Coupon.objects.filter(id = 1).first()
    coupon_obj.content_type_id #取关联django_content_type表的id
    coupon_obj.content_type #点出来的是对象
    coupon_obj.object_id #取关联对象的id
    coupon_obj.content_object #取出对应的model对象

    3.查询django开发的所有优惠券
    一种是
    models.Coupon.objects.filter(object_id = 2,content_type_id=9).all()
    第二种是
    反向查询,需要在每个商品表中添加
    coupons = GenericRelation(to='Coupon')
    python_obj = models.SpecialCourse.objects.filter(id = 2).first()
    python_obj.coupon.all()
     
  • 相关阅读:
    React Native for Android应用名及图标修改
    如何不使用Navigator空间实现跳转页面?
    ReactNative WebView组件详解
    react-native react-navigation使用
    微信小程序——选择某个区间的数字
    Git分支操作——查看、新建、删除、提交、合并
    Github + Hexo 搭建个人博客
    微信小程序——动态设置swiper的高度
    微信小程序——购物车结算
    解决stackoverflow打开慢的问题
  • 原文地址:https://www.cnblogs.com/weihengblog/p/9271319.html
Copyright © 2011-2022 走看看