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框架详解 任何系统都需要提供监控功能,否则在运行期间发生一些异常时,我们将会束手无策.也许有人说,可以增加日志来解决这个问题.日志只能解决你的程序逻辑在运行期的监控, ...
随机推荐
- [JS] jquery控件基本要点备份
(1)CDN Google CDN:<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min. ...
- 【BZOJ】1690: [Usaco2007 Dec]奶牛的旅行(分数规划+spfa)
http://www.lydsy.com/JudgeOnline/problem.php?id=1690 第一题不是水题的题.. 分数规划.. T-T 百度吧..http://blog.csdn.ne ...
- json 转 T
T test = JsonConvert.DeserializeObject<T>(json);(json.net)
- vue-cli打包构建时常见的报错解决方案
报错1:vue-cli项目本地npm run dev启动后,chrome打开是空白页 解决方案:将config下的index.js中的assetsPublicPath路径都设置为‘/’绝对路径 报错2 ...
- hdu 1022:Train Problem I(数据结构,栈,递归,dfs)
Train Problem I Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)T ...
- Oracle数据库sql 列转字符串行函数WMSYS.WM_CONCAT()
例.select TO_CHAR(WMSYS.WM_CONCAT(ID)) from patrol_data_content where patrol_unit_id = '1628D189543B ...
- 如何用sql语句复制一张表
如何用sql语句复制一张表 1.复制表结构及数据到新表 CREATE TABLE 新表 SELECT * FROM 旧表 这种方法会将oldtable中所有的内容都拷贝过来,当然我们可以用delete ...
- post 与get
GET:从服务器上获取数据,也就是所谓的查,仅仅是获取服务器资源,不进行修改. POST:向服务器提交数据,这就涉及到了数据的更新,也就是更改服务器的数据. 补充: PUT:PUT的英文含义是放置,也 ...
- 【BZOJ3648】寝室管理 树分治
[BZOJ3648]寝室管理 Description T64有一个好朋友,叫T128.T128是寄宿生,并且最近被老师叫过去当宿管了.宿管可不是一件很好做的工作,碰巧T128有一个工作上的问题想请T6 ...
- 【IIS】模块 DLL C:\Windows\System32\inetsrv\authcert.dll 未能加载。返回的数据为错误信息。
解决方案,check IIS --Client Certificate Mapping Authentication installed?