Django REST framework+Vue 打造生鲜超市(二)

时间:2024-01-23 09:53:24

Django REST framework+Vue 打造生鲜超市(二)

三、Models设计

3.1.项目初始化

(1)进虚拟环境下安装

  • django2.0.2
  • djangorestframework和相关依赖mark,filter
  • pillow  图片处理
pip install djangorestframework

pip install -i https://pypi.douban.com/simple django==2.0.2

pip install markdown

pip install django-filter

pip install pillow

pip install pymysql

(2)创建项目

  • 项目:MxShop
  • app:users

 

 interpreter选择虚拟环境里面的python.exe

 

(3)Mysql的配置

settings中设置

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'mxshop',        #数据库名字
        'USER': 'root',          #账号
        'PASSWORD': '123456',    #密码
        'HOST': '127.0.0.1',     #IP
        '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

__init__.py添加代码:

import pymysql
pymysql.install_as_MySQLdb()

(4)项目目录结构搭建

新建两个python package

  • extra_apps   (扩展的源码包)
  • apps              (放所有app)

新建两个文件夹

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

把extra_apps和apps标记为sources root,然后settings中也要加路径

#settings.py

import sys

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'))

现在项目目录如下:

 

3.2.users models设计

(1)创建三个app

  • goods        商品
  • trade          交易
  • user_operation       用户操作

 

(2)users/models.py

# apps/users/models.py

from datetime import datetime

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

class UserProfile(AbstractUser):
    '''
    用户信息
    '''
    GENDER_CHOICES = (
        ('male',''),
        ('female','')
    )

    #因为用户是用手机号注册,所以这里name,birthday,email字段可以为空
    name = models.CharField('姓名',max_length=32,null=True,blank=True)
    birthday = models.DateField('出生日期',null=True,blank=True)
    gender = models.CharField('性别',max_length=10,choices=GENDER_CHOICES,default='male')
    mobile = models.CharField('手机号',max_length=11)
    email = models.EmailField('邮箱',max_length=128,null=True,blank=True)

    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)
    mobile = models.CharField('手机号', max_length=11)
    add_time = models.DateTimeField('添加时间',default=datetime.now)

    class Meta:
        verbose_name = '短信验证码'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.code

要想替换系统的用户,还要在settings中配置

#settings.py

#重载系统的用户,让UserProfile生效
AUTH_USER_MODEL = 'users.UserProfile'

(3)这里UserProfile继承AbstractUser,可以看看AbstractUser的源码

class AbstractUser(AbstractBaseUser, PermissionsMixin):
    """
    An abstract base class implementing a fully featured User model with
    admin-compliant permissions.

    Username and password are required. Other fields are optional.
    """
    username_validator = UnicodeUsernameValidator()

    username = models.CharField(
        _('username'),
        max_length=150,
        unique=True,
        help_text=_('Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.'),
        validators=[username_validator],
        error_messages={
            'unique': _("A user with that username already exists."),
        },
    )
    first_name = models.CharField(_('first name'), max_length=30, blank=True)
    last_name = models.CharField(_('last name'), max_length=150, blank=True)
    email = models.EmailField(_('email address'), blank=True)
    is_staff = models.BooleanField(
        _('staff status'),
        default=False,
        help_text=_('Designates whether the user can log into this admin site.'),
    )
    is_active = models.BooleanField(
        _('active'),
        default=True,
        help_text=_(
            'Designates whether this user should be treated as active. '
            'Unselect this instead of deleting accounts.'
        ),
    )
    date_joined = models.DateTimeField(_('date joined'), default=timezone.now)

    objects = UserManager()

    EMAIL_FIELD = 'email'
    USERNAME_FIELD = 'username'
    REQUIRED_FIELDS = ['email']

    class Meta:
        verbose_name = _('user')
        verbose_name_plural = _('users')
        abstract = True

    def clean(self):
        super().clean()
        self.email = self.__class__.objects.normalize_email(self.email)

    def get_full_name(self):
        """
        Return the first_name plus the last_name, with a space in between.
        """
        full_name = '%s %s' % (self.first_name, self.last_name)
        return full_name.strip()

    def get_short_name(self):
        """Return the short name for the user."""
        return self.first_name

    def email_user(self, subject, message, from_email=None, **kwargs):
        """Send an email to this user."""
        send_mail(subject, message, from_email, [self.email], **kwargs)
