【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 ...
随机推荐
- 有用的 Bash 快捷键清单
作者: Sk 译者: LCTT Sun Yongfei 现如今,我在终端上花的时间更多,尝试在命令行完成比在图形界面更多的工作.随着时间推移,我学了许多 BASH 的技巧.这是一份每个 Linux 用 ...
- webpack(构建一个前端项目)详解--升级
升级一个正式的项目结构 分离webpack.config.js文件: 新建一个webpack.config.base.js任何环境依赖的wbpack //public webpack const pa ...
- ES6学习笔记(十二)异步解决方案Promise
1.Promise 的含义 Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大.它由社区最早提出和实现,ES6 将其写进了语言标准,统一了用法,原生提供了P ...
- js 快捷键设置
function hotkey() { var a=window.event.keyCode; if((a==65)&&(event.ctrlKey)) { alert("你 ...
- 绿色便携版Lazarus的制作教程
本文来源: www.fpccn.com 原作者:逍遥派掌门人 http://msdn.microsoft.com/zh-cn/library/windows/apps/hh452791.aspx 本教 ...
- Gym - 100625E Encoded Coordinates 矩阵快速幂
题意: 一直TLE我也是醉了,,不爽! #include <iostream> #include <cstdio> #include <fstream> #incl ...
- easyUI表单验证
1.重写easyui中的 $.extend($.fn.validatebox.defaults.rules, { }) 2.长度重写的方式 1 $.extend($.fn.validatebox.de ...
- 有关error PRJ0003错误的思考
作者:朱金灿 来源:http://blog.csdn.net/clever101 今天同事遇到两个编译错误: 项目: error PRJ0003 : 生成"rc.exe"时出错. ...
- c#同步上下文SynchronizationContext学习笔记
提供在各种同步模型中传播同步上下文的基本功能.同步上下文的工作就是确保调用在正确的线程上执行. 同步上下文的基本操作 Current 获取当前同步上下文 var context = Synchroni ...
- ES6学习笔记(一)新的变量定义命令let和const
1.一些历史 ES6(ECMAScript 6.0)是 JavaScript 语言的新一代标准,于2015 年 6 月正式发布,距今已经4年了,它的目标,是使得 JavaScript 语言可以用来编写 ...