Django congtent types應用

contenttypes 是Django內置的一個應用,可以追蹤項目中所有app和model的對應關系,并記錄在ContentType表中。

每當我們創建了新的model并執行數據庫遷移后,ContentType表中就會自動新增一條記錄。比如我在應用app01的models.py中創建表class Electrics(models.Model): pass。從數據庫查看ContentType表,顯示如下:

idapp_labelmodel
admin, auth等內置應用…
5contenttypescontenttype
6app01electrics

那么這個表有什么作用呢?這里提供一個場景,網上商城購物時,會有各種各樣的優惠券,比如通用優惠券,滿減券,或者是僅限特定品類的優惠券。在數據庫中,可以通過外鍵將優惠券和不同品類的商品表關聯起來:

from django.db import modelsclass Electrics(models.Model):"""id  name1   日立冰箱2   三星電視3   小天鵝洗衣機"""name = models.CharField(max_length=32)class Foods(models.Model):"""id   name1    面包2    烤鴨"""name = models.CharField(max_length=32)class Clothes(models.Model):name = models.CharField(max_length=32)class Coupon(models.Model):"""id     name            Electrics        Foods           Clothes        more...1     通用優惠券       null              null            null           2     冰箱滿減券         2               null            null3     面包狂歡節        null              1              null"""name = models.CharField(max_length=32)electric_obj = models.ForeignKey(to='Electrics', null=True)food_obj = models.ForeignKey(to='Foods', null=True)cloth_obj = models.ForeignKey(to='Clothes', null=True)

如果是通用優惠券,那么所有的ForeignKey為null,如果僅限某些商品,那么對應商品ForeignKey記錄該商品的id,不相關的記錄為null。但是這樣做是有問題的:實際中商品品類繁多,而且很可能還會持續增加,那么優惠券表中的外鍵將越來越多,但是每條記錄僅使用其中的一個或某幾個外鍵字段。

通過使用contenttypes 應用中提供的特殊字段GenericForeignKey,我們可以很好的解決這個問題。只需要以下三步:

  • 在model中定義ForeignKey字段,并關聯到ContentType表。通常這個字段命名為“content_type”
  • 在model中定義PositiveIntegerField字段,用來存儲關聯表中的主鍵。通常這個字段命名為“object_id”
  • 在model中定義GenericForeignKey字段,傳入上述兩個字段的名字。

為了更方便查詢商品的優惠券,我們還可以在商品類中通過GenericRelation字段定義反向關系。

示例代碼:

from django.db import models
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes.fields import GenericForeignKeyclass Electrics(models.Model):name = models.CharField(max_length=32)coupons = GenericRelation(to='Coupon')  # 用于反向查詢,不會生成表字段def __str__(self):return self.nameclass Foods(models.Model):name = models.CharField(max_length=32)coupons = GenericRelation(to='Coupon')def __str__(self):return self.nameclass Clothes(models.Model):name = models.CharField(max_length=32)coupons = GenericRelation(to='Coupon')def __str__(self):return self.nameclass Coupon(models.Model):name = models.CharField(max_length=32)content_type = models.ForeignKey(to=ContentType) # step 1object_id = models.PositiveIntegerField() # step 2content_object = GenericForeignKey('content_type', 'object_id') # step 3def __str__(self):return self.name

創建記錄和查詢

from django.shortcuts import render, HttpResponse
from app01 import models
from django.contrib.contenttypes.models import ContentTypedef test(request):if request.method == 'GET':# ContentType表對象有model_class() 方法,取到對應modelcontent = ContentType.objects.filter(app_label='app01', model='electrics').first()  # 表名小寫cloth_class = content.model_class() # cloth_class 就相當于models.Electricsres = cloth_class.objects.all()print(res)# 為三星電視(id=2)創建一條優惠記錄s_tv = models.Electrics.objects.filter(id=2).first()models.Coupon.objects.create(name='電視優惠券', content_object=s_tv)# 查詢優惠券(id=1)綁定了哪些商品coupon_obj = models.Coupon.objects.filter(id=1).first()prod = coupon_obj.content_objectprint(prod)# 查詢三星電視(id=2)的所有優惠券res = s_tv.coupons.all()print(res)# 查詢obj的所有優惠券:如果沒有定義反向查詢字段,通過如下方式:content = ContentType.objects.filter(app_label='app01', model='model_name').first()res = models.OftenAskedQuestion.objects.filter(content_type=content, object_id=obj.pk).all()return HttpResponse('....')

