【Django】ContentType组件
@
好,现在我们有这样一个需求,我们的商城里有很多的商品,然而节日要来了,我们要搞活动.
那么,我们就要设计优惠券,优惠券都有什么类型呢?满减的、折扣的、立减的、等等等...
我们对应着活动类型,对某类商品设计优惠卷,比如:
家电是一类商品、食物是一类商品,那么我们就可以设计家电折扣优惠券,以及食物满减优惠券等.
所以,我们一顺手,表结构就出来了:
from django.db import models
is_true = {'null': True, 'blank': True}
# 家用电器表
class Appliance(models.Model):
"""
id name
1 冰箱
2 电视
3 洗衣机
"""
name = models.CharField(max_length=64)
# 食品表
class Food(models.Model):
"""
id name
1 面包
2 牛掰
"""
name = models.CharField(max_length=64)
# 水果表
class Fruit(models.Model):
"""
id name
1 苹果
2 香蕉
"""
name = models.CharField(max_length=64)
# class ...
# 优惠卷表
class Coupon(models.Model):
"""
id title appliance_id food_id fruit_id
1 通用优惠卷 null null null
2 冰箱折扣券 1 null null
3 电视折扣券 2 null null
4 苹果满减卷 null null 1
"""
title = models.CharField(max_length=64)
appliance = models.ForeignKey(to='Appliance', **is_true)
food = models.ForeignKey(to='Food', **is_true)
fruit = models.ForeignKey(to='Fruit', **is_true)
# ...
# 实际上我们的商品种类会特别多,导致我们这张表的外键也越来越多
殊不知,我们的大Django早就为我们提供了更高明的用法——ContentType组件.
理解
ContentType是Django中内置的一个应用,可以追踪项目中所有的APP和model的对应关系,并记录在ContentType表中.
当我们的项目做数据迁移后,会在数据库中生成一些Django自带的表,其中就包含django_content_type表.
我们先来看看这张表:

再来看看这张表内默认的数据:

