Django+Vue开发生鲜电商平台之3.数据模型设计和资源导入(上)

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS MySQL,高可用系列 2核4GB
简介: 文章目录一、项目初始化二、数据模型设计1.用户数据模型设计2.商品数据模型设计3.交易数据模型设计4.用户操作数据模型设计三、xadmin后台管理系统的配置四、数据迁移和数据导入1.migration原理和表的生成2.导入商品类别和商品数据

一、项目初始化

在虚拟环境安装好之后,需要安装DjangoDjango REST framework,直接在虚拟环境下使用pip install djangopip 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 datetime
from 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.name
class 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_name
    def __str__(self):
        return self.code

此时定义的用户还未替换系统自定义的用户,还需要在settings.py中进行设置:

ALLOWED_HOSTS = []
AUTH_USER_MODEL = 'users.UserProfile'

2.商品数据模型设计

商品包括商品分类(分为3个层次,具有从属关系)、品牌名、商品、商品轮播图、轮播商品等实体,goods/models.py建立模型如下:

from datetime import datetime
from 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_name
    def __str__(self):
        return self.name
class 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_name
    def __str__(self):
        return self.name
class 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_name
    def __str__(self):
        return self.goods.name
class 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_name
    def __str__(self):
        return self.goods.name

在建立商品模型时,需要用到百度的富文本编辑器UEditor,但是由于官方的Django UEditor停止维护、不再支持Python3,因此需要自行下载,可点击https://download.csdn.net/download/CUFEECR/12641702https://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 datetime
from django.db import models
from django.contrib.auth import get_user_model  # from user.models import UserProfile
from goods.models import Goods
User = 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_name
    def __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_name
    def __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 datetime
from django.db import models
from django.contrib.auth import get_user_model
from goods.models import Goods
User = 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_name
    def __str__(self):
        return self.user.name
class 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_name
    def __str__(self):
        return self.subject
class 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_name
    def __str__(self):
        return self.address


相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
26天前
|
存储 缓存 前端开发
Django 后端架构开发:存储层调优策略解析
Django 后端架构开发:存储层调优策略解析
36 2
|
26天前
|
负载均衡 应用服务中间件 网络安全
Django后端架构开发:Nginx服务优化实践
Django后端架构开发:Nginx服务优化实践
36 2
|
26天前
|
消息中间件 存储 监控
Django后端架构开发:Celery异步调优,任务队列和调度
Django后端架构开发:Celery异步调优,任务队列和调度
40 1
|
21天前
|
C++ Python
Django视图函数VS类视图:如何选择最适合你的开发方式?
【8月更文挑战第31天】本文对比了Django中的函数视图和类视图。函数视图直接处理HTTP请求和响应,灵活且易于维护,适用于简单业务逻辑;类视图基于Python类,提供更丰富的功能和更高的灵活性,适合处理复杂业务逻辑。选择哪种视图取决于具体需求,合理使用两者可帮助你构建高效且易维护的Django应用。
12 0
|
26天前
|
存储 缓存 关系型数据库
Django后端架构开发:缓存机制,接口缓存、文件缓存、数据库缓存与Memcached缓存
Django后端架构开发:缓存机制,接口缓存、文件缓存、数据库缓存与Memcached缓存
29 0
|
26天前
|
存储 API 数据库
Django后端架构开发:构建在线云媒资系统思路解析
Django后端架构开发:构建在线云媒资系统思路解析
32 0
|
26天前
|
存储 监控 开发工具
Django 后端架构开发:手机与邮箱验证码接入、腾讯云短信SDK和网易邮箱
Django 后端架构开发:手机与邮箱验证码接入、腾讯云短信SDK和网易邮箱
26 0
|
1月前
|
机器学习/深度学习 数据采集 数据可视化
基于爬虫和机器学习的招聘数据分析与可视化系统,python django框架,前端bootstrap,机器学习有八种带有可视化大屏和后台
本文介绍了一个基于Python Django框架和Bootstrap前端技术,集成了机器学习算法和数据可视化的招聘数据分析与可视化系统,该系统通过爬虫技术获取职位信息,并使用多种机器学习模型进行薪资预测、职位匹配和趋势分析,提供了一个直观的可视化大屏和后台管理系统,以优化招聘策略并提升决策质量。
|
1月前
|
搜索推荐 前端开发 数据可视化
【优秀python web毕设案例】基于协同过滤算法的酒店推荐系统,django框架+bootstrap前端+echarts可视化,有后台有爬虫
本文介绍了一个基于Django框架、协同过滤算法、ECharts数据可视化以及Bootstrap前端技术的酒店推荐系统,该系统通过用户行为分析和推荐算法优化,提供个性化的酒店推荐和直观的数据展示,以提升用户体验。
|
13天前
|
前端开发 搜索推荐 算法
中草药管理与推荐系统Python+Django网页界面+推荐算法+计算机课设系统+网站开发
中草药管理与推荐系统。本系统使用Python作为主要开发语言,前端使用HTML,CSS,BootStrap等技术和框架搭建前端界面,后端使用Django框架处理应用请求,使用Ajax等技术实现前后端的数据通信。实现了一个综合性的中草药管理与推荐平台。具体功能如下: - 系统分为普通用户和管理员两个角色 - 普通用户可以登录,注册、查看物品信息、收藏物品、发布评论、编辑个人信息、柱状图饼状图可视化物品信息、并依据用户注册时选择的标签进行推荐 和 根据用户对物品的评分 使用协同过滤推荐算法进行推荐 - 管理员可以在后台对用户和物品信息进行管理编辑
48 12
中草药管理与推荐系统Python+Django网页界面+推荐算法+计算机课设系统+网站开发