總結:

當一張表和多個表FK關聯,并且多個FK中只能選擇其中一個或其中n個時,可以利用contenttypes app,只需定義三個字段就搞定!

轉載于:https://www.cnblogs.com/a-dyw/p/9275629.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/452062.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/452062.shtml
英文地址,請注明出處:http://en.pswp.cn/news/452062.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

網絡爬蟲--7.Handler處理器 和 自定義Opener

文章目錄一. 引言二. 簡單的自定義opener()三. ProxyHandler處理器(代理設置)四. Cookie1.Cookie原理2.Cookie應用五. cookiejar庫 和 HTTPCookieProcessor處理器1.案例一:獲取Cookie,并保存到CookieJar()對象中2.案例二:利用cook…

如何選擇面向對象語言

開發人員在選擇面向對象語言時,還應該著重考慮以下一些實際因素。 1. 將來能否占主導地位 為了使自己的產品在若干年后仍然具有很強的生命力,人們可能希望采用將來占主導地位的語言編程。 根據目前占有的市場份額,以及專業書刊和學術會議上所…

Unicode編碼及其實現:UTF-16、UTF-8,and more

本文主要討論Unicode的編碼與各種實現,著重討論UTF-16,UTF-8的實現規則,以及Big-endian和Little-Endian的存儲規則。 一、Unicode編碼 Unicode出現之前已經有各種編碼標準:ANSI、ISO8859-1、GB2312、GBK以及BIG-5等。Unicode試圖統…

Apache Tiles的使用 前配置

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 使用方法見&#xff1a; http://blog.csdn.net/jiangyu1013/article/details/53161580 1.加maven 依賴&#xff1a; <!-- 頁面布局…

day212223:線程、進程、協程

1、程序工作原理 進程的限制&#xff1a;每一個時刻只能有一個線程來工作。多進程的優點&#xff1a;同時利用多個cpu&#xff0c;能夠同時進行多個操作。缺點&#xff1a;對內存消耗比較高當進程數多于cpu數量的時候會導致不能被調用&#xff0c;進程不是越多越好&#xff0c;…

php課程 8-28 php如何繪制生成顯示圖片

php課程 8-28 php如何繪制生成顯示圖片 一、總結 一句話總結&#xff1a;gd庫輕松解決 1、php圖片操作生成的圖的兩種去向是什么&#xff1f; 一種在頁面直接輸出&#xff0c;一種存進本地磁盤 2、php操作圖片的庫有哪些&#xff1f; PHP: Image Processing and Generation - M…

代碼行技術

用代碼行技術估算軟件規模時&#xff0c;當程序較小時常用的單位是代碼行數&#xff08;LOC&#xff09;&#xff0c;當程序較大時常用的單位是千行代碼數&#xff08;KLOC&#xff09;。 代碼行技術的主要優點是&#xff0c;代碼是所有軟件開發項目都有的“產品”&#xff0c;…

網絡爬蟲--8.編碼趣聞

很久很久以前&#xff0c;有一群人&#xff0c;他們決定用8個可以開合的晶體管來組合成不同的狀態&#xff0c;以表示世界上的萬物。他們看到8個開關狀態是好的&#xff0c;于是他們把這稱為"字節"。 再后來&#xff0c;他們又做了一些可以處理這些字節的機器&#…

科技領域的一分鐘

各位果迷是否能想象在一分鐘之內&#xff0c;科技領域都會發生什么事情&#xff1f;——蘋果平均每分鐘賣出81部 iPad&#xff1b;在 iPhone 4S 發布后的第一個周末&#xff0c;每分鐘賣出925部 iPhone 4S&#xff1b;RIM每分鐘賣出103臺黑莓手機&#xff1b;Amazon每分鐘賣出1…

flavr—超級漂亮的jQuery扁平彈出對話框

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 插件描述&#xff1a;flavr是一個時尚的扁平彈出對話框為您的下一個網站。 flavr是響應設計布局&#xff0c;能夠適應任何屏幕大小。 得…