可见,自动就建立了所有APP与其数据表的对应关系.
表结构
步骤
- 在model中定义
ForeignKey字段,并关联到ContentType表,通常这个字段命名为content-type. - 在model中定义
PositiveIntergerField字段,用来存储步骤一中被外键的表中的主键,通常这个字段命名为object_id. - 在model中定义
GenericForeignKey字段,传入上面两个字段的名字. - 为了方便反向查询,可在被外键表中定义
GenericRelation字段并指向创建外键的表.
好,根据开篇的表结构示例以及如上的步骤,我们的新表结构又出来了:
from django.db import models
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation
# 家用电器表
class Appliance(models.Model):
name = models.CharField(max_length=64)
# 4. 为了方便反向查询,可在被外键表中定义GenericRelation字段并指向创建外键的表
coupons = GenericRelation(to='Coupon')
# 食物表
class Food(models.Model):
name = models.CharField(max_length=64)
# 水果表
class Fruit(models.Model):
name = models.CharField(max_length=64)
# 优惠卷表
class Coupon(models.Model):
title = models.CharField(max_length=64)
# 1. 在model中定义ForeignKey字段,并关联到ContentType表
content_type = models.ForeignKey(to=ContentType) # 这里就不要加引号了
# 2. 在model中定义PositiveIntergerField字段,用来存储步骤一中被外键的表中的主键
object_id = models.PositiveIntegerField()
# 3. 在model中定义GenericForeignKey字段,传入上面两个字段的名字.
content_object = GenericForeignKey('content_type', 'object_id')
数据迁移后,django_content_type表中自动就增加了APP与其model的对应字段.
使用
首先 我们准备些数据
# 在Python脚本中调用Django环境
import os if __name__ == '__main__':
# 注意将下面的'blog097.settings'改为对应的配置文件路径
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'blog097.settings')
import django
django.setup()
from blog import models [models.Appliance.objects.create(name=i) for i in ("冰箱", "电视", "洗衣机")]
[models.Food.objects.create(name=i) for i in ("面包", "牛奶")]
[models.Fruit.objects.create(name=i) for i in ("苹果", "香蕉")]
如果不能理解此操作,可见博文:【在Python脚本中调用Django环境】
然后 开始我们的ORM操作
# 在Python脚本中调用Django环境
import os if __name__ == '__main__':
# 注意将下面的'blog097.settings'改为对应的配置文件路径
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'blog097.settings')
import django
django.setup()
from blog import models
from django.contrib.contenttypes.models import ContentType """通过ContentType获得表名"""
content_type_obj = ContentType.objects.filter(app_label='blog', model='appliance').first() # 打印结果:appliance """获得表内的所有对象,相当于models.Applicance"""
model_class = content_type_obj.model_class() # <class 'blog.models.Appliance'>
obj_list = model_class.objects.all()
[print(obj.name) for obj in obj_list] # 冰箱、电视、洗衣机 """为冰箱添加一条优惠记录"""
ice_box = models.Appliance.objects.filter(name="冰箱").first()
models.Coupon.objects.create(title="冰箱折扣券", content_object=ice_box) """查询冰箱的所有优惠卷"""
# 我们定义了反向查询
coupon_list01 = ice_box.coupons.all()
[print(coupon.title) for coupon in coupon_list01] # 如果没有定义反向查询
coupon_list02 = models.Coupon.objects.filter(content_type=content_type_obj, object_id=ice_box.id).all()
[print(coupon.title) for coupon in coupon_list02]
【Django】ContentType组件的更多相关文章
- python 全栈开发,Day98(路飞学城背景,django ContentType组件,表结构讲解)
昨日内容回顾 1. 为什么要做前后端分离? - 前后端交给不同的人来编写,职责划分明确. - API (IOS,安卓,PC,微信小程序...) - vue.js等框架编写前端时,会比之前写jQuery ...
- Django ContentType组件
ContentType组件 引入 现在我们有这样一个需求~我们的商城里有很多的商品~~节日要来了~我们要搞活动~~ 那么我们就要设计优惠券~~优惠券都有什么类型呢~~满减的~折扣的~立减的~~ 我们对 ...
- vue创建路由,axios前后台交互,element-ui配置使用,django contentType组件
vue中创建路由 每一个vue组件都有三部分组成 template:放html代码 script:放js相关 style:放css相关 vue中创建路由 1.先创建组件 Course.vue 2.ro ...
- Django content-type组件
介绍 Django包含一个contenttypes应用程序(app),可以跟踪Django项目中安装的所有模型(Model),提供用于处理模型的高级通用接口. Contenttypes应用的核心是Co ...
- Django之ContentType组件
一.理想表结构设计 1.初始构建 1. 场景刚过去的双12,很多电商平台都会对他们的商品进行打折促销活动的,那么我们如果要实现这样的一个场景,改如何设计我们的表? 2. 初始表设计 注释很重要,看看吧 ...
- Django组件(五) Django之ContentType组件
基础使用 -contenttype组件 -django提供的一个快速连表操作的组件,可以追踪项目中所有的APP和model的对应关系,并记录在ContentType表中. 当我们的项目做数据迁移后,会 ...
- ContentType组件,Django缓存机制,跨域请求
ContentType组件 解决什么问题:表的id和数据id,来唯一确定一条数据 用: 插入数据: models:content_obj = GenericForeignKey('table_id', ...
- contenttype组件、Django缓存机制以及跨域请求
1 昨日回顾 版本控制 *** (1)url=127.0.0.1/course/?version=v100000 1 versioning_class=QueryParameterVersioning ...
- Django day31 contentType组件,Django的缓存
一.contentType组件 1.干什么用的? 是一个django内置的一个组件,方便我们快速的连表操作 2.这两个字段都不会在数据库中生成,他只是用来查询,插入的 -在course表中: poli ...
随机推荐
- UCOSii任务就绪表之OSUnMapTbl[16*16]的数组是如何得到的
我比较喜欢图,如下图: 图1: INT8U const OSUnMapTbl[]数组内的数据. 1.UCOSii的优先级相关内容 首先先介绍一个概念:优先级.UCOSii的优先级按倒叙排列,即优先级数 ...
- javascript与DOM节点的结合使用
文档对象模型(Document Object Model,简称DOM),是W3C组织推荐的处理可扩展标志语言的标准编程接口.在网页上,组织页面(或文档)的对象被组织在一个树形结构中,用来表示文档中对象 ...
- 【Codeforces Round #422 (Div. 2) B】Crossword solving
[题目链接]:http://codeforces.com/contest/822/problem/B [题意] 让你用s去匹配t,问你最少需要修改s中的多少个字符; 才能在t中匹配到s; [题解] O ...
- java反射机制剖析(二)— Class Loader
上一篇博客简要的提了一下java反射机制中涉及到的一些相关知识,那么ClassLoader就是当中之中的一个.本篇博客就具体的对ClassLoader做一个相对深入的了解. 作为了解须要知道的是.事实 ...
- matlab 常用机器学习算法的实现
1. KNN 分类 load fisheriris X = meas; Y = species; % 3 分类问题 % 通过训练集进行训练 Mdl = fitcknn(X, Y, 'NumNeighb ...
- Weka中数据挖掘与机器学习系列之基本概念(三)
数据挖掘和机器学习 数据挖掘和机器学习这两项技术的关系非常密切.机器学习方法构成数据挖掘的核心,绝大多数数据挖掘技术都来自机器学习领域,数据挖掘又向机器学习提出新的要求和任务. 数据挖掘就是在数据中寻 ...
- LINQ的基本语法包含如下的8个上下文关键字,这些关键字和具体的说明如下
出于工作需要,准备把LINQ的相关知识梳理一遍,希望能填补下之前学习漏掉的或是没有注意的地方,也为未来减轻压力~ LINQ查询表达式的基本语法很容易掌握,它使用C#常见的语言构造,从外观上看,和我们常 ...
- Linux下QQ的使用并手动设置QQ文件保存路径
一.背景&&目标 马化腾迟迟不肯做linux版本的QQ和微信,实在抠脚. 没有办法,要在linux上使用QQ,目前我找到最好的办法就是使用wine,然而wine这个杀千刀的又是个坑货, ...
- SpringBoot与SpringCloud的区别
1.Spring boot 是 Spring 的一套快速配置脚手架,可以基于spring boot 快速开发单个微服务:Spring Cloud是一个基于Spring Boot实现的云应用开发工具: ...
- wampserver-mysql创建数据库
首先打开wampserver,在右下角会出现一个这样的图标,左键单击它,选择MYSQL->MYSQL控制台 输入密码 创建一个新的数据库:create database XXX 注意要输“;”, ...