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. [转帖]BurpSuite简介

    BurpSuite简介 https://bbs.ichunqiu.com/thread-54760-1-1.html BurpSuite ,这是一个辅助渗透的工具,可以给我们带来许多便利.Burp 给 ...

  2. 使用SSM搭建一个简单的crud项目

    使用SSM完成增删查改 前端使用到的技术:ajax,json,bootstrap等 完整项目地址:点这里GitHub 项目地址,可以在线访问 这一章节主要搭建SSM的环境. SpringMVC Spr ...

  3. C指针的一些小细节

    1  int *c;*c=4-->int *c;int b;c=&b;*c=4; 在使用指针之前,一定要将其初始化,当然,如果是赋予一个地址,就相当于使用的同时就进行了初始化.

  4. sublime text 疑难解决

    sublime text 白色边框方框解决方法 https://blog.csdn.net/weixin_43228019/article/details/82766316 Sublime Text提 ...

  5. aop 打印请求信息

    项目中使用 AOP 打印请求信息,打印响应信息.package com.example.aspect; import com.alibaba.fastjson.JSON;import com.goog ...

  6. Drools入门

    文章转载自:http://cwqcwq.iteye.com/blog/397869 一.背景知识:  1.什么是规则引擎  Java规则引擎起源于基于规则的专家系统,而基于规则的专家系统又是专家系统的 ...

  7. PTA A1016

    A1016 Phone Bills (25 分) 题目内容 A long-distance telephone company charges its customers by the followi ...

  8. python3的pip3安装

    ---恢复内容开始--- pip3的安装需要对应一整套python的编译工具库,所以安装好的pip3是这个样子: inear@Ai:~$ pip3 -V pip 18.1 from /usr/lib/ ...

  9. 1.ASP.NET Core 中向 Razor Pages 应用添加模型

    右键单击“RazorPagesMovie”项目 >“添加” > “新建文件夹”. 将文件夹命名为“Models”.右键单击“Models”文件夹. 选择“添加” > “类”. 将类命 ...

  10. angular复习笔记4-模板

    Angular复习笔记4-模板 简介 模板是一种自定义的标准化页面,通过模板和模板中的数据结合,可以生成各种各样的网页.在Angular中,模板的默认语言是HTML,几乎所有的HTML语法在模板中都是 ...