在使用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語句來查詢。
