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 提供 ...
随机推荐
- Java基础教程(26)--反射
一.类 对于每一种类型的对象,Java虚拟机都会实例化一个java.lang.Class类的不可变实例.该实例提供了获取对象的运行时属性的方法,包括它的成员和类型信息.Class类还提供了创建新实 ...
- Python之路【第二十九篇】:django ORM模型层
ORM简介 MVC或者MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库,这极大的减轻了开发人员的 ...
- LeetCode 5071. 找出所有行中最小公共元素(Java)
题目:5071. 找出所有行中最小公共元素 给你一个矩阵 mat,其中每一行的元素都已经按 递增 顺序排好了.请你帮忙找出在所有这些行中 最小的公共元素. 如果矩阵中没有这样的公共元素,就请返回 -1 ...
- hadoop2.x大数据视频教程(十二天学会)
- php的json_encode第二个参数学习及应用
php5.4以上: json_encode($data, JSON_FORCE_OBJECT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); p ...
- 【简解】SP7556 Stock Charts
题目大意 给出一个折线图,有N条线段,你想要把这些线段分成几个集合,使得每个集合中任意两条线段不相交. 求最少集合数. 分析 喵帕斯:以下提及的所有折线均指横坐标在\([1,k]\)里的折线段. 思考 ...
- mysql执行顺序与join连接
mysql加载顺序 手写顺序 SELECT DISTINCT <select list> FROM <left_table> join <join_type> JO ...
- js-Date对象(九)
一.Date对象的创建1.new Date()[创建当前时间对象]eg: var date = new Date(); console.log(date); //Thu Jul 18 2019 18: ...
- Linux E667 同步失败
在使用Vim编辑/proc目录下的文件后,保存,显示"E667 同步失败" 原因 因为proc这个目录是一个虚拟文件系统,它放置的数据都是在内存中,本身不占有磁盘空间,所以使用Vi ...
- Celery:routing
参考:http://docs.celeryproject.org/en/latest/userguide/routing.html#guide-routing