源码

 

3.3.goods的model设计

(1)安装

 安装好后把xadmin和DjangoUeditor放到extra_apps目录下面

 

(2)把四个app、xadmin和DjangoUeditor添加到 INSTALLED_APPS中

INSTALLED_APPS = [
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'users',
    'goods',
    'trade',
    'user_operation',
    'rest_framework',
    'xadmin',
    'crispy_forms',
    'DjangoUeditor'
]

 设置media的保存路径

#settings.py

MEDIA_ROOT = os.path.join(BASE_DIR, "media")

(3)商品分类model 设计

from datetime import datetime
from django.db import models


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

    name = models.CharField('类别名',default='',max_length=30,help_text='类别名')
    code = models.CharField('类别code',default='',max_length=30,help_text='类别code')
    desc = models.TextField('类别描述',default='',help_text='类别描述')
    #目录级别,总共有三个级别
    category_type = models.IntegerField('类目级别',choices=CATEGORY_TYPE)
    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',help_text='是否导航')
    add_time = models.DateTimeField('添加时间',default=datetime.now)

    class Meta():
        verbose_name = '商品类别'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.name

 

 

 

 (4)品牌名model设计

from djangoUeditor.models import UEditorField


class Goods(models.Model):
    '''
    商品
    '''

    category = models.ForeignKey(GoodsCategory,verbose_name='商品类目',on_delete=models.CASCADE)
    goods_sn = models.CharField('商品唯一货号',max_length=50,default='')
    name = models.CharField('商品名',max_length=100)
    click_num = models.IntegerField('点击数',default=0)
    sold_num = models.IntegerField('商品销售量',default=0)
    fav_num = models.IntegerField('收藏数',default=0)
    goods_num = models.IntegerField('库存数',default=0)
    market_price = models.FloatField('市场价格',default=0)
    shop_price = models.FloatField('本店价格',default=0)
    goods_brief = models.TextField('商品简短描述',max_length=500)
    goods_desc = UEditorField(
        verbose_name='内容',
        imagePath='goods/images/',
        width=1000,
        height=300,
        filePath='goods/files/',
        default=''
    )
    ship_free = models.BooleanField('是否承担运费',default=True)
    goods_front_image = models.ImageField(
        '封面图',
        upload_to='goods/images/',
        null=True,
        blank=True
    )
    is_new = models.BooleanField('是否新品',default=False)
    is_hot = models.BooleanField('是否新热销',default=False)
    add_time = models.DateTimeField('添加时间', default=datetime.now)

    class Meta():
        verbose_name = '商品'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.name


class GoodsImage(models.Model):
    '''
    商品详情页轮播图
    '''
    goods = models.ForeignKey(Goods,verbose_name='商品',related_name='images',on_delete=models.CASCADE)
    image = models.ImageField(
        '图片',
        null=True,
        blank=True,
        upload_to=''
    )
    add_time = models.DateTimeField('添加时间', default=datetime.now)

    class Meta():
        verbose_name = '商品轮播图'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.goods.name

 

 

 

 (4)首页商品轮播图model设计

因为首页的商品轮播图片是大图,跟商品详情里面的图片不一样,所以要单独写一个首页轮播图model

class Banner(models.Model):
    '''
    轮播的商品
    '''
    goods = models.ForeignKey(Goods,verbose_name='商品',on_delete=models.CASCADE)
    image = models.ImageField('轮播图片',upload_to='banner')
    index = models.IntegerField('轮播顺序',default=0)
    add_time = models.DateTimeField('添加时间', default=datetime.now)

    class Meta():
        verbose_name = '首页轮播商品'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.goods.name

 

 

3.4.trade交易的model设计

