Django+Vue开发生鲜电商平台之3.数据模型设计和资源导入
文章目录
- 一、项目初始化
- 二、数据模型设计
- 1.用户数据模型设计
- 2.商品数据模型设计
- 3.交易数据模型设计
- 4.用户操作数据模型设计
- 三、xadmin后台管理系统的配置
- 四、数据迁移和数据导入
- 1.migration原理和表的生成
- 2.导入商品类别和商品数据
永远不要跟别人比幸运,我从来没想过我比别人幸运,我也许比他们更有毅力,在最困难的时候,他们熬不住了,我可以多熬一秒钟、两秒钟。
——马云
Github和Gitee代码同步更新:
https://github.com/PythonWebProject/Django_Fresh_Ecommerce;
https://gitee.com/Python_Web_Project/Django_Fresh_Ecommerce。
在正式开发项目之前,要确定数据库和表结构。
一、项目初始化
在虚拟环境安装好之后,需要安装Django和Django REST framework,直接在虚拟环境下使用pip install django
和pip install djangorestframework
。为了支持Django REST framework,还需要安装markdown和django-filter,命令类似。
在PyCharm新建项目,需要选择Django,而不是Pure Python,建立好之后,需要选择解释器为建立的虚拟环境所对应的解释器,选择模板语言为Django,设置应用名为users,并取消勾选Enable Django admin。
项目创建后,通过点击PyCharm导航栏Run下的Run 'Project Name'
或者命令行执行python manage.py runserver
即可运行项目,再访问http://127.0.0.1:8000/如果看到以下页面即说明项目初始化成功:
创建项目后,主应用目录下会有一个settings.py文件,是关于项目的配置,其中有关于数据库的配置,如下:
DATABASES = {'default': {'ENGINE': 'django.db.backends.sqlite3','NAME': os.path.join(BASE_DIR, 'db.sqlite3'),}
}
显然,指明了数据库为sqlite,这也是Django的默认数据库,需要修改为MySQL,如下:
DATABASES = {'default': {'ENGINE': 'django.db.backends.mysql','NAME': 'fresh_ec','USER': 'root','PASSWORD': 'root','HOST':'127.0.0.1','OPTIONS': {'init_command': 'SET default_storage_engine=INNODB;'}}
}
因为后面第三方登录时进行数据迁移的需要,需要添加OPTIONS参数,设置存储引擎为INNODB,否则会报错。
此时再运行项目就会报错:
django.core.exceptions.ImproperlyConfigured: Error loading MySQLdb module.
Did you install mysqlclient?
提示安装MySQL驱动,直接通过pip install mysqlclient
安装即可。
在安装过程中可能会报错ERROR: Command errored out with exit status 1
,需要在https://www.lfd.uci.edu/~gohlke/pythonlibs/#mysqlclient中下载对应系统和Python版本的安装文件并将其拷贝到虚拟环境目录下通过pip install 文件名.whl
进行安装。
另外,因为项目中需要进行图片处理,因此需要安装图片处理库pillow,通过pip install pillow
安装即可。
还需要进行项目目录的优化调整:
在项目主目录下New一个Python Package为apps,保存项目中所有的app,并将自动生成的users移动到apps目录下;
再在主目录下创建extra_apps包,保存源码经修改的第三方包;
创建目录media,用于保存文件和图片等;
创建目录db_tools,用于保存数据库初始化的脚本等。
为了以后开发更加方便,可以将apps和extra_apps右键 → Mark Directory as → Sources Root,完成后文件夹颜色会发生改变。
还需要将apps和extra_apps加入到settings.py的根目录参数中,如下:
import os
import sys# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, BASE_DIR)
sys.path.insert(0, os.path.join(BASE_DIR, 'apps'))
sys.path.insert(0, os.path.join(BASE_DIR, 'extra_apps'))
二、数据模型设计
在进行需求分析之后,即可设计数据模型,即数据表。
在创建数据模型之前,需要创建所需的app,项目中需要的app包括商品goods、交易trade、用户users、操作user_operation(是为了防止相互引用而建立的)。
创建app可以直接点击导航栏Tools → Run manage.py Task,在命令行中分别输入startapp goods
、startapp trade
和startapp user_operation
创建对应的app,这比手动创建文件效率高很多。创建好之后,将3个目录移动到apps目录之下即可。
此时即可在每个app下分别创建数据模型。
为了保存数据,在进行删除操作时不真正删除数据,所有模型都增加一个属性is_delete,为布尔型值,为False时表示未删除,为True时表示被删除,以此来保证数据的安全。
1.用户数据模型设计
apps/users/models下创建数据模型如下:
from datetime import datetimefrom django.db import models
from django.contrib.auth.models import AbstractUser# Create your models here.class UserProfile(AbstractUser):'''用户'''name = models.CharField(max_length=30, null=True, blank=True, verbose_name='姓名')birthday = models.DateField(null=True, blank=True, verbose_name='出生日期')gender = models.CharField(max_length=6, choices=(('male', u'男'), ('female', u'女')), default='female',verbose_name='性别')mobile = models.CharField(max_length=11, verbose_name='电话')email = models.CharField(max_length=50, null=True, blank=True, verbose_name='邮箱')is_delete = models.BooleanField(default=False, verbose_name='是否删除')class Meta:verbose_name = '用户'verbose_name_plural = '用户'def __str__(self):return self.nameclass VerifyCode(models.Model):code = models.CharField(max_length=10, verbose_name='验证码')mobile = models.CharField(max_length=11, verbose_name='电话')add_time = models.DateField(default=datetime.now, verbose_name='添加时间')is_delete = models.BooleanField(default=False, verbose_name='是否删除')class Meta:verbose_name = '短信验证码'verbose_name_plural = verbose_namedef __str__(self):return self.code
此时定义的用户还未替换系统自定义的用户,还需要在settings.py中进行设置:
ALLOWED_HOSTS = []AUTH_USER_MODEL = 'users.UserProfile'
2.商品数据模型设计
商品包括商品分类(分为3个层次,具有从属关系)、品牌名、商品、商品轮播图、轮播商品等实体,goods/models.py建立模型如下:
from datetime import datetimefrom django.db import models
from DjangoUeditor.models import UEditorField# Create your models here.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='父类别', related_name='sub_cat', on_delete=models.SET_NULL)is_tab = models.BooleanField(default=False, verbose_name='是否导航', help_text='是否导航')is_delete = models.BooleanField(default=False, verbose_name='是否删除')class Meta:verbose_name = '商品类别'verbose_name_plural = verbose_namedef __str__(self):return self.nameclass GoodsCategoryBrand(models.Model):'''品牌名'''name = models.CharField(default='', max_length=30, verbose_name='品牌名', help_text='品牌名')desc = models.TextField(default='', max_length=200, verbose_name='品牌描述', help_text='品牌描述')image = models.ImageField(max_length=200, upload_to='brand/images/')add_time = models.DateField(default=datetime.now, verbose_name=u'添加时间')is_delete = models.BooleanField(default=False, verbose_name='是否删除')class Meta:verbose_name = '品牌'verbose_name_plural = verbose_namedef __str__(self):return self.nameclass Goods(models.Model):'''商品'''category = models.ForeignKey(GoodsCategory, verbose_name='商品类目', null=True, on_delete=models.SET_NULL)goods_sn = models.CharField(max_length=50, default='', verbose_name='商品唯一货号')name = models.CharField(max_length=300, 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_home = models.BooleanField(default=False, verbose_name='是否热销')add_time = models.DateField(default=datetime.now, verbose_name=u'添加时间')is_delete = models.BooleanField(default=False, verbose_name='是否删除')class GoodsImage(models.Model):'''商品轮播图'''goods = models.ForeignKey(Goods, verbose_name='', related_name='商品', null=True, on_delete=models.SET_NULL)image = models.ImageField(upload_to='', null=True, blank=True, verbose_name='图片')image_url = models.CharField(max_length=300, null=True, blank=True, verbose_name='图片链接')add_time = models.DateField(default=datetime.now, verbose_name=u'添加时间')is_delete = models.BooleanField(default=False, verbose_name='是否删除')class Meta:verbose_name = '商品轮播图'verbose_name_plural = verbose_namedef __str__(self):return self.goods.nameclass Banner(models.Model):'''轮播商品'''goods = models.ForeignKey(Goods, verbose_name='商品', null=True, on_delete=models.SET_NULL)image = models.ImageField(upload_to='banner', verbose_name='轮播图片')index = models.IntegerField(default=0, verbose_name='轮播顺序')add_time = models.DateField(default=datetime.now, verbose_name='添加时间')is_delete = models.BooleanField(default=False, verbose_name='是否删除')class Meta:verbose_name = '轮播商品'verbose_name_plural = verbose_namedef __str__(self):return self.goods.name
在建立商品模型时,需要用到百度的富文本编辑器UEditor,但是由于官方的Django UEditor停止维护、不再支持Python3,因此需要自行下载,可点击https://download.csdn.net/download/CUFEECR/12641702或https://github.com/twz915/DjangoUeditor3/下载并解压后,将DjangoEeditor目录放入项目的extra_apps目录下,并在settings.py中添加app如下:
INSTALLED_APPS = ['django.contrib.auth','django.contrib.contenttypes','django.contrib.sessions','django.contrib.messages','django.contrib.staticfiles','apps.users.apps.UsersConfig','goods','trade','user_operation','DjangoUeditor'
]
当然,也可以如下:
INSTALLED_APPS = ['django.contrib.auth','django.contrib.contenttypes','django.contrib.sessions','django.contrib.messages','django.contrib.staticfiles','apps.users.apps.UsersConfig','goods.apps.GoodsConfig','trade.apps.TradeConfig','user_operation.apps.UserOperationConfig','DjangoUeditor'
]
效果是一样的,这里采用后者。
3.交易数据模型设计
交易涉及到购物车、订单等实体。
购物车中如果商品多次加入购物车,只有1条数据,其数量增加;
点击结算之后,购物车数量减少、结算数量增加。
trade/models.py建立购物车和订单模型如下:
from datetime import datetimefrom django.db import models
from django.contrib.auth import get_user_model # from user.models import UserProfilefrom goods.models import GoodsUser = get_user_model()# Create your models here.class ShoppingCart(models.Model):'''购物车'''user = models.ForeignKey(User, verbose_name='用户', null=True, on_delete=models.SET_NULL)goods = models.ForeignKey(Goods, verbose_name='商品', null=True, on_delete=models.SET_NULL)goods_num = models.IntegerField(default=0, verbose_name='商品数量')add_time = models.DateField(default=datetime.now, verbose_name=u'添加时间')is_delete = models.BooleanField(default=False, verbose_name='是否删除')class Meta:verbose_name = '购物车'verbose_name_plural = verbose_namedef __str__(self):return '%s(%d)'.format(self.goods.name, self.goods_num)class OrderInfo(models.Model):'''订单信息'''ORDER_STATUS = (('success', '成功'),('cancel', '取消'),('paying', '待支付'),)user = models.ForeignKey(User, verbose_name='用户', null=True, on_delete=models.SET_NULL)order_sn = models.CharField(max_length=30, unique=True, verbose_name='订单号')trade_no = models.CharField(max_length=50, unique=True, null=True, blank=True, verbose_name='交易号')pay_status = models.CharField(max_length=100, choices=ORDER_STATUS, verbose_name='订单状态')pay_script = models.CharField(max_length=11, verbose_name='订单留言')order_mount = models.FloatField(default=0.0, verbose_name='订单金额')pay_time = models.DateTimeField(null=True, blank=True, verbose_name='支付时间')# 用户基本信息address = models.CharField(max_length=100, default='', verbose_name='收货地址')signer_name = models.CharField(max_length=20, default='', verbose_name='签收人')signer_mobile = models.CharField(max_length=11, verbose_name='联系电话')add_time = models.DateField(default=datetime.now, verbose_name=u'添加时间')is_delete = models.BooleanField(default=False, verbose_name='是否删除')class OrderGoods(models.Model):'''订单商品详情'''order = models.ForeignKey(OrderInfo, verbose_name='订单信息', null=True, on_delete=models.SET_NULL)goods = models.ForeignKey(Goods, verbose_name='商品', null=True, on_delete=models.SET_NULL)goods_num = models.IntegerField(default=0, verbose_name='商品数量')add_time = models.DateField(default=datetime.now, verbose_name=u'添加时间')is_delete = models.BooleanField(default=False, verbose_name='是否删除')class Meta:verbose_name = '订单商品'verbose_name_plural = verbose_namedef __str__(self):return self.order.order_sn
在定义购物车模型、需要导入用户模型时,因为假如是第三方项目,不知道其定义的具体用户模型和存放目录,所以from user.models import UserProfile
具有一定的局限性。因为之前已经将UserProfile注册到系统用户,所以可以直接用Django提供的函数get_user_model()
来获取用户,这样显得更加灵活。
4.用户操作数据模型设计
最典型的操作是收藏、添加收货地址和留言。
user_operation/models.py建立模型如下:
from datetime import datetimefrom django.db import models
from django.contrib.auth import get_user_modelfrom goods.models import GoodsUser = get_user_model()# Create your models here.class UserFav(models.Model):'''用户收藏'''user = models.ForeignKey(User, verbose_name='用户', null=True, on_delete=models.SET_NULL)goods = models.ForeignKey(Goods, verbose_name='商品', null=True, on_delete=models.SET_NULL)add_time = models.DateField(default=datetime.now, verbose_name=u'添加时间')is_delete = models.BooleanField(default=False, verbose_name='是否删除')class Meta:verbose_name = '用户收藏'verbose_name_plural = verbose_namedef __str__(self):return self.user.nameclass UserLeavingMessage(models.Model):'''用户留言'''MESSAGE_CHOICES = ((1, '留言'),(2, '投诉'),(3, '询问'),(4, '售后'),(5, '求购'),)user = models.ForeignKey(User, verbose_name='用户', null=True, on_delete=models.SET_NULL)message_type = models.IntegerField(default=1, choices=MESSAGE_CHOICES, verbose_name='留言类型',help_text='留言类型: 1(留言), 2(投诉), 3(询问),4(售后), 5(求购)')subject = models.CharField(max_length=80, default='', verbose_name='主题')message = models.TextField(default='', verbose_name='留言内容', help_text='留言内容')file = models.FileField(verbose_name='上传的文件', help_text='上传的文件')add_time = models.DateField(default=datetime.now, verbose_name=u'添加时间')is_delete = models.BooleanField(default=False, verbose_name='是否删除')class Meta:verbose_name = '用户留言'verbose_name_plural = verbose_namedef __str__(self):return self.subjectclass UserAddress(models.Model):'''用户收货地址'''user = models.ForeignKey(User, verbose_name='用户', null=True, on_delete=models.SET_NULL)district = models.CharField(max_length=50, default='', verbose_name='区域')address = models.CharField(max_length=100, default='', verbose_name='详细地址')signer_name = models.CharField(max_length=20, default='', verbose_name='签收人')signer_mobile = models.CharField(max_length=11, default='', verbose_name='联系电话')add_time = models.DateField(default=datetime.now, verbose_name=u'添加时间')is_delete = models.BooleanField(default=False, verbose_name='是否删除')class Meta:verbose_name = '收货地址'verbose_name_plural = verbose_namedef __str__(self):return self.address
三、xadmin后台管理系统的配置
xadmin是一个Django自带后台管理工具的替代品,可以直接使用pip install xadmin
命令安装,但是由于通过这种方式安装的官方版本对版本2.1及以后的Django支持不友好,因此可点击https://download.csdn.net/download/CUFEECR/12647622下载修改后的版本,并将其解压放入extra_apps下。
然后在4个apps下分别创建adminx.py,apps/goods/adminx.py如下:
import xadmin
from .models import Goods, GoodsCategory, GoodsImage, GoodsCategoryBrand, Bannerclass GoodsAdmin(object):list_display = ["name", "click_num", "sold_num", "fav_num", "goods_num", "market_price","shop_price", "goods_brief", "goods_desc", "is_new", "is_hot", "add_time"]search_fields = ['name', ]list_editable = ["is_hot", ]list_filter = ["name", "click_num", "sold_num", "fav_num", "goods_num", "market_price","shop_price", "is_new", "is_hot", "add_time", "category__name"]style_fields = {"goods_desc": "ueditor"}class GoodsImagesInline(object):model = GoodsImageexclude = ["add_time"]extra = 1style = 'tab'inlines = [GoodsImagesInline]class GoodsCategoryAdmin(object):list_display = ["name", "category_type", "parent_category", "add_time"]list_filter = ["category_type", "parent_category", "name"]search_fields = ['name', ]class GoodsBrandAdmin(object):list_display = ["category", "image", "name", "desc"]def get_context(self):context = super(GoodsBrandAdmin, self).get_context()if 'form' in context:context['form'].fields['category'].queryset = GoodsCategory.objects.filter(category_type=1)return contextclass BannerGoodsAdmin(object):list_display = ["goods", "image", "index"]class HotSearchAdmin(object):list_display = ["keywords", "index", "add_time"]class IndexAdAdmin(object):list_display = ["category", "goods"]xadmin.site.register(Goods, GoodsAdmin)
xadmin.site.register(GoodsCategory, GoodsCategoryAdmin)
xadmin.site.register(Banner, BannerGoodsAdmin)
xadmin.site.register(GoodsCategoryBrand, GoodsBrandAdmin)
apps/trade/adminx.py如下:
import xadmin
from .models import ShoppingCart, OrderInfo, OrderGoodsclass ShoppingCartAdmin(object):list_display = ["user", "goods", "nums", ]class OrderInfoAdmin(object):list_display = ["user", "order_sn", "trade_no", "pay_status", "post_script", "order_mount","order_mount", "pay_time", "add_time"]class OrderGoodsInline(object):model = OrderGoodsexclude = ['add_time', ]extra = 1style = 'tab'inlines = [OrderGoodsInline, ]xadmin.site.register(ShoppingCart, ShoppingCartAdmin)
xadmin.site.register(OrderInfo, OrderInfoAdmin)
apps/user_operation/adminx.py如下:
import xadmin
from .models import UserFav, UserLeavingMessage, UserAddressclass UserFavAdmin(object):list_display = ['user', 'goods', "add_time"]class UserLeavingMessageAdmin(object):list_display = ['user', 'message_type', "message", "add_time"]class UserAddressAdmin(object):list_display = ["signer_name", "signer_mobile", "district", "address"]xadmin.site.register(UserFav, UserFavAdmin)
xadmin.site.register(UserAddress, UserAddressAdmin)
xadmin.site.register(UserLeavingMessage, UserLeavingMessageAdmin)
apps/users/adminx.py如下:
import xadmin
from xadmin import views
from .models import VerifyCodeclass BaseSetting(object):enable_themes = Trueuse_bootswatch = Trueclass GlobalSettings(object):site_title = "生鲜后台"site_footer = "fresh_ec"class VerifyCodeAdmin(object):list_display = ['code', 'mobile', "add_time"]xadmin.site.register(VerifyCode, VerifyCodeAdmin)
xadmin.site.register(views.BaseAdminView, BaseSetting)
xadmin.site.register(views.CommAdminView, GlobalSettings)
将xadmin配置到settings.py中:
INSTALLED_APPS = ['django.contrib.auth','django.contrib.contenttypes','django.contrib.sessions','django.contrib.messages','django.contrib.staticfiles','apps.users.apps.UsersConfig','goods','trade','user_operation','DjangoUeditor','xadmin','crispy_forms','django.contrib.admin'
]
还需要安装xadmin的依赖包,从https://github.com/sshwsfc/xadmin/blob/master/requirements.txt可以看到,包括django、django-crispy-forms、django-import-export、django-reversion、django-formtools、future、httplib2和six,可以直接使用一条命令pip install django django-crispy-forms django-import-export django-reversion django-formtools future httplib2 six
安装即可。
此外,还需要安装xlwt和xlsxwriter,这主要用于操作Excel文件、使功能更完善,直接使用命令pip install xlwt xlsxwriter
安装即可。
最后还需要对xadmin进行数据映射,即执行makemigrations
和migrate
即可。
如果遇到ImportError: cannot import name 'six' from 'django.utils'
,可按照下面方法解决:
如果遇到以下报错:
forms.Field.__init__(self, required, widget, label, initial, help_text,
TypeError: __init__() takes 1 positional argument but 6 were given
可直接在xadmin\views\dashboard.py中将forms.Field.__init__(self, required, widget, label, initial, help_text, *args, **kwargs)
改为forms.Field.__init__(self)
即可。
如果遇到其他问题,可参考https://blog.csdn.net/CUFEECR/article/details/104031620进行解决。
进行映射后,再查询数据库:
+------------------------------------+
| Tables_in_fresh_ec |
+------------------------------------+
| auth_group |
| auth_group_permissions |
| auth_permission |
| django_content_type |
| django_migrations |
| django_session |
| goods_banner |
| goods_goods |
| goods_goodscategory |
| goods_goodscategorybrand |
| goods_goodsimage |
| trade_ordergoods |
| trade_orderinfo |
| trade_shoppingcart |
| user_operation_useraddress |
| user_operation_userfav |
| user_operation_userleavingmessage |
| users_userprofile |
| users_userprofile_groups |
| users_userprofile_user_permissions |
| users_verifycode |
| xadmin_bookmark |
| xadmin_log |
| xadmin_usersettings |
| xadmin_userwidget |
+------------------------------------+
25 rows in set (0.01 sec)
显然,xadmin的数据表已经映射进数据库。
此时,还需要对xadmin配置访问路径,urls.py如下:
from django.conf.urls import url
import xadminurlpatterns = [url(r'^xadmin/', xadmin.site.urls),
]
此时还需要创建超级用户,在manage.py@Fresh Ecommerce窗口中执行createsuperuser
命令,输入用户名、邮箱和密码后即可创建超级管理员。
然后访问http://127.0.0.1:8000/xadmin/如下:
显然,此时可以(用刚刚创建的用户名和密码)登录后台,但是网页语言还是英文,需要对settings.py进行设置如下:
LANGUAGE_CODE = 'zh-hans' # 中文支持TIME_ZONE = 'Asia/Shanghai'USE_I18N = TrueUSE_L10N = TrueUSE_TZ = False
apps/goods/apps.py如下:
from django.apps import AppConfigclass GoodsConfig(AppConfig):name = 'goods'verbose_name = '商品'
apps/trade/apps.py如下:
from django.apps import AppConfigclass TradeConfig(AppConfig):name = 'trade'verbose_name = '交易管理'
apps/user_operation/apps.py如下:
from django.apps import AppConfigclass UserOperationConfig(AppConfig):name = 'user_operation'verbose_name = '用户操作管理'
apps/user/apps.py如下:
from django.apps import AppConfigclass UsersConfig(AppConfig):name = 'apps.users'verbose_name = '用户管理'
此时再查看网页如下:
显然,此时已经变为中文,并且点击每个导航栏都能看到具体内容,并且可以进行导出数据等多种操作。
四、数据迁移和数据导入
1.migration原理和表的生成
在导航栏Tools选择点击Run manage.py Task…,在命令行中输入makemigrations
并执行,执行完之后,可以看到每个app下的migrations均生成了0001_initial.py文件。
但是此时数据还并未真正映射到数据库中,还需要执行migrate
命令来执行之前生成的Python文件来映射数据库。也可以在migrate后跟一个具体的app名称来对某个app进行数据库映射,如migrate users
命令就只会映射users下的数据模型。
执行之后,数据库中已经创建出数据模型所对应的表,可以查询如下:
show tables;
打印:
+------------------------------------+
| Tables_in_fresh_ec |
+------------------------------------+
| auth_group |
| auth_group_permissions |
| auth_permission |
| django_content_type |
| django_migrations |
| django_session |
| goods_banner |
| goods_goods |
| goods_goodscategory |
| goods_goodscategorybrand |
| goods_goodsimage |
| trade_ordergoods |
| trade_orderinfo |
| trade_shoppingcart |
| user_operation_useraddress |
| user_operation_userfav |
| user_operation_userleavingmessage |
| users_userprofile |
| users_userprofile_groups |
| users_userprofile_user_permissions |
| users_verifycode |
+------------------------------------+
22 rows in set (0.00 sec)
可以看到,所有的表名称都是由两部分组成,前面是所在的app的名称,剩下的是模型名称的小写形式。
注意:
(1)映射完之后,再修改模型,还需要再次执行makemigrations
和migrate
命令再次同步表到数据库;
django_migrations表保存了每次映射所执行的Python文件,因此不能随意删改这个表中的数据和映射产生的Python文件,否则会对数据映射产生影响。
(2)一旦使用Django模型设计和修改数据模型,就不要再轻易使用MySQL管理工具如Navicat等来手动修改表结构,这样两边不一致会很容易出错。
2.导入商品类别和商品数据
现在是没有数据的,但是为了测试的方便,需要制造一些测试数据并导入。
需要将测试商品的图片文件导入到media/goods目录下,将测试品牌的图片文件导入到media/brands目录下。
然后在db_tools目录下创建名为data的Package,下创建商品数据product_data.py如下:
row_data = [{'images': ['goods/images/1_P_1449024889889.jpg','goods/images/1_P_1449024889264.jpg','goods/images/1_P_1449024889726.jpg','goods/images/1_P_1449024889018.jpg','goods/images/1_P_1449024889287.jpg'],'categorys': ['首页','生鲜食品','根茎类'],'market_price': '¥232元','name': '新鲜水果甜蜜香脆单果约800克','desc': '食用百香果可以增加胃部饱腹感,减少余热量的摄入,还可以吸附胆固醇和胆汁之类有机分子,抑制人体对脂肪的吸收。因此,长期食用有利于改善人体营养吸收结构,降低体内脂肪,塑造健康优美体态。','sale_price': '¥156元','goods_desc': '<p><img src="/media/goods/images/2_20170719161405_249.jpg" title="" alt="2.jpg"/></p><p><img src="/media/goods/images/2_20170719161414_628.jpg" title="" alt="2.jpg"/></p><p><img src="/media/goods/images/2_20170719161435_381.jpg" title="" alt="2.jpg"/></p>'},...,{'sale_price': '¥12元','images': ['goods/images/29_P_1448947631994.jpg'],'market_price': '¥14元','categorys': ['首页','粮油副食','食用油'],'desc': None,'name': '融氏纯玉米胚芽油5l桶','goods_desc': '<p><img src="/media/goods/images/2_20170719161405_249.jpg" title="" alt="2.jpg"/></p><p><img src="/media/goods/images/2_20170719161414_628.jpg" title="" alt="2.jpg"/></p><p><img src="/media/goods/images/2_20170719161435_381.jpg" title="" alt="2.jpg"/></p>'}
]pass
再创建category_data.py如下:
row_data = [{'sub_categorys': [{'sub_categorys': [{'code': 'yr','name': '羊肉'},{'code': 'ql','name': '禽类'},{'code': 'zr','name': '猪肉'},{'code': 'nr','name': '牛肉'}],'code': 'jprl','name': '精品肉类'},{'sub_categorys': [{'code': 'cb','name': '参鲍'},{'code': 'yu','name': '鱼'},{'code': 'xia','name': '虾'},{'code': 'xb','name': '蟹/贝'}],'code': 'hxsc','name': '海鲜水产'},{'sub_categorys': [{'code': 'xhd_xyd','name': '松花蛋/咸鸭蛋'},{'code': 'jd','name': '鸡蛋'}],'code': 'dzp','name': '蛋制品'},{'sub_categorys': [{'code': 'sc','name': '生菜'},{'code': 'bc','name': '菠菜'},{'code': 'yj','name': '圆椒'},{'code': 'xlh','name': '西兰花'}],'code': 'ycl','name': '叶菜类'},{'sub_categorys': [],'code': 'gjl','name': '根茎类'},{'sub_categorys': [],'code': 'qgl','name': '茄果类'},{'sub_categorys': [],'code': 'jgl','name': '菌菇类'},{'sub_categorys': [],'code': 'jksx','name': '进口生鲜'}],'code': 'sxsp','name': '生鲜食品'},...,{'sub_categorys': [{'sub_categorys': [],'code': '白茶','name': '白茶'},{'sub_categorys': [],'code': '红茶','name': '红茶'},{'sub_categorys': [],'code': '绿茶','name': '绿茶'}],'code': '精选茗茶','name': '精选茗茶'}
]
因为存在外键的限制,因此必须先导入category数据,再导入商品数据,这里需要独立于项目单独使用Django的Model。
先创建import_category_data.py如下:
import sys, ospwd = os.path.dirname(os.path.realpath(__file__))
sys.path.append(pwd + '../')
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'Fresh_Ecommerce.settings')import djangodjango.setup()from goods.models import GoodsCategory # 不能位于前面的代码之前,否则会出错from db_tools.data.category_data import raw_datafor lev1_cat in raw_data:lev1_instance = GoodsCategory()lev1_instance.code = lev1_cat['code']lev1_instance.name = lev1_cat['name']lev1_instance.category_type = 1lev1_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 = 2lev2_instance.parent_category = lev1_instancelev2_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 = 3lev3_instance.parent_category = lev2_instancelev3_instance.save()print('Category data imported successfully')
单独运行该文件,打印:
Category data imported successfully
显然,执行成功。
说明:
因为这里是单独使用Django的model,因此需要先进行路径的设置,来保证可以访问项目和app中的内容,所以:
from goods.models import GoodsCategory
必须在
import sys, ospwd = os.path.dirname(os.path.realpath(__file__))
sys.path.append(pwd + '../')
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'Fresh_Ecommerce.settings')import djangodjango.setup()
之后,否则会报错。
此时再查询数据据库如下:
select * from goods_goodscategory;
打印:
+-----+---------------------+---------------------+------+---------------+--------+-----------+--------------------+------------+
| id | name | code | desc | category_type | is_tab | is_delete | parent_category_id | add_time |
+-----+---------------------+---------------------+------+---------------+--------+-----------+--------------------+------------+
| 1 | 生鲜食品 | sxsp | | 1 | 0 | 0 | NULL | 2020-07-21 |
| 2 | 精品肉类 | jprl | | 2 | 0 | 0 | 1 | 2020-07-21 |
| 3 | 羊肉 | yr | | 3 | 0 | 0 | 2 | 2020-07-21 |
| 4 | 禽类 | ql | | 3 | 0 | 0 | 2 | 2020-07-21 |
| 5 | 猪肉 | zr | | 3 | 0 | 0 | 2 | 2020-07-21 |
...
| 116 | 腊味 | 腊味 | | 2 | 0 | 0 | 108 | 2020-07-21 |
| 117 | 精选茗茶 | 精选茗茶 | | 1 | 0 | 0 | NULL | 2020-07-21 |
| 118 | 白茶 | 白茶 | | 2 | 0 | 0 | 117 | 2020-07-21 |
| 119 | 红茶 | 红茶 | | 2 | 0 | 0 | 117 | 2020-07-21 |
| 120 | 绿茶 | 绿茶 | | 2 | 0 | 0 | 117 | 2020-07-21 |
+-----+---------------------+---------------------+------+---------------+--------+-----------+--------------------+------------+
120 rows in set (0.01 sec)
可以看到,共120条数据,分3个类别。
再查看后台管理系统如下:
显然,可以清晰地看到每个商品类别的信息。
再新建import_goods_data.py如下:
import sys, ospwd = os.path.dirname(os.path.realpath(__file__))
sys.path.append(pwd + '../')
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'Fresh_Ecommerce.settings')import djangodjango.setup()from goods.models import Goods, GoodsCategory, GoodsImagefrom db_tools.data.product_data import raw_datafor goods_detail in raw_data:goods = Goods()goods.name = goods_detail['name']goods.market_price = float(goods_detail['market_price'].replace('¥', '').replace('元', ''))goods.shop_price = float(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['desc'] if goods_detail['desc'] is not None else ''goods.goods_front_image = goods_detail['images'][0] if goods_detail['images'] is not None 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_iamge_instance = GoodsImage()goods_iamge_instance.image = goods_imagegoods_iamge_instance.goods = goodsgoods_iamge_instance.save()print('Goods data imported successfully')
单独运行该文件,打印:
Goods data imported successfully
即数据导入成功。
因为商品关系到图片,因此需要再settings.py中设置图访问路径,如下:
STATIC_URL = '/static/'MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
urls.py配置如下:
from django.conf.urls import url
from django.views.static import serve
import xadmin
from Fresh_Ecommerce.settings import MEDIA_ROOTurlpatterns = [url(r'^xadmin/', xadmin.site.urls),url(r'^media/(?P<path>.*)$', serve, {'document_root':MEDIA_ROOT}),
]
再访问后台如下:
显然,数据已经插入成功。
我的博客即将同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=2cj8adg3kxogs
Django+Vue开发生鲜电商平台之3.数据模型设计和资源导入相关推荐
- Django+Vue开发生鲜电商平台之1.项目介绍
文章目录 一.项目概览 二.项目技术要点 三.项目预览 我永远相信只要永不放弃,我们还是有机会的.最后,我们还是坚信一点,这世界上只要有梦想,只要不断努力,只要不断学习,不管你长得如何,不管是这样,还 ...
- Django+Vue开发生鲜电商平台之2.开发环境搭建
文章目录 一.PyCharm的安装和简单使用 二.MySQL和Navicat的安装和使用 三.Python的安装 四.虚拟环境的安装和配置 五.Vue开发环境搭建 一.PyCharm的安装和简单使用 ...
- Django+Vue开发生鲜电商平台之11.首页、商品数量、缓存和限速功能开发
文章目录 一.首页功能完善 1.轮播图实现 2.新品功能开发 3.商品系列分类展示功能 二.商品相关数量功能实现 1.商品点击数.收藏数功能实现 2.商品库存量和销量功能实现 三.DRF缓存设置 1. ...
- Django+Vue开发生鲜电商平台之10.购物车、订单管理和支付功能
文章目录 一.购物车功能实现 1.加入购物车功能实现 2.修改购物车数量功能实现 3.和Vue结合实现购物车功能 二.订单功能实现 1.订单管理接口 2.Vue接入订单接口 三.支付宝支付接口完成 1 ...
- JAVA毕设项目社区生鲜电商平台(java+VUE+Mybatis+Maven+Mysql)
JAVA毕设项目社区生鲜电商平台(java+VUE+Mybatis+Maven+Mysql) 项目运行 环境配置: Jdk1.8 + Tomcat8.5 + Mysql + HBuilderX(Web ...
- Java生鲜电商平台-SpringCloud微服务开发中的数据架构设计实战精讲
Java生鲜电商平台-SpringCloud微服务开发中的数据架构设计实战精讲 Java生鲜电商平台: 微服务是当前非常流行的技术框架,通过服务的小型化.原子化以及分布式架构的弹性伸缩和高可用性, ...
- Java生鲜电商平台-App系统架构开发与设计
Java生鲜电商平台-App系统架构开发与设计 说明:阅读此文,你可以学习到以下的技术分享 1.Java生鲜电商平台-App架构设计经验谈:接口的设计 2.Java生鲜电商平台-App架构设计经验谈: ...
- java 团购开发_Java生鲜电商平台-团购模块设计与架构
Java生鲜电商平台-团购模块设计与架构 说明:任何一个电商系统中,对于促销这块是必不可少的,毕竟这块是最吸引用户的,用户也是最爱的模块之一,理由很简单,便宜. 我的经验是无论是大的餐饮点还是小的餐饮 ...
- 【附源码】Python计算机毕业设计社区生鲜电商平台
项目运行 环境配置: Pychram社区版+ python3.7.7 + Mysql5.7 + HBuilderX+list pip+Navicat11+Django+nodejs. 项目技术: dj ...
最新文章
- 宏基因组合种华山松、云杉专车3天领证
- ASP.NET MVC 1.0 RC 版发布了【转】
- 如何在MFC中调用CUDA
- python type help copyright_Python关于import的实验(8)__init__.py文件内部代码的执行以及内部的导入和内部的变量...
- java大型wms架构设计_Java生鲜电商平台-库存管理设计与架构
- 小技巧:Chrome开发者工具里的Alt+单击
- LVS集群应用配置详解
- keras 的dot、multiply区别
- Ubuntu 下网易云音乐出现“加载失败,网络错误,可以在设置中发送反馈”问题及解决
- dtcms配置多参数
- selenium2 WebDriver 在asp.net项目中的应用
- 智能管家App kotlin版(1)——框架搭建
- Eclips 安装教程
- java怎么实现分享链接_分享Java
- HNU-电子测试平台与工具-元器件及测量基础
- 《零基础学C语言》前言
- android sqlite fts4,在Sqlite中创建动态FTS4表
- python中的copy()与deepcopy()
- idea中的Diagram功能,查看类图
- 诺奖得主本庶佑:真正一流的工作往往没有在顶级刊物上发表!
热门文章
- 电脑c语言发音,C的发音
- 基于51单片机远近光灯切换电路设计方案
- 点击链接跳转到微信公众号关注页、微信关注链接
- 爬虫学习笔记 - day02
- PHP气缸种类,【汽缸】【气缸】|× 【Q】√ - 校对标准:寻找权威依据 - Powered by phpwind...
- 开源软件的许可证(License)
- 【python 监控报警】python 免费短信报警和电话报警
- 解释术语 计算机系统结构,北京邮电大学 计算机系统结构(体系结构) 期末复习 术语解释.doc...
- 《Photoshop修饰与合成专业技法》—第1章伪造的抠像:第一部分
- 华为Android彩蛋,华为手机DIY拨号及彩蛋功能介绍