(项目)生鲜超市(二)

三、Model设计

1、项目初始化

  该项目使用Django Rest Framework完成后台功能,需要安装djangorestframework包及其相关的依赖包,pillow库是图片处理的库,在虚拟环境中安装如下包:

  • pip install djangorestframework
  • pip install markdown
  • pip install django-filter
  • pip install pillow
  • pip install pymysql

  安装完成之后,在settings.py中进行数据库的配置,在这之前需要在数据库中创建一个mxshop数据库:

 1 DATABASES = {
 2     'default': {
 3         'ENGINE': 'django.db.backends.mysql',
 4         'NAME': 'mxshop',
 5         'USER': 'root',
 6         'PASSWORD': 'python',
 7         'HOST': '192.168.161.129',
 8         'PORT': 3306,
 9         'OPTIONS':{'init_command': 'SET default_storage_engine=INNODB;'}
10     }
11 }

  然后安装对应python版本的mysqlclient,下载地址:https://www.lfd.uci.edu/~gohlke/pythonlibs/#mysqlclient,下载好之后放到项目根目录下,直接

pip install mysqlclient-1.3.13-cp36-cp36m-win_amd64.whl

  然后在__init__.py文件中添加代码:

1 import pymysql
2 
3 pymysql.install_as_MySQLdb()

  现在完善项目的目录结构,在项目根目录下新建两个package包:

  • extra_apps(扩展的源码包)
  • apps(放项目创建的app)

  新建两个文件夹:

  • media(上传的文件)
  • db_tools(数据相关)

  将extra_apps和apps两个包标记为sources root,然后在settings.py中添加文件访问路径:

1 import os
2 import sys
3 
4 # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
5 BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
6 sys.path.insert(0, BASE_DIR)
7 sys.path.insert(0, os.path.join(BASE_DIR, 'apps'))
8 sys.path.insert(0, os.path.join(BASE_DIR, 'extra_apps'))

  现在项目的目录结构如下:

 2、model设计

  该项目需要创建四个app,之前在创建django项目的时候已经创建了users用户app了,现在创建其余三个:

  • startapp goods(商品相关)
  • startapp trade(交易相关)
  • startapp user_operation(用户操作相关)

  将这四个app移动到项目目录的apps包下:

  将xadmin的源码包和富文本DjangoUeditor的源码包放到extra_apps包下面,具体的安装方式在我的博客在线教育平台中有详细介绍,这里不再赘述:

  然后将四个app和xadmin、DjangoUeditor添加到settings.py的INSTALLED_APPS中:

 1 INSTALLED_APPS = [
 2     'django.contrib.auth',
 3     'django.contrib.contenttypes',
 4     'django.contrib.sessions',
 5     'django.contrib.messages',
 6     'django.contrib.staticfiles',
 7     'django.contrib.admin',
 8     'users',
 9     'goods',
10     'trade',
11     'user_operation',
12     'xadmin',
13     'crispy_forms',
14     'DjangoUeditor',
15     'rest_framework'
16 ]

  然后在settings.py中配置文件media文件上传的路径:

1 # 设置上传文件的路径
2 MEDIA_URL="/media/"
3 MEDIA_ROOT = os.path.join(BASE_DIR, "media")

  配置上传文件的url:

1 from django.views.static import serve
2 
3 from MxShop.settings import MEDIA_ROOT
4 
5 urlpatterns = [
6     path('media/<path:path>', serve, {'document_root': MEDIA_ROOT}),
7 ]

2.1 users的model设计

 1 from datetime import datetime
 2 
 3 from django.db import models
 4 from django.contrib.auth.models import AbstractUser
 5 
 6 # Create your models here.
 7 
 8 
 9 class UserProfile(AbstractUser):
