Django中通過指令碼的方式將json資料寫入資料庫
這裡記錄一下django中通過指令碼的方式寫入json資料的一些技巧。
通過指令碼不僅可以將已有的json資料寫入資料庫,而且可以批量地模擬一些後臺資料,方便進行頁面的展示。
我們以電商專案中,商品類表,商品資訊表兩個表的資料匯入為例進行分析。
在django中建了一個db_tools的資料夾,將json資料存放在data資料夾中,import開頭的兩個檔案就是匯入的指令碼。
一、商品類表
class GoodsCategory(models.Model): """ 商品類別 """ CATEGORY_TYPE = ( (1, "一級類目"), (2, "二級類目"), (3, "三級類目"), ) name = models.CharField(default="", max_length=30, verbose_name="類別名", help_text="類別名") code = models.CharField(default="", max_length=30, verbose_name="類別code", help_text="類別code") desc = models.TextField(default="", verbose_name="類別描述", help_text="類別描述") category_type = models.IntegerField(choices=CATEGORY_TYPE, verbose_name="類目級別", help_text="類目級別") parent_category = models.ForeignKey("self", null=True, blank=True, verbose_name="父類目級別", help_text="父目錄",related_name="sub_cat",on_delete=models.CASCADE) is_tab = models.BooleanField(default=False, verbose_name="是否導航", help_text="是否導航") add_time = models.DateTimeField(default=datetime.now, verbose_name="新增時間") class Meta: verbose_name = "商品類別" verbose_name_plural = verbose_name def __str__(self): return self.name
資料格式如下圖:
這個資料集的資料最重要的就是分類的巢狀,可以一層套一層,大類包括小類。因此才匯入的時候需要使用多層for迴圈來遍歷。
首先既然是匯入資料庫,所以我們必須和django專案app中的model建立關聯,使用該model。這裡值得強調的是,django的model不僅僅可以在app中使用,而且在獨立的py檔案中也是可以引用使用的。
improt_goods_data.py檔案中初始化設定如下:
# 獨立使用django的model
import sys
import os
pwd = os.path.dirname(os.path.realpath(__file__))
sys.path.append(pwd+"../")
# 找到根目錄(與工程名一樣的資料夾)下的settings
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'VueShop.settings')
import django
django.setup()
這些設定一定要在檔案的最前面,接下來才是引入相關的模型,進行資料操作,此處我們僅引入部分的欄位進行演示:
# 引入的位置必須在這裡,不可提前
from goods.models import GoodsCategory
from db_tools.data.category_data import row_data
for lev1_cat in row_data:
lev1_instance = GoodsCategory()
lev1_instance.code = lev1_cat["code"]
lev1_instance.name = lev1_cat["name"]
lev1_instance.category_type = 1
lev1_instance.save()
for lev2_cat in lev1_cat["sub_categorys"]:
lev2_instance = GoodsCategory()
lev2_instance.code = lev2_cat["code"]
lev2_instance.name = lev2_cat["name"]
lev2_instance.category_type = 2
lev2_instance.parent_category = lev1_instance
lev2_instance.save()
for lev3_cat in lev2_cat["sub_categorys"]:
lev3_instance = GoodsCategory()
lev3_instance.code = lev3_cat["code"]
lev3_instance.name = lev3_cat["name"]
lev3_instance.category_type = 3
lev3_instance.parent_category = lev2_instance
lev3_instance.save()
上圖中,兩個from分別引入的是app模型和預錄入json資料 ,這裡沒有太多要說的,就是三層遍歷,要注意的是,欄位一定要匹配。
二、商品類資訊表
表model設計如下:
class Goods(models.Model):
"""
商品
"""
category = models.ForeignKey(GoodsCategory, verbose_name="商品類目",on_delete=models.CASCADE)
goods_sn = models.CharField(max_length=50, default="", verbose_name="商品唯一貨號")
name = models.CharField(max_length=100, verbose_name="商品名")
click_num = models.IntegerField(default=0, verbose_name="點選數")
sold_num = models.IntegerField(default=0, verbose_name="商品銷售量")
fav_num = models.IntegerField(default=0, verbose_name="收藏數")
goods_num = models.IntegerField(default=0, verbose_name="庫存數")
market_price = models.FloatField(default=0, verbose_name="市場價格")
shop_price = models.FloatField(default=0, verbose_name="本店價格")
goods_brief = models.TextField(max_length=500, verbose_name="商品簡短描述")
goods_desc = UEditorField(verbose_name=u"內容", imagePath="goods/images/", width=1000, height=300,
filePath="goods/files/", default='')
ship_free = models.BooleanField(default=True, verbose_name="是否承擔運費")
goods_front_image = models.ImageField(upload_to="goods/images/", null=True, blank=True, verbose_name="封面圖")
is_new = models.BooleanField(default=False, verbose_name="是否新品")
is_hot = models.BooleanField(default=False, verbose_name="是否熱銷")
add_time = models.DateTimeField(default=datetime.now, verbose_name="新增時間")
class Meta:
verbose_name = '商品'
verbose_name_plural = verbose_name
def __str__(self):
return self.name
資料格式如下:
整個import_goods_data.py如下:
# 獨立使用django的model
import sys
import os
pwd = os.path.dirname(os.path.realpath(__file__))
sys.path.append(pwd+"../")
# 找到根目錄(與工程名一樣的資料夾)下的settings
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'VueShop.settings')
import django
django.setup()
# 引入的位置必須在這裡,不可提前
from goods.models import Goods,GoodsCategory,GoodsImage
from db_tools.data.product_data import row_data
for goods_detail in row_data:
goods = Goods()
goods.name = goods_detail["name"]
goods.market_price = float(int(goods_detail["market_price"].replace("¥","").replace("元","")))
goods.sale_price = float(int(goods_detail["sale_price"].replace("¥","").replace("元","")))
goods.goods_brief = goods_detail["desc"] if goods_detail["desc"] is not None else ""
goods.goods_desc = goods_detail["goods_desc"] if goods_detail["goods_desc"] is not None else ""
goods.goods_front_image = goods_detail["images"][0] if goods_detail["images"] else ""
category_name = goods_detail["categorys"][-1]
category = GoodsCategory.objects.filter(name=category_name)
if category:
goods.category = category[0]
goods.save()
for goods_image in goods_detail["images"]:
goods_image_instance = GoodsImage()
goods_image_instance.image = goods_image
goods_image_instance.goods = goods
goods_image_instance.save()
我們可以從這裡的匯入中看到,用到了一些小的技巧,比如:
通過replace("","")資料處理後再錄入,
通過if等語句進行錄入判斷等等。
當然方法遠遠不止這些,在資料的錄入過程中,可以通過進行設定實現資料過濾。
最後執行指令碼檔案後,我們可以看到資料全部錄入庫中: