Django congtent types应用

contenttypes 是Django内置的一个应用,可以追踪项目中所有app和model的对应关系,并记录在ContentType表中。

每当我们创建了新的model并执行数据库迁移后,ContentType表中就会自动新增一条记录。比如我在应用app01的models.py中创建表class Electrics(models.Model): pass。从数据库查看ContentType表,显示如下:

idapp_labelmodel
admin, auth等内置应用…
5contenttypescontenttype
6app01electrics

那么这个表有什么作用呢?这里提供一个场景,网上商城购物时,会有各种各样的优惠券,比如通用优惠券,满减券,或者是仅限特定品类的优惠券。在数据库中,可以通过外键将优惠券和不同品类的商品表关联起来:

from django.db import modelsclass Electrics(models.Model):"""id  name1   日立冰箱2   三星电视3   小天鹅洗衣机"""name = models.CharField(max_length=32)class Foods(models.Model):"""id   name1    面包2    烤鸭"""name = models.CharField(max_length=32)class Clothes(models.Model):name = models.CharField(max_length=32)class Coupon(models.Model):"""id     name            Electrics        Foods           Clothes        more...1     通用优惠券       null              null            null           2     冰箱满减券         2               null            null3     面包狂欢节        null              1              null"""name = models.CharField(max_length=32)electric_obj = models.ForeignKey(to='Electrics', null=True)food_obj = models.ForeignKey(to='Foods', null=True)cloth_obj = models.ForeignKey(to='Clothes', null=True)

如果是通用优惠券,那么所有的ForeignKey为null,如果仅限某些商品,那么对应商品ForeignKey记录该商品的id,不相关的记录为null。但是这样做是有问题的:实际中商品品类繁多,而且很可能还会持续增加,那么优惠券表中的外键将越来越多,但是每条记录仅使用其中的一个或某几个外键字段。

通过使用contenttypes 应用中提供的特殊字段GenericForeignKey,我们可以很好的解决这个问题。只需要以下三步:

  • 在model中定义ForeignKey字段,并关联到ContentType表。通常这个字段命名为“content_type”
  • 在model中定义PositiveIntegerField字段,用来存储关联表中的主键。通常这个字段命名为“object_id”
  • 在model中定义GenericForeignKey字段,传入上述两个字段的名字。

为了更方便查询商品的优惠券,我们还可以在商品类中通过GenericRelation字段定义反向关系。

示例代码:

from django.db import models
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes.fields import GenericForeignKeyclass Electrics(models.Model):name = models.CharField(max_length=32)coupons = GenericRelation(to='Coupon')  # 用于反向查询,不会生成表字段def __str__(self):return self.nameclass Foods(models.Model):name = models.CharField(max_length=32)coupons = GenericRelation(to='Coupon')def __str__(self):return self.nameclass Clothes(models.Model):name = models.CharField(max_length=32)coupons = GenericRelation(to='Coupon')def __str__(self):return self.nameclass Coupon(models.Model):name = models.CharField(max_length=32)content_type = models.ForeignKey(to=ContentType) # step 1object_id = models.PositiveIntegerField() # step 2content_object = GenericForeignKey('content_type', 'object_id') # step 3def __str__(self):return self.name

创建记录和查询

from django.shortcuts import render, HttpResponse
from app01 import models
from django.contrib.contenttypes.models import ContentTypedef test(request):if request.method == 'GET':# ContentType表对象有model_class() 方法,取到对应modelcontent = ContentType.objects.filter(app_label='app01', model='electrics').first()  # 表名小写cloth_class = content.model_class() # cloth_class 就相当于models.Electricsres = cloth_class.objects.all()print(res)# 为三星电视(id=2)创建一条优惠记录s_tv = models.Electrics.objects.filter(id=2).first()models.Coupon.objects.create(name='电视优惠券', content_object=s_tv)# 查询优惠券(id=1)绑定了哪些商品coupon_obj = models.Coupon.objects.filter(id=1).first()prod = coupon_obj.content_objectprint(prod)# 查询三星电视(id=2)的所有优惠券res = s_tv.coupons.all()print(res)# 查询obj的所有优惠券:如果没有定义反向查询字段,通过如下方式:content = ContentType.objects.filter(app_label='app01', model='model_name').first()res = models.OftenAskedQuestion.objects.filter(content_type=content, object_id=obj.pk).all()return HttpResponse('....')