10     """用户信息"""
11 
12     GENDER_CHOICES = (
13         ('male', ''),
14         ('female', '')
15     )
16 
17     name = models.CharField('姓名', max_length=30, null=True, blank=True)
18     birthday = models.DateField('出生年月', null=True, blank=True)
19     gender = models.CharField('性别', choices=GENDER_CHOICES, max_length=6, default='male')
20     mobile = models.CharField('电话', max_length=11)
21     email = models.EmailField('邮箱', max_length=100, null=True, blank=True)
22 
23     class Meta:
24         verbose_name = '用户信息'
25         verbose_name_plural = verbose_name
26 
27     def __str__(self):
28         return self.username
29 
30 
31 class VerifyCode(models.Model):
32     """短信验证码"""
33 
34     code = models.CharField('验证码', max_length=10)
35     mobile = models.CharField('电话', max_length=11)
36     add_time = models.DateTimeField('添加时间', default=datetime.now)
37 
38     class Meta:
39         verbose_name = '短信验证码'
40         verbose_name_plural = verbose_name
41 
42     def __str__(self):
43         return self.code

  UserProfile继承的是django的AbstractUser,需要在settings.py中进行配置:

1 AUTH_USER_MODEL = 'users.UserProfile'

 2.2 goods的model设计

   依照下面的页面进行商品的model设计:

 

  1 from datetime import datetime
  2 
  3 from django.db import models
  4 from DjangoUeditor.models import UEditorField
  5 
  6 
  7 # Create your models here.
  8 
  9 
 10 class GoodsCategory(models.Model):
 11     """商品分类"""
 12 
 13     CATEGORY_CHOICES = (
 14         (1, '一级类目'),
 15         (2, '二级类目'),
 16         (3, '三级类目'),
 17     )
 18 
 19     name = models.CharField('类别名', max_length=30, default='', help_text='类别名')
 20     code = models.CharField('类别code', max_length=30, default='', help_text='类别code')
 21     desc = models.TextField('类别描述', default='', help_text='类别描述')
 22     category_type = models.IntegerField('类目级别', choices=CATEGORY_CHOICES, help_text='类目级别')
 23     parent_category = models.ForeignKey('self', on_delete=models.CASCADE, null=True, blank=True, verbose_name='父类目级别',
 24                                         help_text='父类目级别', related_name='sub_cat')
 25     is_tab = models.BooleanField('是否导航', default=False, help_text='是否导航')
 26     add_time = models.DateTimeField('添加时间', default=datetime.now)
 27 
 28     class Meta:
 29         verbose_name = '商品类别'
 30         verbose_name_plural = verbose_name
 31 
 32     def __str__(self):
 33         return self.name
 34 
 35 
 36 class GoodsCategoryBrand(models.Model):
 37     """商品宣传商标"""
 38     category = models.ForeignKey(GoodsCategory, on_delete=models.CASCADE, related_name='brands', null=True, blank=True,
 39                                  verbose_name="商品类目")
 40     name = models.CharField("品牌名", default="", max_length=30, help_text="品牌名")
 41     desc = models.TextField("品牌描述", default="", max_length=200, help_text="品牌描述")
 42     image = models.ImageField(max_length=200, upload_to="brands/images/")
 43     add_time = models.DateTimeField("添加时间", default=datetime.now)
 44 
 45     class Meta:
 46         verbose_name = "宣传品牌"
 47         verbose_name_plural = verbose_name
 48         db_table = "goods_goodsbrand"
 49 
 50     def __str__(self):
 51         return self.name
 52 
 53 
 54 class Goods(models.Model):
 55     """商品"""
 56 
 57     category = models.ForeignKey(GoodsCategory, on_delete=models.CASCADE, verbose_name='商品类目')
 58     goods_sn = models.CharField('商品唯一货号', max_length=50, default='')
 59     name = models.CharField('商品名', max_length=100)
 60     click_nums = models.IntegerField('点击数', default=0)
 61     sold_num = models.IntegerField("商品销售量", default=0)
 62     fav_num = models.IntegerField("收藏数", default=0)
 63     goods_num = models.IntegerField("库存数", default=0)
 64     market_price = models.FloatField("市场价格", default=0)
 65     shop_price = models.FloatField("本店价格", default=0)
 66     goods_brief = models.CharField('商品简短描述', max_length=500)
 67     goods_desc = UEditorField(verbose_name="商品描述", imagePath="goods/images/", width=1000, height=300,
 68                               filePath="goods/files/", default='')
 69     ship_free = models.BooleanField('是否承担运费', default=True)
 70     goods_front_image = models.ImageField(upload_to='goods/images/', null=True, blank=True, verbose_name='首页封面图')
 71     is_new = models.BooleanField('是否新品', default=False)  # 首页新品展示
 72     is_hot = models.BooleanField('是否热销', default=False)  # 商品详情页的热卖商品
 73     add_time = models.DateTimeField('添加时间', default=datetime.now)
 74 
 75     class Meta:
 76         verbose_name = '商品信息'
 77         verbose_name_plural = verbose_name
 78 
 79     def __str__(self):
 80         return self.name
 81 
 82 
 83 class GoodsImage(models.Model):
 84     """商品轮播图"""
 85 
 86     goods = models.ForeignKey(Goods, on_delete=models.CASCADE, verbose_name='商品', related_name='images')
 87     image = models.ImageField(upload_to='goods/images/', verbose_name='图片', null=True, blank=True)
 88     add_time = models.DateTimeField('添加时间', default=datetime.now)
 89 
 90     class Meta:
 91         verbose_name = '商品轮播图'
 92         verbose_name_plural = verbose_name
 93 
 94     def __str__(self):
 95         return self.goods.name
 96 
 97 
 98 class Banner(models.Model):
 99     """首页轮播图"""
