上一篇blog介绍到了那个 repository
,其中 trunk/libs.common/src/common/mptt/models.py
里有一个很有意思的叫做 Node 的 model。实现了一个叫 Modified Preorder Tree Traversal
的算法,相关内容还可以参考 这个
页面。
算
法细节刚才链接到的文章都讲得很详细了,吸引我注意的是代码中两个陌生的词语:ContentType,
GenericForeignKey。django 文档中 model-api 中对 GenericForeignKey
完全没有涉及,add_ons 中对 contenttype 的描述也只有简单的一句:
A light framework for hooking into "types" of content, where each installed
Django model is a separate content type. This is not yet documented.
通过 google 也只搜到了这么 一篇文章
,也只是泛泛而谈而已。经过研究,越发地感觉有意思了,于是写下心得,这么有意思的东西被埋没了可真可惜。
简
单得说,ContentType 就是一个 model,也就是一张数据表,其中保存着当前 project 中所有 models
的元数据,具体就是 name、app_label 和 model 三个字段,其中 app_label 和 model
这两个字符串组合起来便可以唯一标识一个 model 。通过调用 django.db.models.get_model(app_label,
model) 就可以获得该 model 类。
这样一个奇怪的 model 会有什么用处呢?可以设想一下,如果你需要一个和任意
model 都建立有关系的 model 时,你会怎么做?比如:用户评论! 假设你的 project
中有电影、有文章、有音乐等等内容,它们分别对应不同的 model
,而用户对它们每一种内容都可以进行评论,那么最简单的做法就是为每一种内容建立相应的评论表,比如:movie_comments,
article_comments 等。不过这种做法的弊端是很明显的:首先是增加了 model
的数量也增加了代码的复杂度;而且没有扩展性,增加其他内容的话还需要增加相应的 comments
表;还有就是统计用户所有评论的时候比较麻烦,需要在多个表中进行查询。
要是我们有了一个记录了项目中所有 model
的元数据的表,表中一条记录便对应着一个 model ,那么我们只要通过一个元数据表的 id 和 一个具体数据表中的 id ,便可以找到任何
model 中的任何记录。ContentType 正是这个表(不过有个前提就是:相关 model
的主键类型必须是相同的,使用django默认的主键就ok了)。
有了 ContentType ,我们的用户评论就只需要一个 model 就可以搞定!
下面开始介绍具体做法吧,首先通过执行以下命令
>django-admin.py startproject ContentType
创建一个 project。
然后修改 settings.py ,配置合适的数据库后端。
然后通过
>cd ContentType
>manage.py startapp contents
创建一个 app,修改 contents/models.py 如下:
from django.db import models
from django.contrib.contenttypes.models import ContentType
class Movie(models.Model):
title = models.CharField(maxlength=100)
class Article(models.Model):
title = models.CharField(maxlength=100)
class Music(models.Model):
title = models.CharField(maxlength=100)
class Comment(models.Model):
content_type = models.ForeignKey(ContentType)
object_id = models.IntegerField()
content_object = models.GenericForeignKey()
title = models.CharField(maxlength=100)
然后在 settings.py 的 INSTALLED_APPS 中加入:
"ContentType.contents",
执行命令:
>manage.py syncdb
然后执行:
>manage.py shell
现在就可以好好地享受享受劳动果实了。
>>> from ContentType.contents.models import *
>>> a = Article()
>>> a.title = 'article1'
>>> a.save()
>>> m = Movie()
>>> m.title = 'movie1'
>>> m.save()
>>> mu = Music()
>>> mu.title = 'music1'
>>> mu.save()
>>> c = Comment()
>>> c.content_object = a
>>> c.title = 'comment1'
>>> c.save()
>>> c = Comment()
>>> c.content_object = m
>>> c.title = 'comment2'
>>> c.save()
>>> c = Comment()
>>> c.content_object = mu
>>> c.title = 'comment3'
>>> c.save()
>>> for c in Comment.objects.all():
... print c.content_type,c.object_id
...
article 1
movie 1
music 1
>>> c.content_object.title
'music1'
还
有一个值得提一下的地方就是 Comment 的 content_object 字段。实际上根据上面的解释它只要有 content_type 和
object_id 两个字段就够了,不过你总是需要亲自指定两个字段的值。而 GenericForeignKey
出现的目的就是要把这个过程给自动化了,只要给 content_object 赋一个对象,就会自动得根据这个对象的元数据 ,给
content_type 和 object_id 赋值了。
GenericForeignKey 的构造函数接受两个可选参数:
def __init__(self, ct_field="content_type", fk_field="object_id"):
你可以在构造 GenericForeignKey 时指定另外的字段名称。
另外还有值得注意的一点就是:contenttype 的表是在 syncdb 时创建的,不过一开始其中并没有元数据,其中的数据是在需要的时候才添加上去的,正如你所想的,它使用的是get_or_create方法。
来源:http://codeplayer.blogspot.com/2006/09/django-contribs-contenttype.html
分享到:
相关推荐
一、引出问题 假如有这两张表,它们中的课程可能价格不一样、周期不一样、等等…不一样...这是因为 Django 本身就会新建 django_content_type 这张表,这张表就保存了 model 中的表名。 二、ContentType 那么怎么创
Django客户管理系统源码 Django客户管理系统源码 Django客户管理系统源码 Django客户管理系统源码 Django客户管理系统源码 Django客户管理系统源码 Django客户管理系统源码 Django客户管理系统...
django电子商务网站源码 django电子商务网站源码 django电子商务网站源码 django电子商务网站源码 django电子商务网站源码 django电子商务网站源码 django电子商务网站源码 django电子商务网站源码 django...
Django实现商城网站源码 Django实现商城网站源码 Django实现商城网站源码 Django实现商城网站源码 Django实现商城网站源码 Django实现商城网站源码 Django实现商城网站源码 Django实现商城网站源码 Django...
基于Django的个人网盘源码 基于Django的个人网盘源码 基于Django的个人网盘源码 基于Django的个人网盘源码 基于Django的个人网盘源码 基于Django的个人网盘源码 基于Django的个人网盘源码 基于Django...
Django auth 登陆后页面跳转至/account/profile,修改跳转至其他页面 这几天在学习django,django功能很强大,自带的auth,基本可以满足用户注册登陆登出,简单的用户注册登陆系统使用django auth足矣。当然也不是拿...
基于Django就业系统源码 基于Django就业系统源码 基于Django就业系统源码 基于Django就业系统源码 基于Django就业系统源码 基于Django就业系统源码 基于Django就业系统源码 基于Django就业系统源码 基于...
Django是Python编程语言中的一款强大且流行的Web框架,它以“快速开发”和“约定优于配置”的理念为核心,让开发者能够高效地构建高质量的Web应用程序。本笔记将深入探讨Django的基础概念、核心功能以及实际应用。 ...
前几天写的django 简易博客开发记录,贴个链接吧 django 简易博客开发 1 安装、创建、配置、admin使用 http://www.cnblogs.com/cacique/archive/2012/09/29/2707976.html django 简易博客开发 2 模板和数据查询 ...
django4最新中文文档+适合python初学或者初次接触django4的开发者 从事Python编程工作的人员,一定听说过这三个框架:Django、Flask、Tornado,它们就像神一样的存在 Django是最有代表性的一种。许多成功的网站和APP...
Django实现在线视频课堂播放网站源码 Django实现在线视频课堂播放网站源码 Django实现在线视频课堂播放网站源码 Django实现在线视频课堂播放网站源码 Django实现在线视频课堂播放网站源码 Django实现在线视频...
Django从零开发的个人博客网站源码 Django从零开发的个人博客网站源码 Django从零开发的个人博客网站源码 Django从零开发的个人博客网站源码 Django从零开发的个人博客网站源码 Django从零开发的个人博客...
使用 Django,我们在几分钟之内就可以创建高品质、易维护、数据库驱动的应用程序。 Django框架的核心组件有: 1、用于创建模型的对象关系映射 2、为最终用户设计的完美管理界面 3、一流的URL设计 4、设计者友好的...
2. **模型(Models)**:Django的核心之一就是ORM(对象关系映射),它允许开发者用Python类来定义数据库表结构。在模型文件中,我们可以定义字段、属性以及字段间的关系,如外键、一对多和多对多等。 3. **视图...
使用Django框架开发的企业OA管理系统源码 使用Django框架开发的企业OA管理系统源码 使用Django框架开发的企业OA管理系统源码 使用Django框架开发的企业OA管理系统源码 使用Django框架开发的企业OA管理系统源码 ...
本篇文章将详细探讨如何将两个强大的Python库——Django和Scrapy结合,以实现通过Django的Web界面控制Scrapy爬虫的运行,并将爬取的数据存入数据库。 首先,让我们了解这两个框架的基本概念。Django是一个高级的Web...
【Django_layui后台模板】是一个专门为Django框架设计的、基于Layui前端框架的后台管理模板。Django是Python开发的一款高级Web框架,它强调代码的可读性和简洁性,而Layui则是一款轻量级的前端UI框架,提供了丰富的...
基于DJango开发的仓库管理系统,软件架构:python 3.5、django 2.2、MySQL 基于DJango开发的仓库管理系统,软件架构:python 3.5、django 2.2、MySQL 基于DJango开发的仓库管理系统,软件架构:python 3.5、...
基于Django的疫情上报系统源码 基于Django的疫情上报系统源码 基于Django的疫情上报系统源码 基于Django的疫情上报系统源码 基于Django的疫情上报系统源码 基于Django的疫情上报系统源码 基于Django的...
这部分是Django的核心之一,让开发者能以Python的方式定义数据库结构。 【第一个视图函数】章节会引导读者创建并理解视图的逻辑,它是处理HTTP请求并返回HTTP响应的关键部分。读者将学习如何处理GET和POST请求,...