1. 程式人生 > >Django中通過指令碼的方式將json資料寫入資料庫

Django中通過指令碼的方式將json資料寫入資料庫

      這裡記錄一下django中通過指令碼的方式寫入json資料的一些技巧。

      通過指令碼不僅可以將已有的json資料寫入資料庫,而且可以批量地模擬一些後臺資料,方便進行頁面的展示。

      我們以電商專案中,商品類表,商品資訊表兩個表的資料匯入為例進行分析。

      在django中建了一個db_tools的資料夾,將json資料存放在data資料夾中,import開頭的兩個檔案就是匯入的指令碼。 

一、商品類表

     

表model設計如下:

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等語句進行錄入判斷等等。

      當然方法遠遠不止這些,在資料的錄入過程中,可以通過進行設定實現資料過濾。

      最後執行指令碼檔案後,我們可以看到資料全部錄入庫中: