一、理想表结构设计

1、初始构建

1. 场景
刚过去的双12,很多电商平台都会对他们的商品进行打折促销活动的,
那么我们如果要实现这样的一个场景,改如何设计我们的表?

2. 初始表设计

注释很重要,看看吧

from django.db import models

# Create your models here.

# 食物类
class Food(models.Model):
'''
理想中的表数据
id title
1 猪肉
2 牛肉
'''
title = models.CharField(max_length=32) # 水果类
class Fruit(models.Model):
'''
理想中的表数据
id title
1 苹果
2 榴莲
'''
title = models.CharField(max_length=32) # 双12打折,优惠卷类
class Coupon(models.Model):
'''
理想中的数据表
id title food_id fruit_id xxx_id ...
1 猪肉9.9折 1 null
2 榴莲11折 null 2
但是这样构建表结构是不现实的,因为如果我的分类有几十种呢,不就要几十个外键吗
########################################################################
因此,我们想到了另一种方法,再建一张MyTable表,专门用于存放表,我们的优惠表就可以如下设计
id title table_id object_id
1 猪肉9.9折 1 1
2 榴莲11折 2 2 table_id找到是哪一张表,object_id是找到那种表的某条数据
'''
title = models.CharField(max_length=32)
# 定位表
table = models.ForeignKey(to='MyTable')
object_id = models.IntegerField() class MyTable(models.Model):
'''
id app_name table_name
1 Demo food
2 Demo fruit
3 Demo coupon
'''
app_name = models.CharField(max_length=32)
table_name = models.CharField(max_length=32)

3. 缺点
这样设计的缺点在于,我每次新建一张表,就必须到MyTable表里面记录,
但是不用担心,我们能想到的,Django也帮我们想到了,
Django的ContentType组件就帮我们实现了跟MyTable一样的表结构,而且你每建一张表,都会自动录进去,不需要自己录入。

二、ContentType

1、介绍

ContentType是Django的内置的一个应用,可以追踪项目中所有的APP和model的对应关系,并记录在ContentType表中。
当我们的项目做数据迁移后,会有很多django自带的表,其中就有django_content_type表。

ContentType组件应用:
  -- 在model中定义ForeignKey字段,并关联到ContentType表,通常这个字段命名为content_type(使用其他命名反向查询会报错)

  -- 在model中定义PositiveIntergerField字段, 用来存储关联表中的主键,通常我们用object_id

  -- 在model中定义GenericForeignKey字段,传入上面两个字段的名字

  -- 方便反向查询可以定义GenericRelation字段

注意:
  -- 也就是说GenericForeignKey是正向查,GenericRelation是反向查
  -- ContentType表中的对象可以使用model_class()这个方法拿到具体的那张表

2、models

from django.db import models
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation # Create your models here. class Food(models.Model):
'''
理想中的表数据
id title
1 猪肉
2 牛肉
'''
title = models.CharField(max_length=32)
# 只用于反向查询,也不生成字段
coupons = GenericRelation(to='Coupon') class Fruit(models.Model):
'''
理想中的表数据
id title
1 苹果
2 榴莲
'''
title = models.CharField(max_length=32)
# 双12打折,有优惠价
class Coupon(models.Model):
'''
理想中的数据表
id title food_id fruit_id xxx_id ...
1 猪肉9.9折 1 null
2 榴莲11折 null 2
但是这样构建表结构是不现实的,因为如果我的分类有几十种呢,不就要几十个外键吗
########################################################################
因此,我们想到了另一种方法,再建一张MyTable表,专门用于存放表,我们的优惠表就可以如下设计
id title table_id object_id
1 猪肉9.9折 1 1
2 榴莲11折 2 2 table_id找到是哪一张表,object_id是找到那种表的某条数据
'''
title = models.CharField(max_length=32)
# 自己的表
# table = models.ForeignKey(to='MyTable')
# object_id = models.IntegerField()
########################################################
# Django提供的表
# 1.跟ComtentType表绑定关系
content_type = models.ForeignKey(to=ContentType)
# 2.对象的id
object_id = models.PositiveIntegerField()
#------------------------------------------------------#
# 如果就这样创建表,那么在新建这个表的数据的时候会很麻烦
# 比如:
# table_id = ContentType.objects.filter(app_label='Demo', model='food').first().id
# Coupon.objects.create(title=xxx, content_type_id=table_id, object_id=x)
# 因此Django也给我们提供了方便的用法,通过表id和object_id不就是为了定位到具体的某个对象吗
# 使用content_obj,会直接根据这个对象去帮你找到对应的content_type_id和object_id
# 这样创建表的时候就容易多了:Coupon.object.create(title=xxx, content_obj=obj)
# 注意:content_obj不是字段,不存在数据库中的,只是Django为了给我们提供方便而帮我们做的一些操作 # 3.通过外键关系给表及对象id绑定关系,不生成字段
content_obj = GenericForeignKey('content_type', 'object_id')

3、示例

