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 提供 ...
随机推荐
- 对javascript中call()方法的理解
call ( thisObj [, arg1 [, arg2 [, [, argN] ] ] ]) call()方法:官方介绍是,调用一个对象的一个方法,以另一个对象替换当前对象. call()方法 ...
- vs 远程调试
程序在vs安装目录: D:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\Remote Debugge ...
- javascript应该嵌入到html中的什么位置
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- k8s 运行应用
一.deployment 创建过程 kubect创建deployment —> deployment 创建ReplicaSet—>根据ReplicaSet 创建Pod 命名方式 relic ...
- springcolud 的学习(一),架构的发展史
一.传统架构 传统的SSH架构,分为三层架构 web控制层.业务逻辑层.数据库访问层. 传统架构也就是单点应用,就是大家在刚开始初学JavaEE技术的时候SSH架构或者SSM架构,业务没有进行拆分,都 ...
- Win10家庭版升级到企业版的方法
一.家庭版升级企业版 1.右键单击[此电脑]——>属性 2.点击更改产品密钥 3.输入密钥:NPPR9-FWDCX-D2C8J-H872K-2YT43 4.点击下一步,验证结束后点击开始升级,然 ...
- Source roots (or source folders) Test source roots (or test source folders; shown as rootTest)Resource rootsTest resource roots
idea中Mark Directory As里的Sources Root.ReSources Root等的区别 1.Source roots (or source folders) 通过这个类指定一个 ...
- MSP---助力企业轻松上云
一.企业上云的总体步骤 1.传统企业级应用上云方法论概述 2.应用现代化概念 3.应用上云都需要什么 1.评估该应用是否可以上云, 2.上云需要付出多少时间和人力 3.企业级应用案例 4.生成评估报告 ...
- Error creating bean with name 'XXX' defined in file
这个错误是我在之前操作时,错将另一个dubbo服务器也加载到了该dubbo服务器上(pom.xml),所以出现了Error creating bean with name 'XXX' defined ...
- 关于justify-content属性的再学习(区分三个属性)
justify-content属性: 用来表示可伸缩项目在主轴方向上的对齐方式: 取值范围为flex-start,flex-end,center,space-between,space-around: ...