trade/models.py

# apps/trade/models.py

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

from django.contrib.auth import get_user_model
#调用这个方法会自动去settings中找我们设置的UserProfile model--->>>settings.AUTH_USER_MODEL
#User相当于users中的UserProfile
User = get_user_model()

class OrderInfo(models.Model):
    '''
    订单信息
    '''
    ORDER_STATUS = {
        ('TRADE_SUCCESS','成功'),
        ('TRADE_CLOSED','超市关闭'),
        ('TRADE_BUYER_PAY','交易创建'),
        ('TRADE_FINISHED','交易结束'),
        ('paying','待支付'),
    }

    user = models.ForeignKey(User,verbose_name='用户')
    order_sn = models.CharField( '订单编号', null=True, blank=True,max_length=30,unique=True)
    trade_no = models.CharField( '交易号',max_length=100,unique=True,null=True, blank=True)
    pay_status = models.CharField('订单状态',choices=ORDER_STATUS,default='paying',max_length=30)
    pay_script = models.CharField('订单留言',max_length=200)
    order_mount = models.FloatField('订单金额',default=0.0)
    pay_time = models.DateTimeField('支付时间',null=True,blank=True)

    #用户的信息
    address = models.CharField('收获地址',max_length=100,default='')
    singer_name = models.CharField('签收人',max_length=20,default='')
    singer_mobile = models.CharField('联系电话',max_length=11)
    add_time = models.DateTimeField('添加时间', default=datetime.now)

    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,verbose_name='订单信息',related_name='goods',on_delete=models.CASCADE)
    goods = models.ForeignKey(Goods,verbose_name='商品',on_delete=models.CASCADE)
    goods_num = models.IntegerField('商品数量',default=0)

    add_time = models.DateTimeField('添加时间', default=datetime.now)

    class Meta():
        verbose_name = '订单商品'
        verbose_name_plural = verbose_name

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

 

3.5.用户操作的model设计

user_operation/models.py

 

# user_operation/models.py

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

from django.contrib.auth import get_user_model
#调用这个方法会自动去settings中找我们设置的UserProfile model--->>>settings.AUTH_USER_MODEL
#User相当于users中的UserProfile
User = get_user_model()


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

    class Meta():
        verbose_name = '用户收藏'
        verbose_name_plural = verbose_name

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


class UserAddress(models.Model):
    '''
    收货地址
    '''
    user = models.ForeignKey(User, verbose_name='用户', on_delete=models.CASCADE)
    provice = models.CharField('省份',max_length=100,default='')
    city = models.CharField('城市',max_length=100,default='')
    distrit = models.CharField('区域',max_length=100,default='')
    address = models.CharField('详细地址',max_length=100,default='')
    signer_name = models.CharField('签收人',max_length=100,default='')
    signer_mobile = models.CharField('电话',max_length=11,default='')
    add_time = models.DateTimeField('添加时间', default=datetime.now)

    class Meta():
        verbose_name = '收获地址'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.address


class UserLeavinMessage(models.Model):
    '''
    用户留言
    '''
    MESSAGE_CHOICES = (
        (1,'留言'),
        (2,'投诉'),
        (3,'询问'),
        (4,'售后'),
        (5,'求购'),
    )
    user = models.ForeignKey(User, verbose_name='用户', on_delete=models.CASCADE)
    message_type = models.IntegerField(
        '留言类型',
        choices=MESSAGE_CHOICES,
        default=1,
        help_text="留言类型: 1(留言),2(投诉),3(询问),4(售后),5(求购)"
    )
    subject = models.CharField('主题',max_length=100,default='')
    message = models.TextField('留言内容',default='',help_text='留言内容')
    file = models.FileField('上传的文件',upload_to='message/images',help_text='上传的文件')
    add_time = models.DateTimeField('添加时间', default=datetime.now)

    class Meta():
        verbose_name = '用户留言'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.subject

 

posted on 2018-04-08 02:38 zhang_derek 阅读(...) 评论(...) 编辑 收藏