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 xadmin安装方法
- DjangoUeditor 富文本编辑器安装方法
安装好后把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 阅读(...) 评论(...) 编辑 收藏