一、什么是Django ContentTypes?
Django ContentTypes是由Django框架提供的一个核心功能,它对当前项目中所有基于Django驱动的model提供了更高层次的抽象接口。 当然我们不是说的是http中的content-type!完全没有任何关系!
下面将一步一步解释Django ContentTypes在Django框架中做了什么,以及如何使用Django ContentTypes。
当然,如果对于ContentTypes有了初步了解而只是不了解它的应用场景,可以直接查阅一下原文档:
https://docs.djangoproject.com/en/1.10/ref/contrib/contenttypes/
二、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的model进行migrate之后,就可以发现在数据库中出现了一张默认生成的名为django_content_type的表。
如果没有建立任何的model,默认django_content_type是这样的:
因此,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_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类型
- ContentType.model_class()
三、Django ContentTypes的使用场景
在我们这个项目中各种商品的优惠卷就运用到了这个知识点:
假使我们models下有这几张表:
class Electrics(models.Model): #电器类 name = models.CharField(max_length=32) price= models.IntegerField(default=100) def __str__(self): return self.name class Foods(models.Model): #食物类 name = models.CharField(max_length=32) price = models.IntegerField(default=100) def __str__(self): return self.name class Clothes(models.Model): #衣服类 name = models.CharField(max_length=32) price= models.IntegerField(default=100) def __str__(self): return self.name class Coupon(models.Model): #优惠券 name = models.CharField(max_length=32) def __str__(self): return self.name
我们先来考虑一个问题,如何把这些商品和优惠卷相关联?
一种商品一个优惠卷,那我们就在表中加入一种商品的优惠券,就是一个一对多的ForeignKey,那么多个商品就有各种优惠卷,
但是一种商品的特定优惠卷在表结构中,就那个字段有值,别的不相关的记录为null,而且每增加一个商品,又要手动的去添加外键,
这是繁琐的!
所以我们就使用contenttypes 应用中提供的特殊字段GenericForeignKey,我们可以解决上面的问题:
只需要以下三步:
- 在model中定义ForeignKey字段,并关联到ContentType表。通常这个字段命名为“content_type”
- 在model中定义PositiveIntegerField字段,用来存储关联表中的主键。通常这个字段命名为“object_id”
- 在model中定义GenericForeignKey字段,传入上述两个字段的名字。
具体实例代码:
class Coupon(models.Model): name = models.CharField(max_length=32) content_type = models.ForeignKey(to=ContentType) # step 1 object_id = models.PositiveIntegerField() # step 2 content_object = GenericForeignKey('content_type', 'object_id') # step 3 def __str__(self): return self.name
这样的话不管表的数据都可以查询出来,而且添加新的商品的商品,也不需要动优惠券的源码。
但我们在查询的过程中,用ORM实在太繁琐了,所以还有一个反向查询的方法:
就是在每个商品中关联 绑定一个关系:
coupons = GenericRelation(to='Coupon') # 用于反向查询,不会生成表字段
这样我们就可以直接ORM的.coupons找相应的字段!
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
RTX 5090要首发 性能要翻倍!三星展示GDDR7显存
三星在GTC上展示了专为下一代游戏GPU设计的GDDR7内存。
首次推出的GDDR7内存模块密度为16GB,每个模块容量为2GB。其速度预设为32 Gbps(PAM3),但也可以降至28 Gbps,以提高产量和初始阶段的整体性能和成本效益。
据三星表示,GDDR7内存的能效将提高20%,同时工作电压仅为1.1V,低于标准的1.2V。通过采用更新的封装材料和优化的电路设计,使得在高速运行时的发热量降低,GDDR7的热阻比GDDR6降低了70%。
更新日志
- 方伊琪.1979-沙鸥(LP版)【星岛全音】【WAV+CUE】
- 蔡琴《醇厚嗓音》6N纯银SQCD【WAV+CUE】
- 陈曦《遇见HQCD》[WAV+CUE]
- 大提琴-刘欣欣《爱的问候》HDCD[WAV+CUE]
- 周耀辉/邓慧中《从什么时候开始》[320K/MP3][95.71MB]
- 周耀辉/邓慧中《从什么时候开始》[FLAC/分轨][361.29MB]
- 蒋荣宗《蒋荣宗ZONG x FOCA 夏日马戏节》[320K/MP3][89.28MB]
- 坣娜.1997-你怎么可以不爱我【巨石】【WAV+CUE】
- 群星.1992-暗恋桃花源电影原声带【滚石】【WAV+CUE】
- 林隆璇.1989-愤怒的情歌【巨石】【WAV+CUE】
- 勤琴《海上花》[DTS-WAV分轨]
- 群星《歌声有故事》[DTS-WAV分轨]
- [发烧人声]群星《邂逅》DTS-WAV
- 艻打绿《夏/狂热(苏打绿版)》[320K/MP3][106.42MB]
- 艻打绿《夏/狂热(苏打绿版)》[FLAC分轨][574.2MB]