这里记录一下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等语句进行录入判断等等。
当然方法远远不止这些,在数据的录入过程中,可以通过进行设置实现数据过滤。
最后运行脚本文件后,我们可以看到数据全部录入库中: