美文网首页
Vue+Django REST framework生鲜电商项目笔

Vue+Django REST framework生鲜电商项目笔

作者: 朝鹿志 | 来源:发表于2020-07-23 12:52 被阅读0次

一、项目初始化

  • 创建虚拟环境安装库
pip install Django==2.2.12
pip install djangorestframework
pip install markdown
pip install django-filter
pip install coreapi
pip install Pygments
pip install django-guardian
pip install pillow
  • 创建项目配置MySQL
    image.png
    settings.py中设置
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'shop',
        'USER':'root',
        'PASSWORD':'123123',
        'HOST':'127.0.0.1',
        'PORT':'3306',
        #这里引擎用innodb(默认myisam)
        #因为后面第三方登录时,要求引擎为INNODB
        # 'OPTIONS':{'init_command': 'SET storage_engine=INNODB'}, #这样设置会报错,改为
        "OPTIONS":{"init_command":"SET default_storage_engine=INNODB;"}
    }
}

安装Mysqlclient
下载地址 https://www.lfd.uci.edu/~gohlke/pythonlibs/
安装方式 pip install mysqlclient-1.3.12-cp36-cp36m-win_amd64

  • 项目结构搭建

新建两个python package

extra_apps (扩展的源码包)
apps (放所有app)
新建两个文件夹

media (保存图片)
db_tools (数据库相关)

二、应用Model设计

users/models.py

from datetime import datetime

from django.contrib.auth.models import AbstractUser
from django.db import models


class UserProfile(AbstractUser):
    GENDER_CHOICES = (
        ('male', '男'),
        ('female', '女')
    )
    nick_name = models.CharField(max_length=20, null=True, blank=True, verbose_name='昵称')
    birthday = models.DateField(null=True, blank=True, verbose_name='出生日期')
    gender = models.CharField(max_length=6, choices=GENDER_CHOICES, default='female', verbose_name='性别')
    mobile = models.CharField(max_length=11, verbose_name='手机号')
    email = models.EmailField(max_length=60, null=True, blank=True, verbose_name='邮箱')

    class Meta:
        verbose_name = '用户'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.username


