在使用django框架時,有些model字段需要存儲json對象,可以使用django-jsonfield中的JSONField。
一、安裝依賴
pip install django-jsonfield==1.2.0
二、使用
from jsonfield import JSONField
class CollectConfig(models.Model):
ext_data = JSONField(_("額外數據"), default={})
config = JSONField(_("配置"), default=[])
可以存儲
dict
,也可以存儲list
。
三、篩選filter
舉例:ext_data
中的數據如下
{
"bk_inst_name": "測試",
"inst_unique_id": "TEST",
"inst_account": "647397c2-f72a-4695-aee0-399d305b912a",
"inst_subscription": "dfaa4903-5af3-4f6b-a3d7-dafb4055d4f5"
}
- 單個字段篩選
此時,需要根據bk_inst_name
字段進行篩選。
CollectConfig.objects.filter(ext_data__contains={'bk_inst_name': '測試'})
如果需要忽略大小寫:
CollectConfig.objects.filter(ext_data__icontains={'bk_inst_name': '測試'})
- 多個字段篩選
需要根據bk_inst_name
和inst_subscription
字段進行篩選, 必須全部符合。
$\color{red}{錯誤用法}$
CollectConfig.objects.filter(ext_data__icontains={'bk_inst_name': '測試', 'inst_subscription': 'dfaa4903-5af3-4f6b-a3d7-dafb4055d4f5'})
這種用法只有在
bk_inst_name
和inst_subscription
連在一起時才會起作用,否則就會查詢不到。
我們可以使用Q,分開查詢
from django.db.models import Q
q = Q(ext_data__icontains={'bk_inst_name': '測試'})
q.add(Q(ext_data__contains={ 'inst_subscription': 'dfaa4903-5af3-4f6b-a3d7-dafb4055d4f5'}), q.AND)
CollectConfig.objects.filter(q)
- 模糊查詢(不支持)
django-jsonfield
用於不提供原生dict
類型且基於簡單TextField
的數據庫, 數據庫中存儲的是str
類型數據。當您使用CollectConfig.ext_data
訪問字段值時,內部保存的str
將由字段本身使用json.loads()
轉換為dict
。因此,您只能使用icontains
和contains
等操作來查詢該字段。
例如:我們需要查詢bk_inst_name
包含測試
兩個字的數據。由於我們不確定測試
字段的具體位置,可能是xx測試xx
、測試xx
、 xx測試
,所以我們不能直接使用icontains
和contains
來查詢。
如果是一些比較特殊的字符,可以結合sql語句來查詢。