国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Python > 正文

Django contenttypes 框架詳解(小結)

2020-01-04 14:56:05
字體:
來源:轉載
供稿:網(wǎng)友

一、什么是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已經(jīng)包含了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系統(tǒng)是根據(jù)contenttypes來實現(xiàn)的。

我們來查詢查閱了一下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,而且它在數(shù)據(jù)庫中的表的名字為django_content_type。

這個表的名字一般都不會陌生,在第一次對Django的model進行migrate之后,就可以發(fā)現(xiàn)在數(shù)據(jù)庫中出現(xiàn)了一張默認生成的名為django_content_type的表。

如果沒有建立任何的model,默認django_content_type是這樣的:

Django,contenttypes

因此,django_content_type記錄了當前的Django項目中所有model所屬的app(即app_label屬性)以及model的名字(即model屬性)。

當然,django_content_type并不只是記錄屬性這么簡單,contenttypes是對model的一次封裝,

因此可以通過contenttypes動態(tài)的訪問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類型,這個跟傳統(tǒng)的get方法的區(qū)別就是它跟get_for_model共享一個緩存,因此更為推薦。
    • ContentType.objects.get_for_model()
      • 通過model或者model的實例來尋找ContentType類型

三、Django ContentTypes的使用場景

在我們這個項目中各種商品的優(yōu)惠卷就運用到了這個知識點:

假使我們models下有這幾張表:

class Electrics(models.Model): #電器類  name = models.CharField(max_length=32)  price= models.IntegerField(default=100)  def __str__(self):    return self.nameclass Foods(models.Model):   #食物類  name = models.CharField(max_length=32)  price = models.IntegerField(default=100)  def __str__(self):    return self.nameclass Clothes(models.Model):  #衣服類  name = models.CharField(max_length=32)  price= models.IntegerField(default=100)  def __str__(self):    return self.nameclass Coupon(models.Model):  #優(yōu)惠券  name = models.CharField(max_length=32)  def __str__(self):    return self.name

我們先來考慮一個問題,如何把這些商品和優(yōu)惠卷相關聯(lián)?

一種商品一個優(yōu)惠卷,那我們就在表中加入一種商品的優(yōu)惠券,就是一個一對多的ForeignKey,那么多個商品就有各種優(yōu)惠卷,

但是一種商品的特定優(yōu)惠卷在表結構中,就那個字段有值,別的不相關的記錄為null,而且每增加一個商品,又要手動的去添加外鍵,

這是繁瑣的!

所以我們就使用contenttypes 應用中提供的特殊字段GenericForeignKey,我們可以解決上面的問題:

只需要以下三步:

  • 在model中定義ForeignKey字段,并關聯(lián)到ContentType表。通常這個字段命名為“content_type”
  • 在model中定義PositiveIntegerField字段,用來存儲關聯(lián)表中的主鍵。通常這個字段命名為“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

這樣的話不管表的數(shù)據(jù)都可以查詢出來,而且添加新的商品的商品,也不需要動優(yōu)惠券的源碼。

但我們在查詢的過程中,用ORM實在太繁瑣了,所以還有一個反向查詢的方法:

就是在每個商品中關聯(lián) 綁定一個關系:

coupons = GenericRelation(to='Coupon') # 用于反向查詢,不會生成表字段

這樣我們就可以直接ORM的.coupons找相應的字段!


注:相關教程知識閱讀請移步到python教程頻道。
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 嘉祥县| 色达县| 东辽县| 环江| 图片| 怀宁县| 镇坪县| 阿尔山市| 盐亭县| 乌兰浩特市| 通州区| 灵丘县| 马公市| 内丘县| 麻江县| 大足县| 安岳县| 巩义市| 长乐市| 深水埗区| 邻水| 宜川县| 阜南县| 象州县| 潼关县| 丹东市| 栾城县| 克什克腾旗| 乐陵市| 汨罗市| 荣昌县| 武鸣县| 广元市| 桐乡市| 济宁市| 策勒县| 临泉县| 桐城市| 尉氏县| 新泰市| 永州市|