contenttypes组件 (处理大量外键)
介绍
http://www.pythontip.com/blog/post/10673/
Django包含一个contenttypes应用程序(app),可以跟踪Django项目中安装的所有模型(Model),提供用于处理模型的高级通用接口。
Contenttypes应用的核心是ContentType模型,位于django.contrib.contenttypes.models.ContentType。 ContentType的实例表示并保存项目中安装的模型的信息,每当有新的模型时会自动创建新的ContentType实例。只要使用django-admin startproject 命令创建的Django项目(PyCharm创建Django项目同理),默认都会在settings.py的INSTALLED_APPS列表中安装好django.contrib.contenttypes。



Django ContentTypes框架使用场景
假设我们创建了如下模型,里面包含文章Post,Picture和评论Comment模型。Comment可以是对Post的评论,也可以是对Picture的评论。如果你还想对其它对象(比如回答,用户) 进行评论, 这样你将需要在comment对象里添加非常多的ForeignKey。你的直觉会告诉你,这样做很傻,会造成代码重复和字段浪费。一个更好的方式是,只有当你需要对某个对象或模型进行评论时,才创建comment与那个模型的关系。这时你就需要使用django contenttypes了。
我们在网上po一段散文诗也可以po一张旅途的风景图,文字可以被评论,图片也可以被评论。我们需要在数据库中建表存储这些数据,我们可能会设计出下面这样的表结构。

class Post(models.Model):
"""帖子表"""
author = models.ForeignKey(User)
title = models.CharField(max_length=72) class Picture(models.Model):
"""图片表"""
author = models.ForeignKey(User)
image = models.ImageField() class Comment(models.Model):
"""评论表"""
author = models.ForeignKey(User)
content = models.TextField()
post = models.ForeignKey(Post, null=True, blank=True, on_delete=models.CASCADE)
picture = models.ForeignKey(Picture, null=True, blank=True, on_delete=models.CASCADE)

这表结构看起来不太简洁,我们画个图来看一下:
能用是能用,但是评论表有点冗余啊。好多列都空着呢啊!
我们优化一下,我们在评论表里不直接外键关联 文字和图片,而是存储一下关联的表名和字段,这样就好很多了。
看下图:
那我们不妨步子再大一点,再往前走一步试试,因为表名在评论里面重复了很多次,我们完全可以把Django项目中的表名都存储在一个表里面。然后评论表里外键关联这个表就可以了。

class Comment(models.Model):
"""评论表"""
author = models.ForeignKey(User)
content = models.TextField() content_type = models.ForeignKey(ContentType) # 外键关联django_content_type表
object_id = models.PositiveIntegerField() # 关联数据的主键
content_object = GenericForeignKey('content_type', 'object_id')

contenttypes使用

import os if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "about_contenttype.settings") import django
django.setup() from app01.models import Post, Picture, Comment
from django.contrib.auth.models import User
# 准备测试数据
user_1 = User.objects.create_user(username='aaa', password='')
user_2 = User.objects.create_user(username='bbb', password='')
user_3 = User.objects.create_user(username='ccc', password='') post_1 = Post.objects.create(author=user_1, title='Python入门教程')
post_2 = Post.objects.create(author=user_2, title='Python进阶教程')
post_3 = Post.objects.create(author=user_1, title='Python入土教程') picture_1 = Picture.objects.create(author=user_1, image='小姐姐01.jpg')
picture_2 = Picture.objects.create(author=user_1, image='小姐姐02.jpg')
picture_3 = Picture.objects.create(author=user_3, image='小哥哥01.jpg') # 给帖子创建评论数据
comment_1 = Comment.objects.create(author=user_1, content='好文!', content_object=post_1)
# 给图片创建评论数据
comment_2 = Comment.objects.create(author=user_2, content='好美!', content_object=picture_1)

from django.contrib.contenttypes.fields import GenericRelation

class Post(models.Model):
"""帖子表"""
author = models.ForeignKey(User)
title = models.CharField(max_length=72) comments = GenericRelation('Comment') # 支持反向查找评论数据(不会在数据库中创建字段) class Picture(models.Model):
"""图片表"""
author = models.ForeignKey(User)
image = models.ImageField() comments = GenericRelation('Comment') # 支持反向查找评论数据(不会在数据库中创建字段)

