使用ContentType处理大量的外键关系
问题分析
在之前的一个商城的项目中使用了mysql, 提到mysql就是外键, 多对多等等一系列的表关系
因为是一个商城的项目, 这里面有优惠券, 商品有很多的分类, 不同的商品又有不同的优惠券
其实要说的也就是商品和优惠券的关系,
说到关系那肯定就是用外键, 优惠券外键商品, 但是有一个问题, 一个外键只能指向一张表
现在假如有10个商品表, 一张优惠券表, 要想在一张表中给另外10张表创建外键关系, 那就需要10个外键关系, 10个外键字段
可想而知, 这种方法是不可行的
其实有一种办法那就是, 在优惠券表不直接关联商品表, 而是搞一个中间表, 关联这个中间表, 那这个中间表应该张什么样子呢?
这张表中存储是的app名字和表的名字
id app_name model_name
1 mian Human_insurance
2 main Life_insurance
然后优惠券表就这张表建立外键关系, 然后在优惠券中在存储一个object_id, 通过外键找到关联的表, 通过object_id找到表中的对象, 这样就OK了
上面的正常人的想法, django的开发者也是正常人, 哈哈, 他们也想到了, 所以django提供了这样的一张表.
使用ContentType处理外键关系
下面是我写的一个小demo, 这里面就利用了django提供的ContentType来处理外键关系
模型表
from django.db import models
from django.contrib.contenttypes.fields import GenericRelation, GenericForeignKey
from django.contrib.contenttypes.models import ContentType class Book(models.Model):
title = models.CharField(max_length=32)
price = models.FloatField()
category_choices = (("chinese", "中文"), ("english", "英文"), ("development", "开发"), ("network", "网络"))
category = models.CharField(choices=category_choices, max_length=32)
pub_date = models.DateTimeField(null=True, blank=True) content_type = models.ForeignKey(ContentType, blank=True, null=True, on_delete=models.CASCADE)
# 定位对象的id
object_id = models.PositiveIntegerField(blank=True, null=True)
# 定位对象
content_object = GenericForeignKey('content_type', 'object_id') def __str__(self):
return self.title class Publish(models.Model):
name = models.CharField(max_length=32)
address = models.CharField(max_length=128)
books = GenericRelation("Book") def __str__(self):
return self.name
book表中的字段介绍
content_type: 是一个外键字段, 关联的表就是和上面自己构造的表结构一致, 只不过是Django提供的
这样就方便了很多.
object_id: 这个字段存储的就是某张表中的某个对象的id, 所以就是用数字类型进行存储
content_object: 这个字段是一个GenericForeignKey, 这个字段给我们提供了很大的方便, 但是这个字段不会真实的在数据库中创建,
为什么说提供了很大的方便呢?
因为, 在创建book对象的时候可以给content_object传一个对象, 这个字段能够自动找到这个对象的app_name和model_name, 并且填充到content_type和object_id中
这样就不用我们自己去查了
下面就使用这个字段对数据库进行操作
查看书籍的出版社
a = models.Book.objects.filter(id=5).first()
print(a.content_object)
#content_object通过content_type和object_id定位到对象
创建book
创建book的时候需要关联出版社, 这就用道了contentType, 只传一个content_object参数就可以了
# 先查询出出版社
b = models.Publish.objects.filter(id=3).first()
# 创建book
c = models.Book.objects.create(title="test", price=99.9, category="english", content_object=b)
print(c)
修改book的出版社
e = models.Book.objects.filter(title="test").first()
e.content_object = models.Publish.objects.filter(id=4).first()
e.save()
删除
因为我使用的的django2.0, 在创建外键的时候必须指定参数on_delete=models.CASCADE, 将出版社删除了book也就没了
models.Publish.objects.filter(id=1).delete()
总结
使用ContentType来处理大量的外键关系
使用ContentType处理大量的外键关系的更多相关文章
- Django——ContentType(与多个表建立外键关系)及ContentType-signals的使用
一.ContentType 在django中,有一个记录了项目中所有model元数据的表,就是ContentType,表中一条记录对应着一个存在的model,所以可以通过一个ContentType表的 ...
- MySQL外键与外键关系说明(简单易懂)
MySQL主键和外键使用及说明 一.外键约束 MySQL通过外键约束来保证表与表之间的数据的完整性和准确性. 外键的使用条件: 1.两个表必须是InnoDB表,MyISAM表暂时不支持外键(据说以后 ...
- Entity Framework Code First主外键关系映射约定
本篇随笔目录: 1.外键列名默认约定 2.一对多关系 3.一对一关系 4.多对多关系 5.一对多自反关系 6.多对多自反关系 在关系数据库中,不同表之间往往不是全部都单独存在,而是相互存在关联的.两个 ...
- 多重外键关系在java中的处理方案
// 0){ var ul = li.getElementsByTagName("ul")[0]; ul.style.display = "none"; var ...
- 通过SQL脚本来查询SQLServer 中主外键关系
在SQLServer中主外键是什么,以及主外键如何创建,在这里就不说了,不懂的可以点击这里,这篇文章也是博客园的博友写的,我觉得总结的很好: 此篇文章主要介绍通过SQL脚本来查看Sqlserver中主 ...
- SQL Server数据库中导入导出数据及结构时主外键关系的处理
2015-01-26 软件开发中,经常涉及到不同数据库(包括不同产品的不同版本)之间的数据结构与数据的导入导出.处理过程中会遇到很多问题,尤为突出重要的一个问题就是主从表之间,从表有外检约束,从而导致 ...
- mysql中主外键关系
一.外键: 1.什么是外键 2.外键语法 3.外键的条件 4.添加外键 5.删除外键 1.什么是外键: 主键:是唯一标识一条记录,不能有重复的,不允许为空,用来保证数据完整性 外键:是另一表的主键, ...
- 【转】PowerDesigner删除外键关系,而不删除外键列
原文:https://blog.csdn.net/tomsyc/article/details/6075530 PowerDesigner中配置外键关系时,如果要删除配置的外键关系,默认设置会一同删除 ...
- MySQL创建数据表并建立主外键关系
为mysql数据表建立主外键需要注意以下几点: 需要建立主外键关系的两个表的存储引擎必须是InnoDB. 外键列和参照列必须具有相似的数据类型,即可以隐式转换的数据类型. 外键列和参照列必须创建索引, ...
随机推荐
- idea output 消失找不到
今天一不小心把idea的 debug的控制台output 搞丢了, 半天找不到,原来是在这里隐藏着 Restore layout
- html 颜色在线取色器
推荐一个链接 还不错 http://www.atool.org/colorpicker.php
- 快速安装测试版Mysql
本文操作系统: CentOS 7.2.1511 x86_64MySQL 版本: 5.7.13 1.卸载系统自带的 mariadb-lib [root@centos-linux ~]# rpm -qa| ...
- InputStream中mark方法使用
在调用mark的地方做上标记,参数readlimit说明在读取readlimit个字符后书签做废(6.0好像没有失效 ,仍然可以标记位置),使用reset后回到标记的位置.import java.io ...
- Mysql学习---基础操作学习2
基本数据类型 Mysql基本数据类型:二进制,数值[整数,小数].字符串[定长,变长]. 二进制数据.时间和枚举集合 bit[(M)] 二进制位(101001),m表示二进制位的长度(1-64),默认 ...
- Google Colab 免费的谷歌GPU for deep learning
Who wants to use a free GPU for deep learning?Google Colab is a free cloud service and now it suppor ...
- php集群和分布式理解
首先架构层次来说: php的集群是指很多台服务器处理同样的工作,指的是硬件上的一般,比如slb负载均衡主要作用是有多台服务器处理同样的工作, php分布式是指多台服务器处理不同的工作,指的是业务上的一 ...
- vsphere的P2V工具做的物理机迁移到虚拟机报错out of memory
vsphere的P2V工具做的物理机迁移到虚拟机 迁移成功,但是启动报错 进入rescue模式后发现是sysctl.conf文件的参数设大了因为虚拟机的内存没有物理机内存大 kernel.shm ...
- Code First TPH、TPT、TPC与继承类
一.Table Per Hierarchy (TPH,默认) 每个层次结构共用一个表,类的每一个属性都必须是可空的. 1.默认行为 只建立一个表,把基类和子类中的所有属性都映射为表中的列. 在这种处理 ...
- 023re模块(正则)
之前我刚学的python知识点,没有题目进行熟悉,后面的知识点会有练习题,并且慢慢补充.看到很多都是很简单的练习,碰到复杂.需要运用的再补充吧#字符串中使用到正则表达式 s='hello world' ...