Django ContentTypes框架使用场景
Django contenttypes是一个非常有用的框架,主要用来创建模型间的通用关系(generic relation)。不过由于其非常抽象,
理解起来并不容易。当你创建一个django项目的时候,可以看到在默认的INSTALL_APPS已经包含了django.contrib.contenttypes。
今天我们来重点讲下它的使用场景及如何使用django contenttypes。
# Application definition INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'app01.apps.App01Config',
]
Django ContentTypes框架使用场景
假设我们创建了如下模型,里面包含文章Post,Picture和评论Comment模型。
Comment可以是对Post的评论,也可以是对Picture的评论。
如果你还想对其它对象(比如回答,用户) 进行评论, 这样你将需要在comment对象里添加非常多的ForeignKey。
你的直觉会告诉你,这样做很傻,会造成代码重复和字段浪费。一个更好的方式是,只有当你需要对某个对象或模型进行评论时,
才创建comment与那个模型的关系。这时你就需要使用django contenttypes了。
from django.db import models
from django.contrib.auth.models import User # Create your models here. class Post(models.Model):
author = models.ForeignKey(User)
title = models.CharField(max_length=75)
body = models.TextField(blank=True) class Picture(models.Model):
author = models.ForeignKey(User)
image = models.ImageField()
caption = models.TextField(blank=True) class Comment(models.Model):
author = models.ForeignKey(User)
body = models.TextField(blank=True)
post = models.ForeignKey(Post, null=True)
picture = models.ForeignKey(Picture, null=True)
Django ContentType提供了一种GenericForeignKey的类型,通过这种类型可以指定content_object。修改过的comment模型如下图所示:
import ContentType
import GenericForeignKey class Comment(models.Model):
author = models.ForeignKey(User)
body = models.TextField(blank=True) content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey(content_type,object_id)
comment里加了3个字段:
content_type: 内容类型,代表了模型的名字(比如Post, Picture)
object_id: 传入对象的id
content_object: 传入的实例化对象,其包含两个属性content_type和object_id。
当你需要对某篇文章或某个图片进行评论时(建立评论关系),
你只需要将实例化的对象user, post或picture传入comment。
这样实现了按需建立评论关系。首先你先需要实例化对象。
user = User.objects.create_user(username='user1', password='')
post = Post.objects.create(author=user,
title='title1',
body='')
picture = Picture.objects.create(author=user,
image="default.png",
caption='picture1')
然后在views或者shell里,你可以按如下代码建立评论关系。
from foreign.models import Post, Picture, Common
>>> from django.contrib.auth.models import User
>>> user = User.objects.get(username='user1')
>>> post = Post.objects.get(title='title1')
>>> c = Comment.objects.create(author=user, body='', content_object=post)
>>> picture = Picture.objects.get(caption='picuture1')
>>> c1 = Comment.objects.create(author=user, body='', content_object=picture)
然而上述创建评论的方式我们并不推荐。
我们更希望直接从模型中获取或创建comment,
我们只需在模型中创建一个与Comment的GenericRelation即可。
注意该字段不会存储于数据库中。
from django.contrib.contenttypes.fields import GenericRelation class Post(models.Model):
author = models.ForeignKey(User)
title = models.CharField(max_length=75)
body = models.TextField(blank=True)
comments = GenericRelation('Comment') class Picture(models.Model):
author = models.ForeignKey(User)
image = models.ImageField()
caption = models.TextField(blank=True)
comments = GenericRelation('Comment')
>>> me = User.objects.get(username='myusername')
>>> pic = Picture.objects.get(author=me)
>>> pic.comments.create(author=me, body="Man, I'm cool!")
>>> pic.comments.all()[<Comment: "Man, I'm cool!">]
值得注意的是,如果在Post中定义了GenericRelation,删除了一个post实例,
在Comment中所有与post相关实例也会被删除。GenericForeignKey不支持设置on_delete参数。
因此,如果对级联删除不满意的话就不要设置GenericRelation。
Django ContentTypes框架使用场景的更多相关文章
- Django contenttypes 框架详解
一.什么是Django ContentTypes? Django ContentTypes是由Django框架提供的一个核心功能,它对当前项目中所有基于Django驱动的model提供了更高层次的抽象 ...
- django内置 Contenttypes 框架
一.什么是Django ContentTypes? 1.Django 包含一个ContentTypes 应用,它可以追踪安装在你的Django 项目里的所有应用,并提供一个高层次的.通用的接口用于与你 ...
- Django contenttypes 应用
Django contenttypes 应用 什么是Django ContentTypes? Django ContentTypes是由Django框架提供的一个核心功能,它对当前项目中所有基于Dja ...
- Linux(CentOS7)系统中部署Django web框架
1. 概述 部署django和vue架在逻辑上可以分为web层与数据库层:web前端通过实现了WSGI协议的模块对python代码进行解析,而python代码中则通过特定于数据库的操作接口对数据库进行 ...
- 路飞学城知识点4之Django contenttypes 应用
Django contenttypes 应用 contenttypes 是Django内置的一个应用,可以追踪项目中所有app和model的对应关系,并记录在ContentType表中. 每当我们创建 ...
- Django+Celery框架自动化定时任务开发
本章介绍使用DjCelery即Django+Celery框架开发定时任务功能,在Autotestplat平台上实现单一接口自动化测试脚本.业务场景接口自动化测试脚本.App自动化测试脚本.Web自动化 ...
- 记Angular与Django REST框架的一次合作(1):分离 or 不分离,it's the question
前言:本次尝试源于我们内部的一个项目,由于前端逻辑比较复杂,就打算将前后端分开来开发.由于之前用Django开发过软件,对Angular.js(Angular 1.0版)也有一定的了解,因此就将技术路 ...
- 记Angular与Django REST框架的一次合作(2):前端组件化——Angular
注:这是这个系列的第二部分,主要集中在Angular的使用方面.之前使用过AngularJS(Angular 1.x),混在Django的模板中使用,这些页面一般完全是结果展示页.在有Django表单 ...
- 教程:Visual Studio 中的 Django Web 框架入门
教程:Visual Studio 中的 Django Web 框架入门 Django 是高级 Python 框架,用于快速.安全及可扩展的 Web 开发. 本教程将在 Visual Studio 提供 ...
随机推荐
- modbus汇总
ModBus协议简介及移植到STM32单片机 https://blog.csdn.net/silent123go/article/details/92440091 Modbus测试工具ModbusPo ...
- Oracle数据库基本知识-原理,实例,表空间,用户,表
1.数据库原理及sql 数据库:是人们存放数据,访问数据,操作数据的存储仓库. DB:数据库,按存储结构来组织,存储和管理的数据仓库 DBMS:数据库管理系统,管理数据库的软件 SQL:结构化查询语言 ...
- Linux 6 修改ssh默认远程端口号
linux 默认的ssh远程端口是22,有时默认端口会遭到别有用心的人们扫描或攻击,为了时我们的系统更加安全那就需要修改远程端口号 操作步骤:1.修改ssh_config配置文件 vim /etc/s ...
- Golang/Go goroutine调度器原理/实现【原】
Go语言在2016年再次拿下TIBOE年度编程语言称号,这充分证明了Go语言这几年在全世界范围内的受欢迎程度.如果要对世界范围内的gopher发起一次“你究竟喜欢Go的哪一点”的调查,我相信很多Gop ...
- docker save load export import的区别
export export命令用于持久化容器(不是镜像).所以,我们就需要通过以下方法得到容器ID: sudo docker ps -a 接着执行导出: sudo docker export < ...
- vim打开多个文件、同时显示多个文件、在文件之间切换
打开多个文件: 1.vim还没有启动的时候: 在终端里输入 vim file1 file2 ... filen便可以打开所有想要打开的文件 2.vim已经启动 输入 :open file 可以再打开 ...
- IEnumerable,ICollection,IList,List的使用
做C#的都知道:一类只能有一个继承类,但可以实现多个接口.这句话就告诉我们:IEnumerable,ICollection,IList,List区别了 首先我看看 IEnumerable: // ...
- Java自学-控制流程 结束外部循环
Java中结束外部循环 Java中如何结束外部for循环? 示例 1 : 结束当前循环 break; 只能结束当前循环 public class HelloWorld { public static ...
- 【开发笔记】- 在MySQL中 root账户被锁定怎么办
MySQL的账户被锁定怎么办? 用Navicat连接数据库报错如下: Access denied for user 'root'@'localhost' (using password:YES) 原因 ...
- 区块链会2020再次爆发,先学点DAPP压压惊,跟我一起学《区块链DApp入门实战》
区块链DApp正在经历市场洗礼,常言道,对抗动荡最稳妥的是稳扎稳打的技术学习,不能临时抱佛脚. 马化腾说:互联网会像水和电一样融入我们的生活.而区块链呢?它是价值互联网的基石,是未来必然的趋势,也会像 ...