class TestView(views.View):
def get(self, request):
# 原始方法给猪肉创建优惠卷
# ContentType的字段是app_label和model
content_type_id = ContentType.objects.filter(app_label='Demo', model='food').first().id
object_id = Food.objects.filter(title='猪肉').first().id
Coupon.objects.create(title='猪肉9.9折', content_type_id=content_type_id, object_id=object_id) # 用ContentType给榴莲创建优惠卷
obj = Fruit.objects.filter(title='榴莲').first()
Coupon.objects.create(title='榴莲11折', content_obj=obj) # 原始方法查榴莲的所有优惠卷
content_type = ContentType.objects.filter(app_label='Demo', model='fruit').first()
ret = Coupon.objects.filter(content_type=content_type, object_id=2).all()
print(ret[0].title) # 用Django提供的ContentType的反向查猪肉的优惠卷
ret = Food.objects.filter(title='猪肉').first().coupons.all()
print(ret[0].title) # 正向查,优惠卷id=1绑定了哪个对象
coupon_obj = Coupon.objects.filter(id=1).first()
print(coupon_obj.content_obj.title) # 通过ContentType获得表名
content = ContentType.objects.filter(app_label='Demo', model='fruit').first()
# 获得表model对象 相当于models.Fruit
fruit_model = content.model_class()
fruit_list = fruit_model.objects.all()
for fruit in fruit_list:
print(fruit.title) return HttpResponse('ok')

Django之ContentType组件的更多相关文章

  1. Django组件(五) Django之ContentType组件

    基础使用 -contenttype组件 -django提供的一个快速连表操作的组件,可以追踪项目中所有的APP和model的对应关系,并记录在ContentType表中. 当我们的项目做数据迁移后,会 ...

  2. Django day31 contentType组件,Django的缓存

    一.contentType组件 1.干什么用的? 是一个django内置的一个组件,方便我们快速的连表操作 2.这两个字段都不会在数据库中生成,他只是用来查询,插入的 -在course表中: poli ...

  3. 【Django】ContentType组件

    目录 理解 表结构 使用 @ 好,现在我们有这样一个需求,我们的商城里有很多的商品,然而节日要来了,我们要搞活动. 那么,我们就要设计优惠券,优惠券都有什么类型呢?满减的.折扣的.立减的.等等等... ...

  4. Django中content-type组件

    django-content 1.需求 一家餐馆,有多个菜系,粤菜.湘菜.闽南菜.东北菜等,每个菜系中的菜品又分为小份.中份.大份,每个菜系对应的菜品量价格不同,现需要将该需求建表. 2. 建表方式 ...

  5. Django中content-type组件的使用

    content-type组件 ContentType是Django的内置的一个应用,可以追踪项目的所有APP和model的对应关系,并记录在ContentTpe表中,当我们的项目做数据迁移后,会有很多 ...

  6. Django :Content-Type组件

    Content_Type 组件 用法: model.py: from django.db import models # Create your models here. class Food(mod ...

  7. Django 之 ContentType组件

    一.什么是 ContentTypes ContentTypes 是 Django 内置的一个应用,它可以追踪记录项目中所有 app 和 model 的对应关系,并记录在 django_content_ ...

  8. Django:ContentType组件

    一.项目背景 二.版本一 三.版本二 三.终极版(使用ContentType) 一.项目背景 luffy项目,有课程有学位课(不同的课程字段不一样),价格策略 问题:1.如何设计表结构,来表示这种规则 ...

  9. django内置组件——ContentTypes

    一.什么是Django ContentTypes? Django ContentTypes是由Django框架提供的一个核心功能,它对当前项目中所有基于Django驱动的model提供了更高层次的抽象 ...

随机推荐

  1. Vue中父组件传子组件

    父组件代码: <template> <section :class="menuMode === 'vertical' ? 'vertical-sub-nav' : 'sub ...

  2. 2019-01-28 [日常]Beyond的歌里最多是"唏嘘"吗? - Python分词+词频

    看了一个Beyond的纪录片, 提到这个. 觉得心有不甘, 于是搜集了24首歌词, 用Python做了简单分词和词频统计. 源码(包括歌词)在: program-in-chinese/study 统计 ...

  3. 算法题丨Remove Duplicates from Sorted Array

    描述 Given a sorted array, remove the duplicates in-place such that each element appear only once and ...

  4. 记一次与iframe之间的抗争

    iframe这个标签之前了解过这个东西,知道它可以引入外来的网页,但是实际开发中没有用到过.这一次有一个需求是说准备要在网页中嵌套另外一个网站,用iframe这个标签,让我测试一下这个可不可以在自己的 ...

  5. django源码分析 python manage.py runserver

    django是一个快速开发web应用的框架, 笔者也在django框架上开发不少web应用,闲来无事,就想探究一下django底层到底是如何实现的,本文记录了笔者对django源码的分析过程 I be ...

  6. MySQL 修改账号的IP限制条件

    今天遇到一个需求:修改MySQL用户的权限,需要限制特定IP地址才能访问,第一次遇到这类需求,结果在测试过程,使用更新系统权限报发现出现了一些问题, 具体演示如下. 下面测试环境为MySQL 5.6. ...

  7. 【原】Java学习笔记005 - 流程控制

    package cn.temptation; public class Sample01 { public static void main(String[] args) { // 程序的流程控制(流 ...

  8. per-CPU变量

    为什么需要per-CPU变量 假设系统中有4个cpu, 同时有一个变量在各个CPU之间是共享的,每个cpu都有访问该变量的权限. 当cpu1在改变变量v的值的时候,cpu2也需要改变变量v的值.这时候 ...

  9. 010 Editor v8.0.1(32 - bit) 算法逆向分析、注册机编写

    010 Editor 的逆向分析整体算下来还是比较简单的,将程序拖入OD,通过字符串搜索定位到核心代码,经过分析,主要是如下图所示的两个关键函数,返回正确的值,才算是注册成功. 00409C9B 这个 ...

  10. 系统功能调用Windows操作系统原理实验

    一.实验目的 1.熟悉操作系统的系统功能调用. 2.掌握用C语言实现系统功能调用的方法和步骤. 3.掌握利用10H号功能调用(BIOS的显示I/O功能调用)来实现对屏幕的操作与控制. 二.实验内容 1 ...