django内置 Contenttypes 框架
一、什么是Django ContentTypes?
1、Django 包含一个ContentTypes 应用,它可以追踪安装在你的Django 项目里的所有应用,并提供一个高层次的、通用的接口用于与你的模型进行交互。
2、Django ContentTypes是由Django框架提供的一个核心功能,它对当前项目中所有基于Django驱动的model提供了更高层次的抽象接口。
3、Contenttypes 的核心应用是ContentType模型,存在于 django.contrib.contenttypes.models.ContentType。ContentType 的实例表示并存储你的项目当中安装的应用的信息,并且每当新的模型安装时会自动创建新的 ContentType 实例。
4、ContentType 实例具有返回它们表示的模型类的方法,以及从这些模型查询对象的方法。ContentType 还有一个自定义的管理器用于添加方法来与ContentType工作,以及用于获得ContentType实例的特定模型。
5、你的模型和ContentType 之间的关系还可以用于一个模型实例和任意一个已经安装的模型的实例建立“generic关联”。
二、Django ContentTypes做了什么?
1、当使用django-admin初始化一个django项目的时候,可以看到在默认的INSTALL_APPS已经包含了django.contrib.contenttypes:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
注释:1、注意django.contrib.contenttypes是在django.contrib.auth之后,这是因为auth中的permission系统是根据contenttypes来实现的。
2、Contenttypes 框架包含在django-admin startproject 创建的默认的INSTALLED_APPS列表中
3、Admin 应用使用它来记录通过Admin 界面添加或更改每个对象的历史。
4、Django 的authentication 框架用它来授用户权限给特殊的模型。
2、关于django.contrib.contenttypes.models文件:
class ContentType(models.Model):
app_label = models.CharField(max_length=100)
model = models.CharField(_('python model class name'), max_length=100)
objects = ContentTypeManager()
class Meta:
verbose_name = _('content type')
verbose_name_plural = _('content types')
db_table = 'django_content_type'
unique_together = (('app_label', 'model'),)
def __str__(self):
return self.name
注释:可以看出ContentType就是一个简单的django model,而且它在数据库中的表的名字为django_content_type。
3、有经验的Django开发者对于这个表的名字一般都不会陌生,在第一次对Django的model进行migrate之后,就可以发现在数据库中出现了一张默认生成的名为django_content_type的表。
如果没有建立任何的model,默认django_content_type是这样的:
sqlite> select * from django_content_type;
1|admin|logentry
2|auth|group
3|auth|user
4|auth|permission
5|contenttypes|contenttype
6|sessions|session 注释:1、django_content_type记录了当前的Django项目中所有model所属的app(即app_label属性)以及model的名字(即model属性)。
2、每一个ContentType 实例有两个字段,共同来唯一描述一个已经安装的模型。
app_label:模型所在的应用的名称。 这取自模型的app_label 属性,并只包括应用的Python 导入路径的最后的部分。例如,"django.contrib.contenttypes"的app_label 是"contenttypes"。
model:模型的类的名称。
4、django_content_type并不只是记录属性这么简单,contenttypes其实是对model的一次封装,因此可以通过contenttypes动态的访问model类型,而不需要每次import具体的model类型。
1、ContentType实例提供的接口
ContentType.model_class() # 获取当前ContentType类型所代表的模型类
ContentType.get_object_for_this_type() #使用当前ContentType类型所代表的模型类做一次get查询 2、ContentType管理器(manager)提供的接口
ContentType.objects.get_for_id() #通过id寻找ContentType类型,这个跟传统的get方法的区别就是它跟get_for_model共享一个缓存,因此更为推荐。
ContentType.objects.get_for_model() #接收一个模型类或模型的实例,并返回表示该模型的ContentType实例
ContentType.objects.get_for_models()
三、Django ContentTypes的使用方法
1、每一个 ContentType 都有一些方法允许你用ContentType实例来到达它所代表的model, 或者从model取出对象:
- ContentType.get_object_for_this_type(**kwargs)[source] #接收ContentType 表示的模型所接收的查询参数,对该模型做一次get() 查询,然后返回相应的对象。
- ContentType.model_class()[source] #返回此ContentType 实例所表示的模型类。
示例:
例如,我们可以查找User 模型的ContentType︰ >>> from django.contrib.contenttypes.models import ContentType
>>> user_type = ContentType.objects.get(app_label="auth", model="user")
>>> user_type
<ContentType: user> 然后使用它来查询一个特定的User,或者访问 User 模型类︰ >>> user_type.model_class()
<class 'django.contrib.auth.models.User'>
>>> user_type.get_object_for_this_type(username='Guido')
<User: Guido>
2、ContentTypeManager(自定义的管理器ContentTypeManager)
clear_cache()#清除ContentType 用于跟踪模型的内部缓存,它已为其创建ContentType 实例。你可能不需要自己调用此方法;Django 将在它需要的时候自动调用。
get_for_id(id) #通过ID查找ContentType。由于此方法使用与get_for_model() 相同的共享缓存,建议使用这个方法而不是通常的 ContentType.objects.get(pk=id)
get_for_model(model[, for_concrete_model=True])#接收一个模型类或模型的实例,并返回表示该模型的ContentType 实例。for_concrete_model=False 允许获取代理模型的ContentType
get_for_models(*models[, for_concrete_models=True])#接收可变数目的模型类,并返回一个字典,将模型类映射到表示它们的ContentType 实例。for_concrete_model=False 允许获取代理模型的ContentType。
-
- get_by_natural_key(app_label, model)#返回由给定的应用标签和模型名称唯一标识的ContentType 实例。这种方法的主要目的是为允许ContentType 对象在反序列化期间通过自然键来引用。
四、ContentType的通用类型
假设以下的应用场景:
class Coupon(models.Model):
"""优惠券生成规则
ID 优惠券名称 A FK B.FK c.FK
1 通用 null null
2 满100-10 8 1
3 满200-30 8 2
4 满200-30 9 1 ID 优惠券名称 content_type_id(表) object_id(表中数据ID)
1 通用 null null
2 满100-10 8 1
3 满200-30 8 2
4 满200-30 9 1
总结:
"""
name = models.CharField(max_length=64, verbose_name="活动名称")
brief = models.TextField(blank=True, null=True, verbose_name="优惠券介绍") # 那个表?
content_type = models.ForeignKey(ContentType, blank=True, null=True)
# 对象ID
object_id = models.PositiveIntegerField("绑定课程", blank=True, null=True, help_text="可以把优惠券跟课程绑定") content_object = GenericForeignKey('content_type', 'object_id')
#content_object = fields.GenericForeignKey() #应该可以这么写注释:ContentType提供了一种GenericForeignKey的类型,通过这种类型可以实现在Comment对其余所有model的外键关系。
一张表和其他多个表管理,并创建多个FK时,并且多个Fk只能选择其中一个时,可以用ContentType。
通过使用一个content_type属性代替了实际的model,而object_id则代表了实际model中的一个实例的主键,其中,content_type和object_id的字段命名都是作为字符串参数传进content_object的。
django内置 Contenttypes 框架的更多相关文章
- 框架----Django内置Admin
Django内置的Admin是对于model中对应的数据表进行增删改查提供的组件,使用方式有: 依赖APP: django.contrib.auth django.contrib.contenttyp ...
- Django内置Admin
Django内置的Admin是对于model中对应的数据表进行增删改查提供的组件,使用方式有: 依赖APP: django.contrib.auth django.contrib.contenttyp ...
- Django内置信号
阅读目录(Content) Django中内置的signal 自定义信号 1.定义信号 2.注册信号 3.触发信号 回到顶部(go to top) Django中内置的signal Django中提供 ...
- Django内置Admin解析
Django 内置的admin是对于model中对应的数据表进行增删改查提供的组建 一.Django admin的内部依赖: 依赖的app django.contrib.auth django.con ...
- django 内置“信号”机制和自定义方法
一.引子 在操作数据的时候,假设我们需要记录一些日志,这个时候,我们需要用什么来显示这个需求呢?装饰器?装饰器只能先实现整体的操作.在django 里面有这么一个东西--信号 下面我们就来了解了解它. ...
- Django内置分页
一.django内置分页 from django.shortcuts import render from django.core.paginator import Paginator, EmptyP ...
- Django 内置分页器
先导入Django内置的分页器 在商品列表页或者购物车列表页导入 在渲染list.html导入 然后在views后台渲染方法写入 打开list页面结果
- Django内置权限扩展案例
当Django的内置权限无法满足需求的时候就自己扩展吧~ 背景介绍 overmind项目使用了Django内置的权限系统,Django内置权限系统基于model层做控制,新的model创建后会默认新建 ...
- Spark2.1.0——内置Web框架详解
Spark2.1.0——内置Web框架详解 任何系统都需要提供监控功能,否则在运行期间发生一些异常时,我们将会束手无策.也许有人说,可以增加日志来解决这个问题.日志只能解决你的程序逻辑在运行期的监控, ...
随机推荐
- [android] AndroidManifest.xml【 manifest -> uses-permission】
在 API Level 1 时被引入 简介: 在某些情况下,你为app设置的权限将会影响到google应用商店会用何种规则来过滤你的APP. 如果你需要一个硬件相关的权限——CAMERA,googl ...
- Hadoop、Pig、Hive、NOSQL 学习资源收集
转自:http://www.cnblogs.com/zzjhn/p/3855566.html (一)hadoop 相关安装部署 1.hadoop在windows cygwin下的部署: http:// ...
- 【BZOJ】1620: [Usaco2008 Nov]Time Management 时间管理(贪心)
http://www.lydsy.com/JudgeOnline/problem.php?id=1620 一开始想不通啊.. 其实很简单... 每个时间都有个完成时间,那么我们就从最大的 完成时间的开 ...
- 转载 -- iOS中SDK的简单封装与使用
一.功能总述 在博客开始的第一部分,我们先来看一下我们最终要实现的效果.下图中所表述的就是我们今天博客中要做的事情,下方的App One和App Two都植入了我们将要封装的LoginSDK, 两个A ...
- Hadoop单机安装配置过程:
1. 首先安装JDK,必须是sun公司的jdk,最好1.6版本以上. 最后java –version 查看成功与否. 注意配置/etc/profile文件,在其后面加上下面几句: export JAV ...
- 一个简单的ServletContextListener示例
ServletContext可以初始化String类型的参数.但是,如果你希望应用初始化参数是一个数据库DataSource呢?上下文参数只能是String.毕竟,你不能把一个Dog对象塞到XML部署 ...
- JS-textarea限制输入字数
解决办法: #descrip 是textarea的id,字数小于40: $("#descrip").on('input',function(event) { if ($(" ...
- VS2013新特性
大家可能看到我这边颜色和字体和原本不同,这里特意分享给大家背景护眼色值(这对每天看电脑的程序员很重要对不对!)还有字体: 工具-选项-字体和颜色:在项背景点击自定义-色调85 饱和度123 亮度205 ...
- Jquery判断某个标签 Id是否存在
query判断某个标签 Id是否存在, 如果是下面的 jQuery 代码判断一个对象是否存在,是不能用的 if($("#id")){}else{} 因为 $(“#id”) 不管对象 ...
- LAMP集群项目二 初始化系统
1.关闭防火墙 /etc/init.d/iptables stop chkconfig iptables off 2.关闭selinux cat /etc/selinux/config #查看状态 s ...