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


目錄

生鮮超市(一)    生鮮超市(二)    生鮮超市(三)   

生鮮超市(四)    生鮮超市(五)    生鮮超市(六)   

生鮮超市(七)    生鮮超市(八)    生鮮超市(九)   

生鮮超市(十)    生鮮超市(十一)    生鮮超市(十二)    生鮮超市(十三)   

代碼下載

github

教程

學習自慕課網-前端vue結合后端DjangoFramework的在線生鮮超市 

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

# users/models.py
__author__ = 'derek'


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


class UserProfile(AbstractUser):
    """
    用戶信息
    """
    GENDER_CHOICES = (
        ("male", u""),
        ("female", u"")
    )
    #用戶用手機注冊,所以姓名,生日和郵箱可以為空
    name = models.CharField("姓名",max_length=30, null=True, blank=True)
    birthday = models.DateField("出生年月",null=True, blank=True)
    gender = models.CharField("性別",max_length=6, choices=GENDER_CHOICES, default="female")
    mobile = models.CharField("電話",max_length=11)
    email = models.EmailField("郵箱",max_length=100, 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 設計

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,help_text="類目級別")
    # 設置models有一個指向自己的外鍵
    parent_category = models.ForeignKey("self", on_delete=models.CASCADE, null=True, blank=True, verbose_name="父類目級別", help_text="父目錄",
                                        related_name="sub_cat")
    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設計

class Goods(models.Model):
    """
    商品
    """
    category = models.ForeignKey(GoodsCategory, on_delete=models.CASCADE, verbose_name="商品類目")
    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=u"內容", 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, verbose_name="封面圖")
    # 首頁中新品展示
    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, on_delete=models.CASCADE, verbose_name="商品", related_name="images")
    image = models.ImageField(upload_to="", verbose_name="圖片", null=True, blank=True)
    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, on_delete=models.CASCADE, verbose_name="商品")
    image = models.ImageField(upload_to='banner', verbose_name="輪播圖片")
    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

 

 

(5)商品廣告和熱搜model

class HotSearchWords(models.Model):
    """
    搜索欄下方熱搜詞
    """
    keywords = models.CharField("熱搜詞",default="", max_length=20)
    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.keywords
#goods/models.py
__author__ = 'derek'


from datetime import datetime
from django.db import models
from DjangoUeditor.models import UEditorField


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,help_text="類目級別")
    # 設置models有一個指向自己的外鍵
    parent_category = models.ForeignKey("self", on_delete=models.CASCADE, null=True, blank=True, verbose_name="父類目級別", help_text="父目錄",
                                        related_name="sub_cat")
    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


class GoodsCategoryBrand(models.Model):
    """
    某一大類下的宣傳商標
    """
    category = models.ForeignKey(GoodsCategory, on_delete=models.CASCADE, related_name='brands', null=True, blank=True, verbose_name="商品類目")
    name = models.CharField("品牌名",default="", max_length=30,help_text="品牌名")
    desc = models.TextField("品牌描述",default="", max_length=200,help_text="品牌描述")
    image = models.ImageField(max_length=200, upload_to="brands/")
    add_time = models.DateTimeField("添加時間",default=datetime.now)

    class Meta:
        verbose_name = "宣傳品牌"
        verbose_name_plural = verbose_name
        db_table = "goods_goodsbrand"

    def __str__(self):
        return self.name


class Goods(models.Model):
    """
    商品
    """
    category = models.ForeignKey(GoodsCategory, on_delete=models.CASCADE, verbose_name="商品類目")
    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=u"內容", 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, verbose_name="封面圖")
    # 首頁中新品展示
    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, on_delete=models.CASCADE, verbose_name="商品", related_name="images")
    image = models.ImageField(upload_to="", verbose_name="圖片", null=True, blank=True)
    add_time = models.DateTimeField("添加時間", default=datetime.now)

    class Meta:
        verbose_name = '商品輪播'
        verbose_name_plural = verbose_name

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


class Banner(models.Model):
    """
    首頁輪播的商品
    """
    goods = models.ForeignKey(Goods, on_delete=models.CASCADE, verbose_name="商品")
    image = models.ImageField(upload_to='banner', verbose_name="輪播圖片")
    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


