问题分析

在之前的一个商城的项目中使用了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处理大量的外键关系的更多相关文章

  1. Django——ContentType(与多个表建立外键关系)及ContentType-signals的使用

    一.ContentType 在django中,有一个记录了项目中所有model元数据的表,就是ContentType,表中一条记录对应着一个存在的model,所以可以通过一个ContentType表的 ...

  2. MySQL外键与外键关系说明(简单易懂)

    MySQL主键和外键使用及说明 一.外键约束 MySQL通过外键约束来保证表与表之间的数据的完整性和准确性. 外键的使用条件:  1.两个表必须是InnoDB表,MyISAM表暂时不支持外键(据说以后 ...

  3. Entity Framework Code First主外键关系映射约定

    本篇随笔目录: 1.外键列名默认约定 2.一对多关系 3.一对一关系 4.多对多关系 5.一对多自反关系 6.多对多自反关系 在关系数据库中,不同表之间往往不是全部都单独存在,而是相互存在关联的.两个 ...

  4. 多重外键关系在java中的处理方案

    // 0){ var ul = li.getElementsByTagName("ul")[0]; ul.style.display = "none"; var ...

  5. 通过SQL脚本来查询SQLServer 中主外键关系

    在SQLServer中主外键是什么,以及主外键如何创建,在这里就不说了,不懂的可以点击这里,这篇文章也是博客园的博友写的,我觉得总结的很好: 此篇文章主要介绍通过SQL脚本来查看Sqlserver中主 ...

  6. SQL Server数据库中导入导出数据及结构时主外键关系的处理

    2015-01-26 软件开发中,经常涉及到不同数据库(包括不同产品的不同版本)之间的数据结构与数据的导入导出.处理过程中会遇到很多问题,尤为突出重要的一个问题就是主从表之间,从表有外检约束,从而导致 ...

  7. mysql中主外键关系

    一.外键: 1.什么是外键 2.外键语法 3.外键的条件 4.添加外键 5.删除外键 1.什么是外键: 主键:是唯一标识一条记录,不能有重复的,不允许为空,用来保证数据完整性 外键:是另一表的主键, ...

  8. 【转】PowerDesigner删除外键关系,而不删除外键列

    原文:https://blog.csdn.net/tomsyc/article/details/6075530 PowerDesigner中配置外键关系时,如果要删除配置的外键关系,默认设置会一同删除 ...

  9. MySQL创建数据表并建立主外键关系

    为mysql数据表建立主外键需要注意以下几点: 需要建立主外键关系的两个表的存储引擎必须是InnoDB. 外键列和参照列必须具有相似的数据类型,即可以隐式转换的数据类型. 外键列和参照列必须创建索引, ...

随机推荐

  1. 向Github提交更改的代码

    更改了本地的某一文件的代码,那么如何覆盖Github上的同一文件代码呢?请看以下步骤: 1.先用 git status 看你更改了哪些文件: 2.然后 git add 你想要提交的更改的文件 或者 g ...

  2. python 数据结构应用

  3. WPF&Silverlight5 常用功能差异

    一晃从Wpf转到sl也有半年多了,总想总结一下wpf和sl的差异,今天终于下笔. 首先来个整体图: 通过上图可以发现其实sl只是使用了wpf的一小部分,只是sl依赖的freamwork有很大部分都一样 ...

  4. 深入理解mysql的底层实现

    MySQL 的常用引擎 1. InnoDB InnoDB 的存储文件有两个,后缀名分别是 .frm 和 .idb,其中 .frm 是表的定义文件,而 idb 是数据文件. InnoDB 中存在表锁和行 ...

  5. dctcp-2.6.26-rev1.1.0.patch

    dctcp-2.6.26-rev1.1.0.patch diff -Naur linux-/include/linux/sysctl.h linux--dctcp-rev1.1.0/include/l ...

  6. Linux(centos7)安装maven3.5

    1.创建一个maven文件夹 [root@MiWiFi-R3-srv ~]# mkdir /usr/local/maven 1 2.上传apache-maven-3.5.0-bin.tar.gz到/u ...

  7. NFS-heartbeat-drbd模拟NFS高可用

    NFS介绍: NFS(Network File System)即网络文件系统,是FreeBSD支持的文件系统中的一种,它允许网络中的计算机之间通过TCP/IP网络共享资源.在NFS的应用中,本地NFS ...

  8. Entity Framework: 主从表的增删改

    1.根据主表添加从表数据 var dest = (from d in context.Destinations where d.Name == "Bali" select d).S ...

  9. c3p0-0.9.1.2.jar

    C3P0是一个开源的JDBC连接池,它实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展.目前使用它的开源项目有Hibernate,Spring等

  10. WAS上配置数据源连接失败

    问题描述: 在节点 cnshh171Node01 上的服务器 server1 上, 对数据源 testj2cbug 执行的测试连接操作 由于以下异常 java.sql.SQLException: 调用 ...