查询示例:
post_1 = Post.objects.filter(id=1).first()
comment_list = post_1.comments.all()
contenttypes组件 (处理大量外键)的更多相关文章
- Hibernate中映射一对一关联(按主键映射和外键映射)和组件映射
Hibernate中映射一对一关联(按主键映射和外键映射)和组件映射 Hibernate提供了两 ...
- Django contenttypes 组件
contenttypes组件 介绍 Django包含一个contenttypes应用程序(app),可以跟踪Django项目中安装的所有模型(Model),提供用于处理模型的高级通用接口. Conte ...
- Django contenttypes组件
contenttypes组件 介绍 Django包含一个contenttypes应用程序(app),可以跟踪Django项目中安装的所有模型(Model),提供用于处理模型的高级通用接口. Conte ...
- 基于MVC4+EasyUI的Web开发框架经验总结(9)--在Datagrid里面实现外键字段的转义操作
我们在使用EasyUI的时候,很多情况下需要使用到表格控件datagrid,这个控件控件非常强大,使用起来很简洁,但是我在使用中,发现对于一个表里面的外键字段进行转义,并显示引用表的一些名称的操作,却 ...
- DRF如何序列化外键的字段
我觉得在有些应用场景下,这个操作是有用的,因为可以减少一个AJAX的请求,以增加性能. 当然,是二次请求,还是一次传输.这即要考虑用户体验,还要兼顾服务器性能. 一切是有条件的平衡吧.就算是一次传输, ...
- python 全栈开发,Day116(可迭代对象,type创建动态类,偏函数,面向对象的封装,获取外键数据,组合搜索,领域驱动设计(DDD))
昨日内容回顾 1. 三个类 ChangeList,封装列表页面需要的所有数据. StarkConfig,生成URL和视图对应关系 + 默认配置 AdminSite,用于保存 数据库类 和 处理该类的对 ...
- PowerDesigner 12小技巧-pd小技巧-pd工具栏不见了-pd修改外键命名规则-pd添加外键
PowerDesigner 12小技巧-pd小技巧-pd工具栏不见了-pd修改外键命名规则-pd添加外键 1. 附加:工具栏不见了 调色板(Palette)快捷工具栏不见了PowerDesigner ...
- Django——ContentType(与多个表建立外键关系)及ContentType-signals的使用
一.ContentType 在django中,有一个记录了项目中所有model元数据的表,就是ContentType,表中一条记录对应着一个存在的model,所以可以通过一个ContentType表的 ...
- 使用ContentType处理大量的外键关系
问题分析 在之前的一个商城的项目中使用了mysql, 提到mysql就是外键, 多对多等等一系列的表关系 因为是一个商城的项目, 这里面有优惠券, 商品有很多的分类, 不同的商品又有不同的优惠券 其实 ...
随机推荐
- MariaDB 数据库索引详解(9)
MariaDB数据库管理系统是MySQL的一个分支,主要由开源社区在维护,采用GPL授权许可MariaDB的目的是完全兼容MySQL,包括API和命令行,MySQL由于现在闭源了,而能轻松成为MySQ ...
- linux shell实现批量关闭局域网中主机端口
假设局域网中有多台主机,只能开通ssh服务(端口22),如果发现其他服务打开,则全部关闭.通过运行一个shell脚本,完成以上功能.在实际运维中,可以通过puppet等工具更快更好的完成这个功能,所以 ...
- ubuntu16搭建harbor镜像库
参考 https://blog.csdn.net/qq_35720307/article/details/86691752 目的:搭建本地镜像库,方便快速的存放和拉取需要的镜像文件.
- Shell - 简明Shell入门10 - 管道(Pipe)
示例脚本及注释 #!/bin/bash echo '##### Number of *.conf : ' find /etc -name *.conf | grep system | wc -l ec ...
- 【xsy2272】 与运算 状压dp
题目大意:给你一个长度为$n$的序列$a$,我们定义$f_i$表示序列$a$前i项一次进行按位与运算后的值. 我们认为一个序列的价值为$\sum_{i=1}^{n}f_i$,现在你要重新排列序列$a$ ...
- odoo开发 相关知识点
(1)导入模块可以起别名: (2) 新的模型前端要调用显示有关联的另一个模型的相关字段 (3) 传递上下文 搜索视图打开默认按照接收的参数搜索显示: 发起端视图 上下文写法: 目标端 触发显示,搜索视 ...
- ES代码总结2
本文部分转载于: http://www.cnblogs.com/luxiaoxun/p/4869509.html ElasticSearch的基本用法与集群搭建 一.简介 ElasticSearch ...
- Sublime text3 Package Control不能使用
Package Control打开时提示"There are no availabel for installation"的两个处理办法: 第一种: ping一下sublime的服 ...
- java重点知识
一.java基本知识点 java是由SUN公司在1995年推出的,在2009年SUN公司又被甲骨文公司收购,所以甲骨文公司获得java版权.其底层是由C语言写的,java分为三个体系: JavaSE, ...
- Editplus php
一.配置PHP帮助手册 1.打开Editplus,[工具]-->[配置用户工具],在[添加工具]子菜单下选择[HTML帮助(*.chm)(T)],文件路径选择php的chm帮助文件路径. 这样在 ...