总结:

当一张表和多个表FK关联,并且多个FK中只能选择其中一个或其中n个时,可以利用contenttypes app,只需定义三个字段就搞定!

转载于:https://www.cnblogs.com/a-dyw/p/9275629.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/452062.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网络爬虫--7.Handler处理器 和 自定义Opener

文章目录一. 引言二. 简单的自定义opener()三. ProxyHandler处理器(代理设置)四. Cookie1.Cookie原理2.Cookie应用五. cookiejar库 和 HTTPCookieProcessor处理器1.案例一:获取Cookie,并保存到CookieJar()对象中2.案例二:利用cook…

如何选择面向对象语言

开发人员在选择面向对象语言时,还应该着重考虑以下一些实际因素。 1. 将来能否占主导地位 为了使自己的产品在若干年后仍然具有很强的生命力,人们可能希望采用将来占主导地位的语言编程。 根据目前占有的市场份额,以及专业书刊和学术会议上所…

Unicode编码及其实现:UTF-16、UTF-8,and more

本文主要讨论Unicode的编码与各种实现,着重讨论UTF-16,UTF-8的实现规则,以及Big-endian和Little-Endian的存储规则。 一、Unicode编码 Unicode出现之前已经有各种编码标准:ANSI、ISO8859-1、GB2312、GBK以及BIG-5等。Unicode试图统…

Apache Tiles的使用 前配置

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 使用方法见&#xff1a; http://blog.csdn.net/jiangyu1013/article/details/53161580 1.加maven 依赖&#xff1a; <!-- 页面布局…

day212223:线程、进程、协程

1、程序工作原理 进程的限制&#xff1a;每一个时刻只能有一个线程来工作。多进程的优点&#xff1a;同时利用多个cpu&#xff0c;能够同时进行多个操作。缺点&#xff1a;对内存消耗比较高当进程数多于cpu数量的时候会导致不能被调用&#xff0c;进程不是越多越好&#xff0c;…

php课程 8-28 php如何绘制生成显示图片

php课程 8-28 php如何绘制生成显示图片 一、总结 一句话总结&#xff1a;gd库轻松解决 1、php图片操作生成的图的两种去向是什么&#xff1f; 一种在页面直接输出&#xff0c;一种存进本地磁盘 2、php操作图片的库有哪些&#xff1f; PHP: Image Processing and Generation - M…

代码行技术

用代码行技术估算软件规模时&#xff0c;当程序较小时常用的单位是代码行数&#xff08;LOC&#xff09;&#xff0c;当程序较大时常用的单位是千行代码数&#xff08;KLOC&#xff09;。 代码行技术的主要优点是&#xff0c;代码是所有软件开发项目都有的“产品”&#xff0c;…

网络爬虫--8.编码趣闻

很久很久以前&#xff0c;有一群人&#xff0c;他们决定用8个可以开合的晶体管来组合成不同的状态&#xff0c;以表示世界上的万物。他们看到8个开关状态是好的&#xff0c;于是他们把这称为"字节"。 再后来&#xff0c;他们又做了一些可以处理这些字节的机器&#…

科技领域的一分钟

各位果迷是否能想象在一分钟之内&#xff0c;科技领域都会发生什么事情&#xff1f;——苹果平均每分钟卖出81部 iPad&#xff1b;在 iPhone 4S 发布后的第一个周末&#xff0c;每分钟卖出925部 iPhone 4S&#xff1b;RIM每分钟卖出103台黑莓手机&#xff1b;Amazon每分钟卖出1…

flavr—超级漂亮的jQuery扁平弹出对话框

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 插件描述&#xff1a;flavr是一个时尚的扁平弹出对话框为您的下一个网站。 flavr是响应设计布局&#xff0c;能够适应任何屏幕大小。 得…

