什么是Django ContentTypes?
Django ContentTypes是由Django框架提供的一个核心功能,它对当前项目中所有基于Django驱动的model提供了更高层次的抽象接口。
然而,对于Django ContentTypes不熟悉的人来说,上面这句话说了跟没说一样,因此,笔者将一步一步解释Django ContentTypes在Django框架中做了什么,以及如何使用Django ContentTypes。
当然,如果对于ContentTypes有了初步了解而只是不了解它的应用场景,可以直接查阅以下这两个链接:
- Django official documentation:The contenttypes framework
- stackoverflow: How exactly do Django content types work?
Django ContentTypes做了什么?
当使用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',
]
而且注意django.contrib.contenttypes是在django.contrib.auth之后,这是因为auth中的permission系统是根据contenttypes来实现的。
笔者紧接着查阅了一下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。
有经验的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
因此,django_content_type记录了当前的Django项目中所有model所属的app(即app_label属性)以及model的名字(即model属性)。
当然,django_content_type并不只是记录属性这么简单,在一开始的时候笔者就提及了contenttypes是对model的一次封装,因此可以通过contenttypes动态的访问model类型,而不需要每次import具体的model类型。
- ContentType实例提供的接口
- ContentType.model_class()
- 获取当前ContentType类型所代表的模型类
- ContentType.get_object_for
- ContentType.model_class()