标题:django contenttype framework | 作者: catfish | 时间:2019年12月03日
暂无法显示图片

ContentType框架

from django.contrib.contenttypes.models import ContentType

位置:django.contrib.contenttypes.models.ContentType

安装:在INSTALL_APP中自带

使用:记录管理界面每个对象的历史记录。将用户权限绑定到特定的模型。

ContentType类的表结构

contenttype类的表在你创建数据库后就已经存在了。这个表用于记录所有的app的数据类型。

class DjangoContentType(models.Model):
    app_label = models.CharField(max_length=100)    # app 名字 记录
    model = models.CharField(max_length=100)                       # app 内的表名

    class Meta:
        managed = False
        db_table = 'django_content_type'
        unique_together = (('app_label', 'model'),)

初始ContentType表里面的东西如下:

'''
1|admin|logentry
2|auth|permission
3|auth|group
4|auth|user
5|contenttypes|contenttype
6|sessions|session
'''

ContentType实例常用方法

model_class()返回该对象对应的类

>>> from django.contrib.contenttypes.models import ContentType
>>> a = ContentType.objects.first()
>>> a.model_class()
<class 'django.contrib.admin.models.LogEntry'>    # 返回该模型的类

ContentType.objects 方法

Content.objects.get_for_model(model)  

由类返回ContentType中记录的类


通用关系&多态关系

使用示例:

from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType
from django.db import models

class TaggedItem(models.Model):
    tag = models.SlugField()

    # 以下三行为常规操作,构建的每个类都要写。
    content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)         # ContentType型对象
    object_id = models.PositiveIntegerField()                              # 对象的id
    content_object = GenericForeignKey('content_type', 'object_id')                  # 表示原始对象。在admin中设置以上两个,或者只设置这一个。

    def __str__(self):
        return self.tag

GenericForeignKey

是一种特殊的数据类型,接受两个参数。如果绑定的两个名称是content_type和object_id,则可以不用传递,因为这是它的默认值。这个数据代表该类的指定类的实例化对象。

>>> from django.contrib.auth.models import User
>>> guido = User.objects.get(username='Guido')
>>> t = TaggedItem(content_object=guido, tag='bdfl')
>>> t.save()
>>> t.content_object

由于GenericForeignKey的特殊性,它不能用于塞选filter和exclude等操作。

GenericRelation类

通俗点讲,用于contenttype的反向关联。用法如下,与上文的表相互关联:

from django.contrib.contenttypes.fields import GenericRelation
from django.db import models

class Bookmark(models.Model)
    url = models.URLField()
    tags = GenericRelation(TaggedItem)

反向关联的使用如下:

>>> b = Bookmark(url='https://www.djangoproject.com/')
>>> b.save()
>>> t1 = TaggedItem(content_object=b, tag='django')
>>> t1.save()
>>> t2 = TaggedItem(content_object=b, tag='python')
>>> t2.save()
>>> b.tags.all()          # 反向关联
<QuerySet [<TaggedItem: django>, <TaggedItem: python>]>

附录

我写过一个contenttype好像出现了一个问题没有解决,最后用外键代替了contenttype行使相同的功能。终端操作数据保存数据都不变,一到后台操作数据就报错。出现这种错误之前好像是由于在删掉contenttype对象之前删掉了它所关联的对象。记录一下,有时间我再去试试,感兴趣的大佬可以尝试下,记得告诉我怎么处理这个错误,在此谢过。

我要评论

没有登录?请先登录后再评论

最新评论

暂无人评论,来抢个沙发吧!