Django ContentTypes框架詳解及使用場景介紹
標簽: django contenttypes comment genricrelation
Django contenttypes是一個非常有用的框架,主要用來創建模型間的通用關系(generic relation)。不過由于其非常抽象,理解起來并不容易。當你創建一個django項目的時候,可以看到在默認的INSTALL_APPS已經包含了django.contrib.contenttypes。今天我們來重點講下它的使用場景及如何使用django contenttypes。
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
本文參考了StackOverflow上著名問題及DjangoContentTypes詳解
How exactly do Django content types work?
https://blog.csdn.net/laughing2333/article/details/53014267
Django ContentTypes框架使用場景
假設我們創建了如下模型,里面包含文章Post,Picture和評論Comment模型。Comment可以是對Post的評論,也可以是對Picture的評論。如果你還想對其它對象(比如回答,用戶) 進行評論, 這樣你將需要在comment對象里添加非常多的ForeignKey。你的直覺會告訴你,這樣做很傻,會造成代碼重復和字段浪費。一個更好的方式是,只有當你需要對某個對象或模型進行評論時,才創建comment與那個模型的關系。這時你就需要使用django contenttypes了。
from django.db import models
from django.contrib.auth.models import User
# Create your models here.
class Post(models.Model):
author = models.ForeignKey(User)
title = models.CharField(max_length=75)
body = models.TextField(blank=True)
class Picture(models.Model):
author = models.ForeignKey(User)
image = models.ImageField()
caption = models.TextField(blank=True)
class Comment(models.Model):
author = models.ForeignKey(User)
body = models.TextField(blank=True)
post = models.ForeignKey(Post, null=True)
picture = models.ForeignKey(Picture, null=True)
Django ContentType提供了一種GenericForeignKey的類型,通過這種類型可以指定content_object。修改過的comment模型如下圖所示:
from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType
class Comment(models.Model):
author = models.ForeignKey(User)
body = models.TextField(blank=True)
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey()
comment里加了3個字段:
content_type: 內容類型,代表了模型的名字(比如Post, Picture)
object_id: 傳入對象的id
content_object: 傳入的實例化對象,其包含兩個屬性content_type和object_id。
當你需要對某篇文章或某個圖片進行評論時(建立評論關系), 你只需要將實例化的對象user, post或picture傳入comment。這樣實現了按需建立評論關系。首先你先需要實例化對象。
user = User.objects.create_user(username='user1', password='2333')
post = Post.objects.create(author=user,
title='title1',
body='')
picture = Picture.objects.create(author=user,
image="default.png",
caption='picture1')
然后在views或者shell里,你可以按如下代碼建立評論關系。
>>> from foreign.models import Post, Picture, Common
>>> from django.contrib.auth.models import User
>>> user = User.objects.get(username='user1')
>>> post = Post.objects.get(title='title1')
>>> c = Comment.objects.create(author=user, body='', content_object=post)
>>> picture = Picture.objects.get(caption='picuture1')
>>> c1 = Comment.objects.create(author=user, body='', content_object=picture)
然而上述創建評論的方式我們并不推薦。我們更希望直接從模型中獲取或創建comment,我們只需在模型中創建一個與Comment的GenericRelation即可。注意該字段不會存儲于數據庫中。
我們修改過的模型及創建和獲取評論的代碼如下所示:
from django.contrib.contenttypes.fields import GenericRelation
class Post(models.Model):
author = models.ForeignKey(User)
title = models.CharField(max_length=75)
body = models.TextField(blank=True)
comments = GenericRelation('Comment')
class Picture(models.Model):
author = models.ForeignKey(User)
image = models.ImageField()
caption = models.TextField(blank=True)
comments = GenericRelation('Comment')
>>> me = User.objects.get(username='myusername')
>>> pic = Picture.objects.get(author=me)
>>> pic.comments.create(author=me, body="Man, I'm cool!")
>>> pic.comments.all()[<Comment: "Man, I'm cool!">]
值得注意的是,如果在Post中定義了GenericRelation,刪除了一個post實例,在Comment中所有與post相關實例也會被刪除。GenericForeignKey不支持設置on_delete參數。
因此,如果對級聯刪除不滿意的話就不要設置GenericRelation。
智能推薦
3.1.6 Django框架介紹
前言 由于Python的簡潔、易讀、強大、高效。現在Python應用在文件處理、網絡編程、數據庫編程、游戲、Web開發、數據分析、機器學習等各個領域。就Web開發而言,為了提高開發效率,應運而生了很多框架,如flask、django、twisted(底層定義)、tornado(高并發)等。框架很多,根據業務需求、選擇適合的框架。 &...
Django框架介紹
文章目錄 Django框架 框架思想 虛擬環境 環境 項目介紹 創建項目和app 項目結構介紹 url映射 DEBUG模式 視圖與URL映射 指定url傳遞的參數的類型 URL模塊化 重定向、反轉、url命名、應用命名空間、實例命名空間 redirect、reverse、url命名、應用命名空間 實例命名空間 reverse反轉中傳遞參數 傳遞/形式的參數 傳遞?形式的參數 指定默認參數 re_p...
django框架的介紹
目錄 一、Django介紹 1、簡介 2、安裝 3、文檔 二、Django相關知識學習 1、Django結構 2、相關術語和規范 三、Django學習途徑 一、Django介紹 1、簡介 ?Django是Python語言中的一個web框架,并遵循MVC設計。Python語言中主流的web框架有Django、Tornado、Flask 等多種,Django相較與其它WEB框架,其優勢為:大而全,框架...
Django介紹
在進行項目之前先創建一個虛擬環境 創建虛擬環境: 進入環境: 安裝Django: 創建Django工程: 內層目錄:項目的真正的python包 init.py:一個空文件,它告訴python這個目錄應該被看做一個python包 settings.py:項目的配置 urls.py:項目的url聲明 wsgi.py:項目與WSGI兼容的Web服務器入口 manage.py:一個命令行工具,可以使你用多...
猜你喜歡
Django框架
一、Django建站基礎 1. Django項目創建 step1. 創建工程 ● manage.py : 命令行工具,允許以多種方式與項目進行交互。在CMD窗口下,將路徑切換到django項目下輸入 python manage.py help 可以查看工具的具體功能 ● init.py : 初始化文件,通常無需修改 ● setting.py : 項目配置文件 ● url.py : 項目的URL設置...
Django框架
一、什么是web框架 框架,即framework,特指為解決一個開放性問題而設計的具有一定約束性的支撐結構,使用框架可以幫你快速開發特定的系統,簡單地說,就是你用別人搭建好的舞臺來做表演。 對于所有的Web應用,本質上其實就是一個socket服務端,用戶的瀏覽器其實就是一個socket客戶端。 最簡單的Web應用就是先把HTML用文件保存好,用一個現成的HTTP服務器軟件,...
Django框架
電商網站(Django框架)—— 大綱內容與基本功能分析 原創 2017年10月28日 14:42:20 1323 1. 項目架構 2. 數據庫表結構 3. 數據庫讀寫分離 4. Django讀寫分離配置 新建utils/db_router.py 課后閱讀資料 ...
freemarker + ItextRender 根據模板生成PDF文件
1. 制作模板 2. 獲取模板,并將所獲取的數據加載生成html文件 2. 生成PDF文件 其中由兩個地方需要注意,都是關于獲取文件路徑的問題,由于項目部署的時候是打包成jar包形式,所以在開發過程中時直接安照傳統的獲取方法沒有一點文件,但是當打包后部署,總是出錯。于是參考網上文章,先將文件讀出來到項目的臨時目錄下,然后再按正常方式加載該臨時文件; 還有一個問題至今沒有解決,就是關于生成PDF文件...