Django中contenttypes框架與通用外鍵總結
標簽: # Django
ContentType介紹
Django ContentTypes
是由Django
框架提供的一個核心功能,它對當前項目中所有基于Django
驅動的model
提供了更高層次的抽象接口。
Django
權限管理中的Permission
借助ContentType
實現了對任意models
的權限操作。ContenType
的通用類型-GenericRelation
(通用外鍵關聯),使模型類中的某張表關聯到任意的表。
在新建一個項目的時候在installed_app
中默認會有contenttypes
:
在遷移完數據庫后會發現項目的表中存在一張叫做django_content_type
的表,表中有兩個關鍵字段:
app_label
:應用標簽,也就是我們每個app模塊的名字。model
:對應app模塊下的模型類名稱。
這張表就是Django模型管理的表,根據這兩個字段我們可以定位到任何一個模型類。
ContentType源碼解析
源碼位置:
from django.contrib.contenttypes.models import ContentType
-
獲取自定義模型類例子:
>>> from django.contrib.contenttypes.models import ContentType >>> user_type = ContentType.objects.get(app_label='auth', model='user') >>> user_type <ContentType: user>
-
查詢模型類中的字段例子:
-
先根據上邊的例子獲取模型類
-
查詢模型類中的字段
>>> user_type.model_class() <class 'django.contrib.auth.models.User'> >>> user_type.get_object_for_this_type(username='Guido') <User: Guido>
-
GenericRelation和GenericForeignKey介紹與使用
假如在一個項目中有博客模塊、文章模塊、圖片模塊,每一個功能模塊都可以讓其他人進行評論,也就是說每一個模塊的model要關聯到評論model。
在不使用通用外鍵時每個應用的模型類以及評論的模型類如下:
from django.db import models
from django.contrib.auth.models import User
# 博客model
class Post(models.Model):
author = models.Foreignkey(User, on_delete=models.CASADE)
body = models.TextField(blank=True)
# 文章model
class Article(models.Model):
author = models.ForeignKey(User, on_delete=models.CASADE)
body = models.TextField(blank=True)
# 圖片model
class Picture(models.Model):
author = models.ForeignKey(User, on_delete=models.CASADE)
body = models.TextField(blank=True)
# 博客評論
class Post_omment(models.Model):
author = models.ForeignKey(User, on_delete=models.CASADE)
body = models.TextField(blank=True)
post = models.ForeignKey(to=Post, on_delete=models.CASADE, null=True)
# 圖片評論
class Pic_omment(models.Model):
author = models.ForeignKey(User, on_delete=models.CASADE)
body = models.TextField(blank=True)
pic = models.ForeignKey(to=Picture, on_delete=models.CASADE, null=True)
# 文章評論
class Article_comment(models.Model):
author = models.ForeignKey(User, on_delete=models.CASADE)
body = models.TextField(blank=True)
article = models.ForeignKey(to=Article, on_delete=models.CASADE, null=True)
存在問題:這樣對于代碼的擴展性不是很友好,每當新增一個模塊需要添加評論功能的時候都需要在增加一個該模塊的評論model
。
解決方法:Django框架其實已經考慮到這種情況,并且提供了對應的處理機制,那就是通用外鍵的使用。
通用外鍵:將一個自定義model
變為一個通用的模型類,該model
可以成為任意模型類的外鍵關聯的表。
使用通用外鍵我們就不用每次新增模塊的時候去創建對應的評論模型類,直接讓需要的模塊關聯到定義了通用外鍵的模型類就可以了。
使用方法:
-
首先要明白表與表之間的關聯的意思:
表與表之間的關聯也是記錄與記錄之間的關聯,也就是一個表的一條記錄關聯到另一張表的一條記錄。
-
想要讓兩張表關聯就要有能夠定位到表中的每一條記錄的方法,前邊講解的使用ContentType可以定位到一張表,接下來的通用外鍵就可以幫我們定位到一條記錄。
-
定義含有通用外鍵的評論模型類:
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.fields import GenericForeignKey # 此時的模型類為通用模型類 class Comment(models.Modle): author = models.ForeignKey(to=User, on_delete=models.CASADE) body = models.TextField(blank=True) # 1. 使用ContenType定位到一張表 content_type = models.ForeignKey(ContentType, models.CASADE) # 2. 主鍵id object_id = models.IntegerField() # 3. 根據1和2定位到一條記錄 content_object = GenericForeignKey('content_type', 'object_id')
第三步默認情況下傳遞的參數名稱就是
content_type
和object_id
, 如果第1和第2步的名字和這一樣的話,可以缺省參數:content_object = GenericForeignKey()
-
定義好通用模型類后,在其他模型類中就可以關聯到這個通用模型類了:
from django.contrib.contenttypes.fields import GenericRelation from django.db import models from django.contrib.auth.models import User # 博客model class Post(models.Model): author = models.Foreignkey(User, on_delete=models.CASADE) body = models.TextField(blank=True) # 這樣就關聯到了評論模型類 comments = GenericRelation(Comment) # 文章model class Article(models.Model): author = models.ForeignKey(User, on_delete=models.CASADE) body = models.TextField(blank=True) # 這樣就關聯到了評論模型類 comments = GenericRelation(Comment) # 圖片model class Picture(models.Model): author = models.ForeignKey(User, on_delete=models.CASADE) body = models.TextField(blank=True) # 這樣就關聯到了評論模型類 comments = GenericRelation(Comment)
這樣不管以后增加了幾個功能模塊,都不要在重寫評論模型類,直接讓該模塊的模型類關聯到通用評論模型類就可以了。
-
需要注意的是通用模型類的通用外鍵
content_object = GenericForeignKey('content_type', 'object_id')
默認是級聯刪除,且不提供on_delete
參數:也就是說當我們刪除了文章模塊后,關于文章模塊的評論也將被刪除。
智能推薦
MySQL中的外鍵(foreign key)
引言 在MySQL中,我們都對主鍵比較了解,知道主鍵的主要作用是唯一區分表中的各個行;但是,對于外鍵(foreign key) 比較陌生。那么什么是外鍵呢?外鍵的作用是什么呢? 一、外鍵、外鍵作用及其限制條件 1.外鍵的定義: 外鍵是某個表中的一列,它包含在另一個表的主鍵中。 外鍵也是索引的一種,是通過一張表中的一列指向另一張表中的主鍵,來對兩張表進行關聯。 一張表可以有一個外鍵,也可以存在多個外...
MySQL中的外鍵(foreign key)
閱讀目錄 前言 一、外鍵作用及其限制條件 1 外鍵的定義 2 外鍵的作用 3 外鍵創建限制 二、外鍵創建方法 1 創建外鍵的語法 2 舉例 (1)創建兩張表 (2)創建外鍵 (3)查看表結構 三、驗證外鍵作用 1 先向主表中添加數據 2 觸發限制使用默認值 RESTRICT 的情況下 (1)從表插入新行,外鍵值不在主表中,被阻止 (2)從表修改外鍵值,新值不是主表的主鍵值,阻止修改 (3)主表刪除...
MySQL(9):關系與外鍵
1.創建成績表(scores) 創建成績表scores,結構中字段為id、學生、科目、成績。思考:學生列應該存什么信息呢? 答:學生列的數據不是在這里新建的,而應該從學生表引用過來,關系也是一條數據;根據范式要求應該存儲學生的編號,而不是學生的姓名等其它信息;同理,科目表也是...
數據庫主鍵與外鍵
數據庫主鍵與外鍵 數據庫:數據庫是一些關聯表的集合。 數據表: 表是數據的矩陣。在一個數據庫中的表看起來像一個簡單的電子表格。 列: 一列(數據元素) 包含了相同的數據, 例如學生學號。 行:一行(=元組,或記錄)是一組相關的數據,例如一個學生的個人信息(姓名、學號、年齡、班級、專業等)。 冗余:存儲兩倍數據,冗余降低了性能,但提高了數據的安全性。 主鍵:主鍵是唯一的。一個數據表中只能包含一個主鍵...
猜你喜歡
freemarker + ItextRender 根據模板生成PDF文件
1. 制作模板 2. 獲取模板,并將所獲取的數據加載生成html文件 2. 生成PDF文件 其中由兩個地方需要注意,都是關于獲取文件路徑的問題,由于項目部署的時候是打包成jar包形式,所以在開發過程中時直接安照傳統的獲取方法沒有一點文件,但是當打包后部署,總是出錯。于是參考網上文章,先將文件讀出來到項目的臨時目錄下,然后再按正常方式加載該臨時文件; 還有一個問題至今沒有解決,就是關于生成PDF文件...
電腦空間不夠了?教你一個小秒招快速清理 Docker 占用的磁盤空間!
Docker 很占用空間,每當我們運行容器、拉取鏡像、部署應用、構建自己的鏡像時,我們的磁盤空間會被大量占用。 如果你也被這個問題所困擾,咱們就一起看一下 Docker 是如何使用磁盤空間的,以及如何回收。 docker 占用的空間可以通過下面的命令查看: TYPE 列出了docker 使用磁盤的 4 種類型: Images:所有鏡像占用的空間,包括拉取下來的鏡像,和本地構建的。 Con...
requests實現全自動PPT模板
http://www.1ppt.com/moban/ 可以免費的下載PPT模板,當然如果要人工一個個下,還是挺麻煩的,我們可以利用requests輕松下載 訪問這個主頁,我們可以看到下面的樣式 點每一個PPT模板的圖片,我們可以進入到詳細的信息頁面,翻到下面,我們可以看到對應的下載地址 點擊這個下載的按鈕,我們便可以下載對應的PPT壓縮包 那我們就開始做吧 首先,查看網頁的源代碼,我們可以看到每一...