Django之ContentType理解应用

Django ContentType是由Django框架提供的一个核心功能,对当前项目中所有基于Django驱动的model提供了更高层次的抽象接口

  • 为什么要使用它?

    假设我们创建了如下模型,里面包含文章Post,Picture和评论Comment模型。Comment可以是对Post的评论,也可以是对Picture的评论。如果你还想对其它对象(比如回答,用户) 进行评论, 这样你将需要在comment对象里添加非常多的ForeignKey。你的直觉会告诉你,这样做很傻,会造成代码重复和字段浪费。一个更好的方式是,只有当你需要对某个对象或模型进行评论时,才创建comment与那个模型的关系。这时你就需要使用django contenttypes
    –>即指定对象获模型具有这个表的内容,进行联系
  • ContentType
    其就是一个简单的mode模型,其在数据库中表的名字为django_content_type
#源码
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'),)

django_content_type记录了当前的Django项目中所有model所属的app(即app_label属性)以及model的名字(即model属性)。

在这里插入图片描述

可以通过contenttypes动态的访问model类型,而不需要每次import具体的model类型。

ContentType实例提供的接口

  • ContentType.model_class()
    获取当前ContentType类型所代表的模型类
  • ContentType.get_object_for_this_type()
    使用当前ContentType类型所代表的模型类做一次get查询

ContentType管理器(manager)提供的接口

  • ContentType.objects.get_for_id()
    通过id寻找ContentType类型,这个跟传统的get方法的区别就是它跟get_for_model共享一个缓存,因此更为推荐。
  • ContentType.objects.get_for_model()
    通过model或者model的实例来寻找ContentType类型

使用contenttypes

  • 在model中定义ForeignKey字段,并关联到ContentType表。通常这个字段命名为“content_type”
  • 在model中定义PositiveIntegerField字段,用来存储关联表中的主键。通常这个字段命名为“object_id”
  • 在model中定义GenericForeignKey字段,传入上述两个字段的名字。
  • 也可添加其余字段,作为model的属性
from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType
class ReadDetail(models.Model):
    content_type = models.ForeignKey(ContentType, on_delete=models.DO_NOTHING)#必须
    object_id = models.PositiveIntegerField()#必须
    content_object = GenericForeignKey('content_type', 'object_id')#必须
    date = models.DateField(default=timezone.now)#自添加字段
    read_num = models.IntegerField(default=0)#自添加字段
from django.contrib.contenttypes.models import ContentType
blog=Blog()#实例化Blog是model类
blog_content_type=ContentType.objects.get_for_model(blog)
#通过model或者model的实例来寻找ContentType类型
readnum, created = ReadNum.objects.get_or_create(content_type=blog_content_type, object_id=3)
#创建ReadDetail 实例 get_or_create 如果由这个对象就获取readnum,没有则创建这个对象 返回的是 (obj,Trye|False)
readnum.read_num=3
readnem.save()
 #我们就通过ContentType关联到对应的model,并可获其操作.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值