Django contenttypes组件
时间:2019-10-19
本文章向大家介绍Django contenttypes组件,主要包括Django contenttypes组件使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
contenttypes组件
介绍
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_content_type的表。
表结构如下图所示:
其中,app_label字段存储了APP的名称,model字段存储了APP下的具体的模型类的名称。
应用场景
我们在网上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项目中的表名都存储在一个表里面。然后评论表里外键关联这个表就可以了。
这个时候我们就用上了前面讲到的contenttypes,借助contenttypes我们就能够在创建Comment的时候再决定和Post关联还是和Picture关联。
在models.py中使用django.contrib.contenttypes中提供的特殊字段GenericForeignKey来实现:
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='123') user_2 = User.objects.create_user(username='bbb', password='123') user_3 = User.objects.create_user(username='ccc', password='123') 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)
接下来如果我们想要查看某篇帖子或者某个照片的所有评论,这个时候就可以用上另外一个工具--GenericRelation了。
from django.contrib.contenttypes.fields import GenericRelation
修改models.py中的Post和Picture,添加用于反向查询的comments字段:
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()
原文地址:https://www.cnblogs.com/XLHIT/p/11704426.html
- 【团队分享】苍翼之刃:论File Descriptor泄漏如何导致Crash?
- 【沙龙干货分享】你要知道的N个Android适配问题
- 优化安卓应用内存的神秘方法以及背后的原理,一般人我不告诉他
- 安全快速下载Xcode的姿势
- Android之实现妙趣横生的粘连布局
- 萝莉有话说:你的App真正适配了iOS 9吗?
- H5 缓存机制浅析 移动端 Web 加载性能优化
- Android 开发必备知识:我和 Gradle 有个约会
- dex分包变形记
- 手把手教你如何分析 iOS 系统栈 crash
- 通往全栈工程师的捷径 —— React
- GLC - glog 日志清理类库
- Go发起Http请求及获取相关参数
- Go语言并发模型的2种编程方案
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 实现浏览器中的最大请求并发数控制
- 【漏洞复现】Weblogic漏洞搭建与复现:CVE-2018-2894 任意文件上传
- 终于把进程和线程学会了
- 对方向你转账60元--三角函数方法精确位的实现
- 牛客网-树的子结构
- 牛客网-删除链表中重复的节点
- 牛客网-包含min函数的栈
- 牛客网-反转链表
- 牛客网-替换空格
- 手把手教你破解文件密码、wifi密码、网页密码
- 如何安装 Elastic 栈中的 Logstash
- 你的GitHub项目被封存到北极了吗?
- Logstash: 如何创建可维护和可重用的 Logstash 管道
- 手把手教你微信好友头像形成指定的文字
- Logstash: 应用实践 - 装载 CSV 文档到 Elasticsearch