class IndexAd(models.Model):
    """
    商品廣告
    """
    category = models.ForeignKey(GoodsCategory, on_delete=models.CASCADE, related_name='category',verbose_name="商品類目")
    goods =models.ForeignKey(Goods, on_delete=models.CASCADE, related_name='goods')

    class Meta:
        verbose_name = '首頁廣告'
        verbose_name_plural = verbose_name

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


class HotSearchWords(models.Model):
    """
    搜索欄下方熱搜詞
    """
    keywords = models.CharField("熱搜詞",default="", max_length=20)
    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.keywords
goods/models.py

 

3.4.trade交易的model設計

trade/models.py

# trade/models.py
__author__ = 'derek'

from datetime import datetime
from django.db import models

from goods.models import Goods

# get_user_model方法會去setting中找AUTH_USER_MODEL
from django.contrib.auth import get_user_model
User = get_user_model()


# Create your models here.
class ShoppingCart(models.Model):
    """
    購物車
    """
    user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name="用戶")
    goods = models.ForeignKey(Goods, on_delete=models.CASCADE, verbose_name="商品")
    nums = models.IntegerField("購買數量",default=0)

    add_time = models.DateTimeField(default=datetime.now, verbose_name="添加時間")

    class Meta:
        verbose_name = '購物車喵'
        verbose_name_plural = verbose_name
        unique_together = ("user", "goods")

    def __str__(self):
        return "%s(%d)".format(self.goods.name, self.nums)


class OrderInfo(models.Model):
    """
    訂單信息
    """
    ORDER_STATUS = (
        ("TRADE_SUCCESS", "成功"),
        ("TRADE_CLOSED", "超時關閉"),
        ("WAIT_BUYER_PAY", "交易創建"),
        ("TRADE_FINISHED", "交易結束"),
        ("paying", "待支付"),
    )
    PAY_TYPE = (
        ("alipay", "支付寶"),
        ("wechat", "微信"),
    )

    user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name="用戶")
    #訂單號唯一
    order_sn = models.CharField("訂單編號",max_length=30, null=True, blank=True, unique=True)
    # 微信支付會用到
    nonce_str = models.CharField("隨機加密串",max_length=50, null=True, blank=True, 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_type = models.CharField("支付類型",choices=PAY_TYPE, default="alipay", max_length=10)
    post_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="")
    signer_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, on_delete=models.CASCADE, verbose_name="訂單信息", related_name="goods")
    # 兩個外鍵形成一張關聯表
    goods = models.ForeignKey(Goods, on_delete=models.CASCADE, verbose_name="商品")
    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
__author__ = 'derek'


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

from django.contrib.auth import get_user_model
User = get_user_model()


class UserFav(models.Model):
    """
    用戶收藏操作
    """
    user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name="用戶")
    goods = models.ForeignKey(Goods, on_delete=models.CASCADE, verbose_name="商品", help_text="商品id")
    add_time = models.DateTimeField("添加時間",default=datetime.now)

    class Meta:
        verbose_name = '用戶收藏'
        verbose_name_plural = verbose_name
        unique_together = ("user", "goods")

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


class UserAddress(models.Model):
    """
    用戶收貨地址
    """
    user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name="用戶" )
    province = models.CharField("省份",max_length=100, default="")
    city = models.CharField("城市",max_length=100, default="")
    district = 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 UserLeavingMessage(models.Model):
    """
    用戶留言
    """
    MESSAGE_CHOICES = (
        (1, "留言"),
        (2, "投訴"),
        (3, "詢問"),
        (4, "售后"),
        (5, "求購")
    )
    user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name="用戶")
    message_type = models.IntegerField(default=1, choices=MESSAGE_CHOICES, verbose_name="留言類型",
                                      help_text=u"留言類型: 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/", verbose_name="上傳的文件", help_text="上傳的文件")
    add_time = models.DateTimeField("添加時間",default=datetime.now)

    class Meta:
        verbose_name = "用戶留言"
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.subject

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM