1. 程式人生 > >(專案)生鮮超市(二)

(專案)生鮮超市(二)

三、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     'users.apps.UsersConfig',
 8     'users',
 9     'goods',
10     'trade',
11     'user_operation',
12     'rest_framework',
13     'xadmin',
14     'crispy_forms',
15     'DjangoUeditor'
16 ]

  然後在settings.py中配置檔案media上傳的路徑:

1 MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

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