使用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. 外键列和参照列必须具有相似的数据类型,即可以隐式转换的数据类型. 外键列和参照列必须创建索引, ...
随机推荐
- Windows ->> Windows下一代文件系统 -- Resilient file system(ReFS)
Comming soon!!! 参考文献: Building the next generation file system for Windows: ReFS ReFS: What you need ...
- Oracle数据库从入门到精通 单行函数问题
视频课程:李兴华 Oracle从入门到精通视频课程 学习者:阳光罗诺 视频来源:51CTO学院 Oracle数据库从入门到精通-单行函数 在数据库中,为了方便用户的数据开发,往往会提供一系列的支持函数 ...
- Excel Events
WorkbookEvents Interface WorkbookEvents_ActivateEventHandler Delegate WorkbookEvents_AddinInstallEve ...
- css如何制作八边形
随着技术的发展,css也越发强大,css可以制作很多有趣的图形,让我们一起来看一下如何使用css制作一个八边形吧. 方法/步骤 1新建一个html文件.如图: 在html文件上创建一个 ...
- SqlParameter.Value = NULL 引发的数据库异常
摘自:http://www.cnblogs.com/ccweb/p/3403492.html using (SqlCommand cmd = new SqlCommand()) { cmd.Conne ...
- Code First TPH、TPT、TPC与继承类
一.Table Per Hierarchy (TPH,默认) 每个层次结构共用一个表,类的每一个属性都必须是可空的. 1.默认行为 只建立一个表,把基类和子类中的所有属性都映射为表中的列. 在这种处理 ...
- SAP人工智能服务Recast.AI的一个简单例子
关于这个例子的完整介绍,请参考公众号 "汪子熙"的两篇文章: SAP C/4HANA与人工智能和增强现实(AR)技术结合的又一个创新案例 和使用Recast.AI创建具有人工智能的 ...
- was缓存以致web.xml更改无效
was缓存导致web.xml更改无效 在项目中经常遇见这样的问题:修改应用的配置文件web.xml后,无论重启应用还是重启WebSphere服务器,都不能重新加载web.xml,导致修改的内容无效. ...
- PHP 获取数组随意下标key的上一个prev和下一个next下标值
PHP 获取数组随意下标key的上一个prev和下一个next下标值 <? php $xoops[1] = '小'; $xoops[2] = '孩'; $xoops[3] = '子'; $xoo ...
- [原创] SiteServer 3.5 批量导入文章的SQL处理脚本
2005时做过一个小网站,当时是用ASP+Access做的,功能很简单,但里面的文章不少 现在就像把它转移到SS上来,重点就是如何导入文章 本来SS本身提供了批量导入功能,但对于在WEB上一次性导入一 ...