經緯度之間的距離計算

來自谷歌地圖的計算公式&#xff1a; 通過JAVA的Math類各種方法調用。實現上述公式 private static double EARTH_RADIUS 6378.137;// 單位千米/*** 角度弧度計算公式 rad:(). <br/>* * 360度2π πMath.PI* * x度 x*π/360 弧度* * author chiwei* param d* return* s…

在CentOS7阿里云服務器部署ThinkPHP5,并配置phpstrom實現同步開發(微信小程序及管理員后端)...

小程序和后端同步開發 1.服務器安裝tp5框架&#xff1a; 方法很多比如&#xff1a;github、linux命令直接手動下、composer 都可以&#xff0c;方法很多&#xff0c;百度一下&#xff0c;不再累述 2.這時你會發現怎么都訪問出現不了這個令人舒心的界面&#xff08;ok第一個坑到…

ER圖( 實體聯系圖)

E-R圖也稱實體-聯系圖(Entity Relationship Diagram)&#xff0c;提供了表示實體類型、屬性和聯系的方法&#xff0c;用來描述現實世界的概念模型。 它是描述現實世界概念結構模型的有效方法。是表示概念模型的一種方式&#xff0c;用矩形表示實體型&#xff0c;矩形框內寫明…

網絡爬蟲--9.正則表達式

文章目錄一. 正則表達式1.為什么要學正則表達式2.什么是正則表達式3.正則表達式匹配規則二. Python 的 re 模塊1.re 模塊的一般使用步驟2.compile 函數3.match 方法4.search 方法5.findall 方法6.finditer 方法7.split 方法8.sub 方法9.匹配中文10.貪婪模式與非貪婪模式1&#…

概念模型

將需求分析得到的用戶需求抽象為信息結構&#xff08;即概念模型&#xff09;的過程就是概念結構設計 概念模型的特點 &#xff08;1&#xff09;能真實、充分地反映現實世界&#xff0c;是現實世界的一個真 實模型。 &#xff08;2&#xff09;易于理解&#xff0c;從…

筆記本電池的正確使用方法

一、新買筆記本不需要激活&#xff0c;也不需要前三次的充電12小時深充深放&#xff0c;這主要是鋰電池的原理和特性決定的。電池設計有電量保護&#xff0c;不可能將電量完全用完&#xff0c;當然也不可能過度充電。 二、筆記本電池的壽命受周圍環境的影響很大&#xff0c;最好…

關于XShell 啟動虛擬機的weblogic并在本地打開oracle-weblogic 有關部署

對于沒有用過這款軟件的童鞋&#xff0c;我想必定會有幾步彎路&#xff1a; 1.新建好的虛擬機記得換成root用戶【su root】~ifconfig【eth0 inet addr】如果沒有這項請點擊右上角的電腦標識&#xff0c;鼠標左擊一下連接&#xff0c;沒有了x號就重新輸入ifconfig就有了 2.xshe…

JQuery Datatables Dom 和 Language 參數詳細說明

前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家。點擊跳轉到教程。 Dom說明 定義表格控件在頁面的顯示順序。 每個控件元素在數據表都有一個關聯的單個字母。 l - 每頁顯示行數的控件f - 檢索條件的控件…

程序員的思維修煉》讀書筆記

PB15061359 王亞正 這本書主要是從思維角度上來寫的&#xff0c;不具體針對到程序員如何寫代碼。我覺得這本書不僅僅適合程序員&#xff0c;其他對各行各業的人都同樣適用。 書中首先講了新手和專家的區別&#xff0c;一個需要靠規則&#xff0c;另一個則是靠感覺。 之后介紹了…

網絡爬蟲--10.使用正則表達式的爬蟲

文章目錄一. 前言二. 第一步&#xff1a;獲取數據三. 第二步&#xff1a;篩選數據四. 第三步&#xff1a;保存數據五. 第四步&#xff1a;實現循環抓取一. 前言 現在擁有了正則表達式這把神兵利器&#xff0c;我們就可以進行對爬取到的全部網頁源代碼進行篩選了。 下面我們一…