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='')
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)
接下来如果我们想要查看某篇帖子或者某个照片的所有评论,这个时候就可以用上另外一个工具--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()

Django contenttypes 组件的更多相关文章

  1. Django contenttypes组件

    contenttypes组件 介绍 Django包含一个contenttypes应用程序(app),可以跟踪Django项目中安装的所有模型(Model),提供用于处理模型的高级通用接口. Conte ...

  2. python 全栈开发,Day98(路飞学城背景,django ContentType组件,表结构讲解)

    昨日内容回顾 1. 为什么要做前后端分离? - 前后端交给不同的人来编写,职责划分明确. - API (IOS,安卓,PC,微信小程序...) - vue.js等框架编写前端时,会比之前写jQuery ...

  3. Django - Xadmin 组件(一)

    Django - Xadmin 组件(一) Web 应用中离不开的就是后台管理, Django 自带的 admin 组件提供了一部分内容,但往往现实项目中会有更多的需求,所以自定义自己的后台管理就十分 ...

  4. 自定义 Django admin 组件

    摘要:学习 Django admin 组件,仿照源码的逻辑,自定义了一个简易的 stark 组件,实现类似 admin 的功能. 可自动生成 url 路由,对于model 有与之相应的配置类对象,可进 ...

  5. django Form组件

    django Form组件 Django的Form主要具有一下几大功能: 生成HTML标签 验证用户数据(显示错误信息) HTML Form提交保留上次提交数据 初始化页面显示内容 小试牛刀 1.创建 ...

  6. Django contenttypes 应用

    Django contenttypes 应用 什么是Django ContentTypes? Django ContentTypes是由Django框架提供的一个核心功能,它对当前项目中所有基于Dja ...

  7. 9.24 Django Form组件

    2018-9-23 20:10:04 这两天优化了自己图书管理系统 github 连接:https://github.com/TrueNewBee/pythonDemo 顺便整理了博客,写了好多总结, ...

  8. django -----分页器组件

    分页器组件 本文目录 1 Django的分页器(paginator)简介 2 应用View层 3 模版层 index.html 4 扩展 回到目录 1 Django的分页器(paginator)简介 ...

  9. contenttypes组件 (处理大量外键)

    介绍 Django contenttypes是一个非常有用的框架,主要用来创建模型间的通用关系(generic relation).   https://www.cnblogs.com/huchong ...

随机推荐

  1. npm私有仓库 配置verdaccio在docker环境

    前端开发过程中,少不了自己封装一些通用的包,但又不想放在公共的平台,所以搭建一个npm私有的仓库是很有必要的. 在这里简单介绍如何使用 verdoccio 在docker环境下的配置.verdocci ...

  2. java多线程(6)---ThreadLocal

    ThreadLocal 什么是ThreadLocal? 顾名思义它是local variable(线程局部变量).它的功用非常简单,就是为每一个使用该变量的线程都提供一个变量值的副本,是每一个线程都可 ...

  3. 使用ML.NET实现基于RFM模型的客户价值分析

    RFM模型 在众多的客户价值分析模型中,RFM模型是被广泛应用的,尤其在零售和企业服务领域堪称经典的分类手段.它的核心定义从基本的交易数据中来,借助恰当的聚类算法,反映出对客户较为直观的分类指示,对于 ...

  4. Owin学习笔记(一) Owin的前生今世

    ASP.NET框架至今为止已经存在了数十年了,大量的网站使用ASP.NET框架进行开发.随着网站应用开发技术的进步,  许多网站应用开发框架有了新的流行趋势 轻量化 模块化 可移植 ASP.NET框架 ...

  5. 前端笔记之JavaScript(十二)缓冲公式&检测设备&Data日期

    一.JavaScript缓冲公式ease 原生JS没有自己的缓冲公式,但是你要自己推理的话,必须要懂一些数学和物理公式: 让div用100毫秒(帧),从left100px的位置变化到left800px ...

  6. nodejs接收get参数和post参数

    get请求用query //http://localhost:3000?a=3&b=4&c=5 router.get('/', function (req, res, next) { ...

  7. Hibernate【inverse和cascade属性】知识要点

    Inverse属性 Inverse属性:表示控制权是否转移.. true:控制权已转移[当前一方没有控制权] false:控制权没有转移[当前一方有控制权] Inverse属性,是在维护关联关系的时候 ...

  8. web前端安全

    之前对web前端安全进行了总结,想给大家分享一下,有不对的地方,大家多多交流,由于写在了PPT上,只好给大家一张一张粘上来,希望大家不要在意,了解知识为主

  9. 多线程(5)async&await

    .net 4.0的Task已经让我们可以非常简单地使用多线程,并且可以有返回值,也可以支持线程的取消等操作,可谓已经很强大了.但.net 4.5为我们带来了async&await,使得实现多线 ...

  10. C#设计模式之二十一访问者模式(Visitor Pattern)【行为型】

    一.引言 今天我们开始讲“行为型”设计模式的第九个模式,该模式是[访问者模式],英文名称是:Visitor Pattern.如果按老规矩,先从名称上来看看这个模式,我根本不能获得任何对理解该模式有用的 ...