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框架使用场景的更多相关文章

  1. Django contenttypes 框架详解

    一.什么是Django ContentTypes? Django ContentTypes是由Django框架提供的一个核心功能,它对当前项目中所有基于Django驱动的model提供了更高层次的抽象 ...

  2. django内置 Contenttypes 框架

    一.什么是Django ContentTypes? 1.Django 包含一个ContentTypes 应用,它可以追踪安装在你的Django 项目里的所有应用,并提供一个高层次的.通用的接口用于与你 ...

  3. Django contenttypes 应用

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

  4. Linux(CentOS7)系统中部署Django web框架

    1. 概述 部署django和vue架在逻辑上可以分为web层与数据库层:web前端通过实现了WSGI协议的模块对python代码进行解析,而python代码中则通过特定于数据库的操作接口对数据库进行 ...

  5. 路飞学城知识点4之Django contenttypes 应用

    Django contenttypes 应用 contenttypes 是Django内置的一个应用,可以追踪项目中所有app和model的对应关系,并记录在ContentType表中. 每当我们创建 ...

  6. Django+Celery框架自动化定时任务开发

    本章介绍使用DjCelery即Django+Celery框架开发定时任务功能,在Autotestplat平台上实现单一接口自动化测试脚本.业务场景接口自动化测试脚本.App自动化测试脚本.Web自动化 ...

  7. 记Angular与Django REST框架的一次合作(1):分离 or 不分离,it's the question

    前言:本次尝试源于我们内部的一个项目,由于前端逻辑比较复杂,就打算将前后端分开来开发.由于之前用Django开发过软件,对Angular.js(Angular 1.0版)也有一定的了解,因此就将技术路 ...

  8. 记Angular与Django REST框架的一次合作(2):前端组件化——Angular

    注:这是这个系列的第二部分,主要集中在Angular的使用方面.之前使用过AngularJS(Angular 1.x),混在Django的模板中使用,这些页面一般完全是结果展示页.在有Django表单 ...

  9. 教程:Visual Studio 中的 Django Web 框架入门

    教程:Visual Studio 中的 Django Web 框架入门 Django 是高级 Python 框架,用于快速.安全及可扩展的 Web 开发. 本教程将在 Visual Studio 提供 ...

随机推荐

  1. PHP调用webServer接口遇到的坑

    昨天公司分配给我一个任务,写一个中转接口,目标接口是一个webservice类型的接口,平时没有接触过,然后遇到一些坑, 一般情况下,能在浏览器打开并显示数据的接口是直接可以使用 CURL或者file ...

  2. 虚拟机CentOS创建/使用快照

    快照 1.什么是快照 说的直白一点,就是创建一个备份.当执行了不可逆的错误操作后,可以通过快照用来恢复系统 2.创建快照的三种模式 挂载状态下创建快照 开机状态下创建快照 关机状态下创建快照 3.如何 ...

  3. golang微服务框架go-micro 入门笔记1.搭建 go-micro环境

    微服务的本质是让专业的人做专业的事情,做出更好的东西. golang具备高并发,静态编译等特性,在性能.安全等方面具备非常大的优势.go-micro是基于golang的微服务编程框架,go-micro ...

  4. 通过对比ASCII编码来理解Unicode编码

    Unicode是个规范,可以理解为一个索引表,世界上所有字符基本上在这个索引表中都能找到唯一一个数码与之对应,就像ASCII码表一样,也是一个规范,也可以看成是一个索引表,所有的英文字符都可以在这个索 ...

  5. Zipkin存储Sleuth信息实现调用链追踪的几种方法

    版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/alva_xu/article/detail ...

  6. 移动端开发rem布局之less+媒体查询布局的原理步骤和心得

    rem即是以html文件中font-size的大小的倍数rem布局的原理:通过媒体查询设置不同屏幕宽度下的html的font-size大小,然后在css布局时用rem单位取代px,从而实现页面元素大小 ...

  7. 表单提交学习笔记(三)—利用Request.Files上传图片并预览

    一.html页面如下 <div id="container"> <form id="myForm"> <p class=" ...

  8. sudo apt-get install libstdc++6

    sudo apt-get install libstdc++6 yum install  libncurses.so.5 sudo apt-get install libncurses.so.5 su ...

  9. 【转载】JAVA SpringBoot 项目打成jar包供第三方引用自动配置(Spring发现)解决方案

    JAVA SpringBoot 项目打成jar包供第三方引用自动配置(Spring发现)解决方案 本文为转载,原文地址为:https://www.cnblogs.com/adversary/p/103 ...

  10. 用StatSVN统计svn项目中每人代码提交量

    用StatSVN统计SVN服务器项目的代码量 下载并安装SVN统计工具StatSVN 1)下载地址:sourceforge.net/projects/statsvn/ 2)解压压缩包,到一个目录,如D ...