问题分析

在之前的一个商城的项目中使用了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. 关于H5的自定义属性data-*

    data-* 是H5的新属性,用来让开发者对标签添加自定义属性的. 其读写方式有如下几种: 如果是 data-abc 的格式,则采用正常格式 abc 来读写该属性值 <div id=" ...

  2. 记一次使用MemoryCache不能Get的问题

    在.NET Core自带的Angular模板项目中,我想要做一个简单的登录认证. 所以想填写用户名密码,使用guid作为key,存储登录信息,每次页面刷新的时候check它. 思路觉得没有问题,但是一 ...

  3. January 31 2017 Week 5 Tuesday

    Better to get hurt by the truth than comforted with a lie. 被真相伤害好过被谎言安慰. For ourselves, we need to b ...

  4. 看了xici有写给孩子的信,maybe我也要写给孩子一些东西了

    看了xici有写给孩子的信,maybe我也要写给孩子一些东西了

  5. DB TABLE实践

    我的数据库设计实践(一)   兜兜转转,突然发现我现在已经是一个老司机了,一直写代码都很忙,没有把很多点点滴滴的记录下来,今天开始就开始一个系列,分析当年我接触或者我设计过的表结构,有好有坏,有欢喜也 ...

  6. 使用ant进行邮件发送,ant发送已存在的html文件

    Jenkins上使用发送邮件功能一直有问题,放弃Jenkins配置,使用ant的进行发送邮件,参考文档可以: https://www.jianshu.com/p/04cfce59890a 我这里是要发 ...

  7. Django 模型中DateField字段

    DateField¶ class DateField([auto_now=False, auto_now_add=False, **options])¶ 这是一个使用Python的datetime.d ...

  8. YII中使用SOAP一定要注意的一些东西

    SiteController.php 在Yii框架下使用soap接口的时候,需要注意几个问题:: 1 服务器要打开soap功能,在phpinfo里搜soap,如果已经打开了的话有个大标题就是SOAP2 ...

  9. PHP 基础系列(三) 【转】PHP 函数实现原理及性能分析

    作者:HDK (百度) 前言 在任何语言中,函数都是最基本的组成单元.对于PHP的函数,它具有哪些特点?函数调用是怎么实现的?php函数的性能如何,有什么使用建议?本文将从原理出发进行分析结合实际的性 ...

  10. Kali-linux应用更新和配置额外安全工具

    本节将介绍更新Kali的过程和配置一些额外的工具.这些工具在后面的章节中将是有用的.Kali软件包不断地更新和发布之间,用户很快发现一套新的工具比最初在DVD ROM上下载的软件包更有用.本节将通过更 ...