class VerifyCode(models.Model):
    code=models.CharField(max_length=10,verbose_name='验证码')
    mobile = models.CharField(max_length=11, 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.code

goods/models.py

from datetime import datetime

from django.db import models
from extra_apps.DjangoUeditor.models import UEditorField

class GoodsCategory(models.Model):
    CATEGORY_TYPE=(
        (1, '一级目录'),
        (2, '二级目录'),
        (3, '三级目录'),
    )

    name=models.CharField(max_length=30,default='',verbose_name='类别名',help_text='类别名')
    code=models.CharField(max_length=30,default='',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',on_delete=models.CASCADE,null=True,blank=True,verbose_name='父类目级别',help_text='父目录',related_name='sub_cat')
    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


class GoodsCategoryBrand(models.Model):
    """
    品牌名
    """
    category=models.ForeignKey(GoodsCategory,on_delete=models.CASCADE,null=True,blank=True,verbose_name='商品类目')
    name=models.CharField(max_length=20,default='',verbose_name='品牌名',help_text='品牌名')
    desc=models.TextField(max_length=300,default='',verbose_name='品牌描述',help_text='品牌描述')
    image=models.ImageField(max_length=200,upload_to='brands/images',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


class Goods(models.Model):
    """
    商品
    """
    category=models.ForeignKey(GoodsCategory,on_delete=models.CASCADE,verbose_name='所属商品类目')
    goods_sn=models.CharField(max_length=50,default='',verbose_name='商品唯一货号')
    name=models.CharField(max_length=50,default='',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=300,verbose_name='商品简短描述')
    goods_desc=UEditorField(default='',width=1000,height=300,imagePath="goods/images/",filePath="goods/files/",verbose_name=u'内容')
    ship_free=models.BooleanField(default=True, verbose_name="是否承担运费")
    goods_front_image = models.ImageField(max_length=200,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





class GoodsImage(models.Model):
    goods=models.ForeignKey(Goods,on_delete=models.CASCADE,related_name='images',verbose_name='商品')
    image=models.ImageField(max_length=200,upload_to="", null=True, blank=True,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.goods.name


class Banner(models.Model):
    goods = models.ForeignKey(Goods,on_delete=models.CASCADE, verbose_name='商品名')
    image = models.ImageField(upload_to='banner/images', verbose_name='轮播图')
    index = models.IntegerField(default=0, 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.goods.name

# Create your models here.

trade/models.py

from django.db import models
from datetime import  datetime
from django.db import models
from apps.goods.models import Goods

# get_user_model方法会去setting中找AUTH_USER_MODEL
from django.contrib.auth import get_user_model
User=get_user_model()



class ShoppingCart(models.Model):
    """
    购物车
    """
    user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name="用户")
    goods = models.ForeignKey(Goods, on_delete=models.CASCADE, verbose_name="商品")
    goods_nums = models.IntegerField(default=0, verbose_name="购买数量")
    add_time = models.DateTimeField(default=datetime.now, verbose_name="添加时间")

    class Meta:
        verbose_name = '购物车'
        verbose_name_plural = verbose_name
        unique_together = ("user", "goods")

    def __str__(self):
        return "{0}({1})".format(self.goods.name,self.goods_nums)




class OrderInfo(models.Model):
    """
    订单信息
    """
    ORDER_STATUS = (
        ("TRADE_SUCCESS", "成功"),
        ("TRADE_CLOSED", "超时关闭"),
        ("WAIT_BUYER_PAY", "交易创建"),
        ("TRADE_FINISHED", "交易结束"),
        ("paying", "待支付"),
    )
    PAY_TYPE = (
        ("alipay", "支付宝"),
        ("wechat", "微信"),
    )
    user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name="用户")
    # 订单号唯一
    order_sn = models.CharField(max_length=30, null=True, blank=True, unique=True,verbose_name="订单编号")
    # 微信支付会用到
    nonce_str = models.CharField(max_length=50, null=True, blank=True, unique=True,verbose_name="随机加密串")
    # 支付宝交易号
    trade_no = models.CharField(max_length=100,unique=True, null=True, blank=True,verbose_name="交易号")
    # 支付状态
    pay_status = models.CharField(max_length=30,choices=ORDER_STATUS, default="paying",verbose_name="订单状态")
    # 订单的支付类型
    pay_type = models.CharField(max_length=10,choices=PAY_TYPE, default="alipay",verbose_name="支付类型")
    post_script = models.CharField(max_length=200,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="签收人")
    singer_mobile = models.CharField(max_length=11,verbose_name="联系电话")
    add_time = models.DateTimeField(default=datetime.now, verbose_name="添加时间")

    class Meta:
        verbose_name = "订单信息"
        verbose_name_plural = verbose_name

    def __str__(self):
        return str(self.order_sn)


class OrderGoods(models.Model):
    """
       订单商品详情
    """
    # 一个订单对应多个商品
    order = models.ForeignKey(OrderInfo, on_delete=models.CASCADE, verbose_name="订单信息", related_name="goods")
    # 两个外键形成一张关联表
    goods = models.ForeignKey(Goods, on_delete=models.CASCADE, verbose_name="商品")
    goods_num = models.IntegerField(default=0,verbose_name="商品数量")
    add_time = models.DateTimeField(default=datetime.now,verbose_name="添加时间")

    class Meta:
        verbose_name = "订单商品"
        verbose_name_plural = verbose_name

    def __str__(self):
        return str(self.order.order_sn)
# Create your models here.

users_operation/models.py

from datetime import  datetime
from django.db import models
from apps.goods.models import Goods

# get_user_model方法会去setting中找AUTH_USER_MODEL
from django.contrib.auth import get_user_model
User=get_user_model()


class UserFav(models.Model):
    user=models.ForeignKey(User,on_delete=models.CASCADE,verbose_name='用户')
    goods = models.ForeignKey(Goods,on_delete=models.CASCADE,verbose_name="商品", help_text="商品id")
    add_time = models.DateTimeField(default=datetime.now, verbose_name='添加时间')

    class Meta:
        verbose_name = '用户收藏'
        verbose_name_plural = verbose_name
        unique_together = ("user", "goods")

    def __str__(self):
        return self.user.username


class UserLeavingMessage(models.Model):
    MESSAGE_CHOICES = (
        (1, "留言"),
        (2, "投诉"),
        (3, "询问"),
        (4, "售后"),
        (5, "求购")
    )
    user = models.ForeignKey(User,on_delete=models.CASCADE,verbose_name="用户")
    message_type = models.IntegerField(default=1, choices=MESSAGE_CHOICES, verbose_name="留言类型",help_text=u"留言类型: 1(留言),2(投诉),3(询问),4(售后),5(求购)")
    subject = models.CharField(max_length=100, default="", verbose_name="主题")
    message = models.TextField(default="", verbose_name="留言内容", help_text="留言内容")
    file = models.FileField(upload_to="message/images/", 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.subject



class UserAddress(models.Model):
    """
    用户收货地址
    """
    user = models.ForeignKey(User,on_delete=models.CASCADE,verbose_name="用户" )
    province = models.CharField(max_length=100, default="", verbose_name="省份")
    city = models.CharField(max_length=100, default="", verbose_name="城市")
    district = models.CharField(max_length=100, default="", verbose_name="区域")
    address = models.CharField(max_length=100, default="", verbose_name="详细地址")
    signer_name = models.CharField(max_length=100, default="", verbose_name="签收人")
    signer_mobile = models.CharField(max_length=11, default="", 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.address
# Create your models here.
  • 配置APP安装xadmin依赖
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    "rest_framework",
    'goods.apps.GoodsConfig',
    'users.apps.UsersConfig',
    'user_operation.apps.UserOperationConfig',
    'trade.apps.TradeConfig',
    'DjangoUeditor',
    'xadmin',
    'crispy_forms',#xadmin依赖 
]

三、单独使用model导入商品类别数据

由于分类和商品的数据很多,我们写个脚本来导入,我们单独使用Django中的Model批量导入数据

  • db_tools下新建文件夹data,然后把前端的json文件(category_data和product_data)拷贝到里面
  • 把brands和goods图片拷贝到media目录下

#db_tools/import_category_data.py

#独立使用django中的model
import os,sys

#  获取当前文件的路径,以及路径的父级文件夹名
pwd=os.path.dirname(os.path.realpath(__file__))
# 将项目目录加入setting
sys.path.append(pwd+"../")
# manage.py中
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'GoShop.settings')

import  django
django.setup()

# 这行代码必须在初始化django之后
from apps.goods.models import GoodsCategory

from db_tools.data.category_data import row_data


#遍历入库 一级分类
for lev1_cat in row_data:
    lev1_intance=GoodsCategory()
    lev1_intance.code=lev1_cat['code']
    lev1_intance.name=lev1_cat['name']
    lev1_intance.category_type=1
    lev1_intance.save()
    # 二级分类
    for lev2_cat in lev1_cat['sub_categorys']:
        lev2_intance = GoodsCategory()
        lev2_intance.code = lev2_cat['code']
        lev2_intance.name = lev2_cat['name']
        lev2_intance.category_type = 2
        lev2_intance.parent_category=lev1_intance
        lev2_intance.save()
        #三级分类
        for lev3_cat in  lev2_cat['sub_categorys']:
            lev3_intance = GoodsCategory()
            lev3_intance.code = lev3_cat['code']
            lev3_intance.name = lev3_cat['name']
            lev3_intance.category_type = 3
            lev3_intance.parent_category = lev2_intance
            lev3_intance.save()

#db_tools/import_goods_data.py

#独立使用django中的model
import os,sys

#  获取当前文件的路径,以及路径的父级文件夹名
pwd=os.path.dirname(os.path.realpath(__file__))
# 将项目目录加入setting
sys.path.append(pwd+"../")
# manage.py中
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'GoShop.settings')

import  django
django.setup()

# 这行代码必须在初始化django之后
from apps.goods.models import Goods, GoodsImage, GoodsCategory

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.shop_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 ""
    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()
  • 配置Media设置
#settings.py_设置上传文件路径
MEDIA_URL='/media/'
MEDIA_ROOT=os.path.join(BASE_DIR,'media')

#urls.py_设置媒体文件访问路径
url(r'^media/(?P<path>.*)$',serve,{'document_root':MEDIA_ROOT}),
image.png

"OPTIONS":{"init_command":"SET default_storage_engine=INNODB;"}

相关文章

网友评论

      本文标题:Vue+Django REST framework生鲜电商项目笔

      本文链接:https://www.haomeiwen.com/subject/ylpbcktx.html