Django JSONField的自動(dòng)轉(zhuǎn)換思路詳解(django自定義模型字段)
Django JSONField的自動(dòng)轉(zhuǎn)換(django自定義模型字段)
背景
Django v3.1的主要更新之一便是完善了對(duì)JSON數(shù)據(jù)存儲(chǔ)的支持,新增models.JSONField和forms.JSONField,可在所有受支持的數(shù)據(jù)庫(kù)后端上使用。
通過(guò)models.JSONField可指定此字段為存儲(chǔ)類(lèi)型為JSON格式。null=True表示此字段可以為空。
from django.db import models class Hello(models.Model): name = models.CharField(max_length=200) data = models.JSONField(null=True) def __str__(self): return self.name
思路
如果您想實(shí)現(xiàn)JSONField的自動(dòng)轉(zhuǎn)換,可以使用Django REST framework的JSONField,或者自定義一個(gè)字段類(lèi)并覆蓋from_db_value()和get_prep_value()方法來(lái)實(shí)現(xiàn)這個(gè)功能。
DRF的JSONField更簡(jiǎn)單,但使用上相對(duì)復(fù)雜一些。自定義字段類(lèi)的方法更輕量,但需要我們自己完成一定的編碼工作。
這里推薦使用自定義字段類(lèi)的方法!
使用DRF的JSONField
要使用DRF的JSONField,主要是在Serializer中導(dǎo)入并應(yīng)用于需要自動(dòng)轉(zhuǎn)換JSON的字段,然后在視圖進(jìn)行序列化和反序列化,JSONField會(huì)自動(dòng)完成與之相關(guān)的所有轉(zhuǎn)換工作。
自定義一個(gè)字段類(lèi)并覆蓋from_db_value()和get_prep_value()方法
直接使用JSONField不會(huì)自動(dòng)轉(zhuǎn)換,是因?yàn)?
- JSONField只是一個(gè)簡(jiǎn)單的繼承自TextField的字段
- 它本身并未實(shí)現(xiàn)from_db_value()和get_prep_value()方法
- 所以當(dāng)我們?cè)L問(wèn)instance.JSONField時(shí),得到的僅是JSON編碼后的字符串,而非Python對(duì)象
- 它也不會(huì)在保存實(shí)例時(shí)自動(dòng)將Python對(duì)象重新轉(zhuǎn)換為JSON字符串
覆蓋模型字段的from_db_value()和get_prep_value()方法可以實(shí)現(xiàn)「自動(dòng)轉(zhuǎn)換」的效果。
- from_db_value()方法用于數(shù)據(jù)庫(kù)讀取值時(shí)將值轉(zhuǎn)換為Python對(duì)象
- get_prep_value()方法用于數(shù)據(jù)庫(kù)保存值前將Python對(duì)象轉(zhuǎn)換為值
通過(guò)覆蓋這兩個(gè)方法,我們可以實(shí)現(xiàn)自定義的轉(zhuǎn)換邏輯,從而達(dá)到自動(dòng)轉(zhuǎn)換的效果。
django自定義模型字段 @models.register_field()
@models.register_field()是一個(gè)模型注冊(cè)裝飾器。使用它可以注冊(cè)自定義字段,使其可以像內(nèi)置字段一樣在模型中使用。
例如,使用了這個(gè)裝飾器的JSONField可以在模型中像此使用:
python
class Product(models.Model):
info = models.JSONField()
而不用導(dǎo)入字段類(lèi):
python
from .fields import JSONField
class Product(models.Model):
info = JSONField()
總結(jié):這樣的話,就不用單獨(dú)導(dǎo)入字段類(lèi)了(我們只需要在django啟動(dòng)入口的位置,如apps.py中 導(dǎo)入JSONField。目的是為了使用@models.register_field裝飾器注冊(cè)這個(gè)字段,使其在Django知道并可以在任何模型中像內(nèi)置字段一樣使用)。如果不使用這個(gè)裝飾器,我們必須導(dǎo)入字段類(lèi)后才能在模型中使用它。
另外,即使使用了@models.register_field裝飾器,我們也可以直接導(dǎo)入JSONField字段類(lèi)并在模型中使用。
舉例:apps.py導(dǎo)入了,在具體的模型類(lèi)中又單獨(dú)引入了這個(gè)JSONField,用的是哪個(gè)?
在這種情況下,Django會(huì)使用您在模型中直接導(dǎo)入的JSONField字段類(lèi)。
也就是說(shuō),apps.py中的導(dǎo)入會(huì)被忽略,模型中導(dǎo)入的字段類(lèi)會(huì)生效并在模型中實(shí)際使用。
這是因?yàn)?
- Django會(huì)根據(jù)實(shí)際使用解析哪個(gè)字段類(lèi),而不是根據(jù)哪個(gè)被導(dǎo)入了。
- 如果同一個(gè)字段類(lèi)被 imports 了兩次,Python也只會(huì)使用最后一個(gè)導(dǎo)入的那個(gè)。
使用@models.register_field()帶來(lái)的好處是:
- 使自定義字段的使用看起來(lái)像內(nèi)置字段,較為簡(jiǎn)潔直接,易于理解。
- 不用導(dǎo)入自定義字段類(lèi),模型可以獨(dú)立定義,解耦了字段的導(dǎo)入依賴(lài)。
- 自動(dòng)處理字段的參數(shù),無(wú)需在模型中傳遞,使用起來(lái)像內(nèi)置字段。
- 方便第三方庫(kù)的集成,可直接在模型中使用第三方提供的自定義字段。
另外,需要注意的一點(diǎn)是,您使用了@models.register_field裝飾器,將JSONField注冊(cè)為了一個(gè)可以像內(nèi)建字段一樣使用的模型字段。
但是,Django在首次運(yùn)行時(shí)需要導(dǎo)入這個(gè)字段類(lèi),才知道JSONField代表什么字段。
所以,您需要在首次使用JSONField的模型對(duì)應(yīng)的apps.py中導(dǎo)入這個(gè)字段類(lèi)。
經(jīng)過(guò)測(cè)試Django-4.2.1,里沒(méi)有register_field裝飾器。
因此總結(jié)起來(lái),直接定義自定義模型字段類(lèi),使用時(shí)單獨(dú)引入即可,這樣也不污染環(huán)境(不用在不用入口apps.py導(dǎo)一次,IDE還報(bào)灰色),即用即可,感覺(jué)更清晰。
到此這篇關(guān)于Django JSONField的自動(dòng)轉(zhuǎn)換(django自定義模型字段)的文章就介紹到這了,更多相關(guān)django自定義模型字段內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python設(shè)計(jì)模式之簡(jiǎn)單工廠模式實(shí)例詳解
這篇文章主要介紹了Python設(shè)計(jì)模式之簡(jiǎn)單工廠模式,結(jié)合實(shí)例形式分析了簡(jiǎn)單工廠模式的概念、原理及相關(guān)使用技巧,需要的朋友可以參考下2019-01-01Pycharm2020最新激活碼|永久激活(附最新激活碼和插件的詳細(xì)教程)
這篇文章主要介紹了Pycharm2020最新激活碼|永久激活(附最新激活碼和插件的詳細(xì)教程),本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-09-09教你用Python尋找重復(fù)文件并刪除的腳本寫(xiě)法
這篇文章主要介紹了如何用Python尋找重復(fù)文件并刪除,該腳本主要包括diskwalk,chechsum,find_dupes,delete模塊,其中diskwalk模塊是遍歷文件的,給定路徑,遍歷輸出該路徑下的所有文件,需要的朋友可以參考下2022-01-01tensorflow實(shí)現(xiàn)訓(xùn)練變量checkpoint的保存與讀取
今天小編就為大家分享一篇tensorflow實(shí)現(xiàn)訓(xùn)練變量checkpoint的保存與讀取,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-02-02