• (项目)生鲜超市(二)


    三、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

      

  • 相关阅读:
    Notepad++如何对比文件 Notepad++对比两个文件代码方法
    如何识别图片中的文字
    如何用DOS命令查看占用某端口的程序及PID号
    java使用POI获取sheet、行数、列数
    程序中的.htaccess文件是做什么的
    阿里云服务器配置https(总结)
    legend3---19、要更多的从服务器端控制元素的显示和隐藏,而不要是页面端
    Laravel 中 Session 的使用问题(dd()导致laravel中session取值问题)
    legend3---lamp.sh常用操作
    阿里云服务器发送邮件:Connection could not be established with host smtp.qq.com [Connection timed out #110]
  • 原文地址:https://www.cnblogs.com/Sweltering/p/10014114.html
Copyright © 2020-2023  润新知