经纬度之间的距离计算

来自谷歌地图的计算公式&#xff1a; 通过JAVA的Math类各种方法调用。实现上述公式 private static double EARTH_RADIUS 6378.137;// 单位千米/*** 角度弧度计算公式 rad:(). <br/>* * 360度2π πMath.PI* * x度 x*π/360 弧度* * author chiwei* param d* return* s…

在CentOS7阿里云服务器部署ThinkPHP5,并配置phpstrom实现同步开发(微信小程序及管理员后端)...

小程序和后端同步开发 1.服务器安装tp5框架&#xff1a; 方法很多比如&#xff1a;github、linux命令直接手动下、composer 都可以&#xff0c;方法很多&#xff0c;百度一下&#xff0c;不再累述 2.这时你会发现怎么都访问出现不了这个令人舒心的界面&#xff08;ok第一个坑到…

ER图( 实体联系图)

E-R图也称实体-联系图(Entity Relationship Diagram)&#xff0c;提供了表示实体类型、属性和联系的方法&#xff0c;用来描述现实世界的概念模型。 它是描述现实世界概念结构模型的有效方法。是表示概念模型的一种方式&#xff0c;用矩形表示实体型&#xff0c;矩形框内写明…

网络爬虫--9.正则表达式

文章目录一. 正则表达式1.为什么要学正则表达式2.什么是正则表达式3.正则表达式匹配规则二. Python 的 re 模块1.re 模块的一般使用步骤2.compile 函数3.match 方法4.search 方法5.findall 方法6.finditer 方法7.split 方法8.sub 方法9.匹配中文10.贪婪模式与非贪婪模式1&#…

概念模型

将需求分析得到的用户需求抽象为信息结构&#xff08;即概念模型&#xff09;的过程就是概念结构设计 概念模型的特点 &#xff08;1&#xff09;能真实、充分地反映现实世界&#xff0c;是现实世界的一个真 实模型。 &#xff08;2&#xff09;易于理解&#xff0c;从…

笔记本电池的正确使用方法

一、新买笔记本不需要激活&#xff0c;也不需要前三次的充电12小时深充深放&#xff0c;这主要是锂电池的原理和特性决定的。电池设计有电量保护&#xff0c;不可能将电量完全用完&#xff0c;当然也不可能过度充电。 二、笔记本电池的寿命受周围环境的影响很大&#xff0c;最好…

关于XShell 启动虚拟机的weblogic并在本地打开oracle-weblogic 有关部署

对于没有用过这款软件的童鞋&#xff0c;我想必定会有几步弯路&#xff1a; 1.新建好的虚拟机记得换成root用户【su root】~ifconfig【eth0 inet addr】如果没有这项请点击右上角的电脑标识&#xff0c;鼠标左击一下连接&#xff0c;没有了x号就重新输入ifconfig就有了 2.xshe…

JQuery Datatables Dom 和 Language 参数详细说明

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到教程。 Dom说明 定义表格控件在页面的显示顺序。 每个控件元素在数据表都有一个关联的单个字母。 l - 每页显示行数的控件f - 检索条件的控件…

程序员的思维修炼》读书笔记

PB15061359 王亚正 这本书主要是从思维角度上来写的&#xff0c;不具体针对到程序员如何写代码。我觉得这本书不仅仅适合程序员&#xff0c;其他对各行各业的人都同样适用。 书中首先讲了新手和专家的区别&#xff0c;一个需要靠规则&#xff0c;另一个则是靠感觉。 之后介绍了…

网络爬虫--10.使用正则表达式的爬虫

文章目录一. 前言二. 第一步&#xff1a;获取数据三. 第二步&#xff1a;筛选数据四. 第三步&#xff1a;保存数据五. 第四步&#xff1a;实现循环抓取一. 前言 现在拥有了正则表达式这把神兵利器&#xff0c;我们就可以进行对爬取到的全部网页源代码进行筛选了。 下面我们一…