100 
101     goods = models.ForeignKey(Goods, on_delete=models.CASCADE, verbose_name='商品')
102     image = models.ImageField(upload_to='banners/images/', verbose_name='轮播图')
103     index = models.IntegerField('轮播顺序', default=0)
104     add_time = models.DateTimeField('添加时间', default=datetime.now)
105 
106     class Meta:
107         verbose_name = '首页轮播图'
108         verbose_name_plural = verbose_name
109 
110     def __str__(self):
111         return self.goods.name
112 
113 
114 class IndexAd(models.Model):
115     """商品广告"""
116     category = models.ForeignKey(GoodsCategory, on_delete=models.CASCADE, related_name='category', verbose_name="商品类目")
117     goods = models.ForeignKey(Goods, on_delete=models.CASCADE, related_name='goods')
118 
119     class Meta:
120         verbose_name = '首页广告'
121         verbose_name_plural = verbose_name
122 
123     def __str__(self):
124         return self.goods.name
125 
126 
127 class HotSearchWords(models.Model):
128     """热搜词"""
129 
130     keywords = models.CharField('热搜词', max_length=20, default='')
131     index = models.IntegerField('排序', default=0)
132     add_time = models.DateTimeField('添加时间', default=datetime.now)
133 
134     class Meta:
135         verbose_name = '热搜排行'
136         verbose_name_plural = verbose_name
137 
138     def __str__(self):
139         return self.keywords

2.3 trade的model设计

 1 from datetime import datetime
 2 
 3 from django.db import models
 4 from django.contrib.auth import get_user_model
 5 
 6 from goods.models import Goods
 7 
 8 
 9 # get_user_model会去setting中找AUTH_USER_MODEL
10 User = get_user_model()
11 
12 # Create your models here.
13 
14 
15 class ShoppingCart(models.Model):
16     """购物车"""
17 
18     user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name='用户')
19     goods = models.ForeignKey(Goods, on_delete=models.CASCADE, verbose_name='商品')
20     nums = models.IntegerField('购买数量', default=0)
21     add_time = models.DateTimeField('添加时间', default=datetime.now)
22 
23     class Meta:
24         verbose_name = '购物车'
25         verbose_name_plural = verbose_name
26         unique_together = ('user', 'goods')
27 
28     def __str__(self):
29         return self.goods.name
30 
31 
32 class OrderInfo(models.Model):
33     """订单信息"""
34 
35     ORDER_STATUS = (
36         ("TRADE_SUCCESS", "成功"),
37         ("TRADE_CLOSED", "超时关闭"),
38         ("WAIT_BUYER_PAY", "交易创建"),
39         ("TRADE_FINISHED", "交易结束"),
40         ("paying", "待支付"),
41     )
42     PAY_TYPE = (
43         ("alipay", "支付宝"),
44         ("wechat", "微信"),
45     )
46 
47     user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name='用户')
48     order_sn = models.CharField('订单编号', max_length=30, null=True, blank=True, unique=True)
49     nonce_str = models.CharField('随机加密串', max_length=50, null=True, blank=True, unique=True)  # 微信支付会用到
50     trade_no = models.CharField('交易号', max_length=100, null=True, blank=True, unique=True)  # 支付号交易号
51     pay_status = models.CharField('订单状态', choices=ORDER_STATUS, default='paying', max_length=30)
52     pay_type = models.CharField('支付类型', choices=PAY_TYPE, default='alipay', max_length=10)
53     post_script = models.CharField('订单留言', max_length=200)
54     order_mount = models.FloatField('订单金额', default=0.0)
55     pay_time = models.DateTimeField('支付时间', null=True, blank=True)
56     address = models.CharField('收货地址', max_length=100, default='')
57     singer_name = models.CharField('签收人', max_length=20, default='')
58     singer_mobile = models.CharField('签收电话', max_length=11)
59     add_time = models.DateTimeField('添加时间', default=datetime.now)
60 
61     class Meta:
62         verbose_name = '订单信息'
63         verbose_name_plural = verbose_name
64 
65     def __str__(self):
66         return str(self.order_sn)
67 
68 
69 class OrderGoods(models.Model):
70     """订单内商品"""
71 
72     order = models.ForeignKey(OrderInfo, on_delete=models.CASCADE, verbose_name='订单信息', related_name='goods')
73     goods = models.ForeignKey(Goods, on_delete=models.CASCADE, verbose_name='商品')
74     goods_num = models.IntegerField('商品数量', default=0)
75     add_time = models.DateTimeField('添加时间', default=datetime.now)
76 
77     class Meta:
78         verbose_name = '订单商品'
79         verbose_name_plural = verbose_name
80 
81     def __str__(self):
82         return str(self.order.order_sn)

2.4 user_operation的model设计

 1 from datetime import datetime
 2 
 3 from django.db import models
 4 from django.contrib.auth import get_user_model
 5 
 6 from goods.models import Goods
 7 
 8 User = get_user_model()
 9 
10 
11 # Create your models here.
12 
13 
14 class UserFav(models.Model):
15     """用户收藏"""
16 
17     user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name='用户')
18     goods = models.ForeignKey(Goods, on_delete=models.CASCADE, verbose_name='商品', help_text='商品id')
19     add_time = models.DateTimeField('添加时间', default=datetime.now)
20 
21     class Meta:
22         verbose_name = '用户收藏'
23         verbose_name_plural = verbose_name
24         unique_together = ('user', 'goods')
25 
26     def __str__(self):
27         return self.user.username
28 
29 
30 class UserAddress(models.Model):
31     """收货地址"""
32 
33     user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name='用户')
34     province = models.CharField("省份", max_length=100, default="")
35     city = models.CharField("城市", max_length=100, default="")
36     district = models.CharField("区域", max_length=100, default="")
37     address = models.CharField("详细地址", max_length=100, default="")
38     signer_name = models.CharField("签收人", max_length=100, default="")
39     signer_mobile = models.CharField("电话", max_length=11, default="")
40     add_time = models.DateTimeField("添加时间", default=datetime.now)
41 
42     class Meta:
43         verbose_name = "收货地址"
44         verbose_name_plural = verbose_name
45 
46     def __str__(self):
47         return self.address
48 
49 
50 class UserLeavingMessage(models.Model):
51     """用户留言"""
52 
53     MESSAGE_CHOICES = (
54         (1, "留言"),
55         (2, "投诉"),
56         (3, "询问"),
57         (4, "售后"),
58         (5, "求购")
59     )
60     user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name="用户")
61     message_type = models.IntegerField("留言类型", default=1, choices=MESSAGE_CHOICES,
62                                        help_text="留言类型: 1(留言),2(投诉),3(询问),4(售后),5(求购)")
63     subject = models.CharField("主题", max_length=100, default="")
64     message = models.TextField("留言内容", default="", help_text="留言内容")
65     file = models.FileField(upload_to="message/images/", verbose_name="上传的文件", help_text="上传的文件")
66     add_time = models.DateTimeField("添加时间", default=datetime.now)
67 
68     class Meta:
69         verbose_name = "用户留言"
70         verbose_name_plural = verbose_name
71 
72     def __str__(self):
73         return self.subject

 

  

posted @ 2018-11-25 10:41  Sweltering  阅读(586)  评论(2编辑  收藏  举报