vue+django 生鮮項目 (二)


vue+django2.0.2-rest-framework 生鮮項目


一、項目初始化

 1)window下安裝虛擬環境

mkvirtualenv -p=C:\Python3.6\python.exe Mxshop

 

2)進虛擬環境安裝:

  • django
  • 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

 

 3)創建項目

  • 項目:MxShop
  • app:users

 

4)setting中數據庫選擇mysql:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'mxshop',        #數據庫名字
        'USER': 'root',          #賬號
        'PASSWORD': '***',    #密碼
        '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;"}
    }
}

 

Navicat連接數據庫並創建mxshop數據庫

 

此時,運行項目會出錯:需要安裝 MySQLclient:

 自從開發全面轉向python3之后,由於mysqldb不支持python3,所以django連接mysql就不能再使用mysqldb了。故而選擇了mysqlclient,然而兩者之間並沒有太大的使用上的差異

 

打開終端,到虛擬環境Mxshop中安裝MySQLclient

首先到 https://www.lfd.uci.edu/~gohlke/pythonlibs/, 找到 mysqlclient-1.3.13-cp36-cp36m-win_amd64.whl (最新版本)下載下來,

再在終端虛擬環境安裝:

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

  

安裝成功再運行項目即可以了

 

4)項目目錄結構搭建:

 新建兩個python package (app):

  • extra_apps   (擴展的源碼包)
  • apps              (放所有app)

 新建兩個文件夾:

  • media       (保存圖片)
  • db_tools   (數據庫配置文件等相關)

 把extra_apps和apps標記為sources root,

 然后settings中也要加路徑,后面import時就只需要import users ,不用再from apps import users了 (參考下項目目錄圖)

#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'))

 

 現在項目目錄情況如下:

 


 

二、users models設計  

1)創建三個app ,放進apps包里(users app已經在項目創建的時候便創建了)

  • goods        商品
  • trade          交易
  • user_operation       用戶操作
python manage.py startapp goods

python manage.py startapp trade

python manage.py startapp user_operation

 注意:model設計時,關於add_time 、 update_time字段的添加,應按如下類型添加:

class UserProfile(AbstractUser):
    """
    用戶信息
    """
    ……
    add_time = models.DateTimeField(auto_now_add=True)    # 創建時間應使用:auto_now_add=True
    update_time = models.DateTimeField(default=datetime.now)    # 需要默認更新時間時,應采用defaultt=datetime.now

# 注意點:
#
1. 使用auto_now、auto_now_add類型,不能通過ORM手動修改該字段(除使用update方法不更新時間外,每次修改/添加數據時,都會自動化更新修改/添加時間(不需手段填寫));使用default=datetime.now、default=datetime.now() ,可通過ORM手段修改該字段(后端添加/修改數據時,需要我們手動填寫添加(有默認值)時間/修改時間) # 2. 使用User.objects.update方法時,設置的default=datetime.now和auto_now=True都不會生效,而default=datetime.now能通過ORM手段修改,因此update_time參數類型要設置成default=datetime.now
# 也就是說,add_time使用auto_now_add=True可以避免人為修改數據;update_time使用default=datetime.now可以避免使用update方法不更新時間的bug(但每次更新需手動填寫update_time字段,如不填寫會報錯)

 

 

2.1)users/models.py 設計表信息

# 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", 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.name


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
UserProfile繼承於Django自帶AbstractUser,使用UserProfile用戶,需要在setting中配置:
#settings.py

#重載系統的用戶,讓UserProfile生效
AUTH_USER_MODEL = 'users.UserProfile'
"""
users存於apps包中,正常正確引用UserProfile是:apps.users.UserProfile,
但由於setting.py中配置了:sys.path.insert(0,os.path.join(BASE_DIR, 'apps')),
故可以直接通過 users.UserProfile 找到 UserProfile
"""

 


 

 2.2)goods/models表設計

 1)導入DjangoUeditor 到extra_apps目錄下面 ,在models中import進去

 2)將四個app(goods、trade、users、user_operation)均注冊到setting中的INSTALLED_APPS:

INSTALLED_APPS = [
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'apps.users.apps.UsersConfig',
    'goods',
    'trade',
    'user_operation',
    'users'
]

 3)設置media的保存路徑:

# setting.py

MEDIA_URL = "/media/"

MEDIA_ROOT = os.path.join(BASE_DIR, "media")

 

 goods/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,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

 

 

goods/models下商品分類下的宣傳圖標表:

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, verbose_name="品牌名", help_text="品牌名")
    desc = models.TextField(default="", max_length=200, verbose_name="品牌描述", help_text="品牌描述")
    image = models.ImageField(max_length=200, upload_to="brands/")
    add_time = models.DateTimeField(default=datetime.now, verbose_name="添加時間")

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

    def __str__(self):
        return self.name

 

goods/models下商品表 ,及商品輪播:

class Goods(models.Model):
    """
    商品
    """
    category = models.ForeignKey(GoodsCategory, on_delete=models.CASCADE, verbose_name="商品類目")
    goods_sn = models.CharField(max_length=50, default="", verbose_name="商品唯一貨號")
    name = models.CharField(max_length=100, verbose_name="商品名")
    click_num = models.IntegerField(default=0, verbose_name="點擊數")
    sold_num = models.IntegerField(default=0, verbose_name="商品銷售量")
    fav_num = models.IntegerField(default=0, verbose_name="收藏數")
    goods_num = models.IntegerField(default=0, verbose_name="庫存數")
    market_price = models.FloatField(default=0, verbose_name="市場價格")
    shop_price = models.FloatField(default=0, verbose_name="本店價格")
    goods_brief = models.TextField(max_length=500, verbose_name="商品簡短描述")
    goods_desc = UEditorField(verbose_name="內容", imagePath="goods/images/", width=1000, height=300,
                              filePath="goods/files/", default='')
    ship_free = models.BooleanField(default=True, verbose_name="是否承擔運費")
    # 首頁中展示的商品封面圖
    goods_front_image = models.ImageField(upload_to="goods/images/", null=True, blank=True, verbose_name="封面圖")
    # 首頁中新品展示
    is_new = models.BooleanField(default=False, verbose_name="是否新品")
    # 商品詳情頁的熱賣商品,自行設置
    is_hot = models.BooleanField(default=False, verbose_name="是否熱銷")
    add_time = models.DateTimeField(default=datetime.now, verbose_name="添加時間")

    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, verbose_name="添加時間")

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

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

 

  

 goods/models下首頁商品輪播:

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, verbose_name="輪播順序")
    add_time = models.DateTimeField(default=datetime.now, verbose_name="添加時間")

    class Meta:
        verbose_name = '首頁輪播'
        verbose_name_plural = verbose_name

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

 

  

 


 

 

三、trade models設計

 trade/models.py

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

# 傳統做法,從user.models中引入
#from users.models import UserProfile
# 但是當第三方模塊根本不知道你的user model在哪里如何導入呢
from django.contrib.auth import get_user_model
# 這個方法會去setting中找AUTH_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, verbose_name="購買數量")

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

    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", "取消/超時關閉"),
        ("paying", "待支付"),
    )
    # PAY_TYPE = (
    #     ("alipay", "支付寶"),
    #     ("wechat", "微信"),
    # )

    user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name="用戶")
    # unique訂單號唯一
    order_sn = models.CharField(max_length=30, null=True, blank=True, unique=True, verbose_name="訂單編號")
    # 微信支付可能會用到
    # nonce_str = models.CharField(max_length=50, null=True, blank=True, unique=True, verbose_name="隨機加密串")
    # 支付寶支付時的交易號與本系統進行關聯
    trade_no = models.CharField(max_length=100, unique=True, null=True, blank=True, verbose_name="交易號")
    # 以防用戶支付到一半不支付了
    pay_status = models.CharField(choices=ORDER_STATUS, default="paying", max_length=30, verbose_name="訂單狀態")
    # 訂單的支付類型
    # pay_type = models.CharField(choices=PAY_TYPE, default="alipay", max_length=10, verbose_name="支付類型")
    post_script = models.CharField(max_length=200, verbose_name="訂單留言")
    order_mount = models.FloatField(default=0.0, verbose_name="訂單金額")
    pay_time = models.DateTimeField(null=True, blank=True, verbose_name="支付時間")

    # 用戶的基本信息
    address = models.CharField(max_length=100, default="", verbose_name="收貨地址")
    signer_name = models.CharField(max_length=20, default="", verbose_name="簽收人")
    singer_mobile = models.CharField(max_length=11, verbose_name="聯系電話")

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

    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, verbose_name="商品數量")

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

    class Meta:
        verbose_name = "訂單商品"
        verbose_name_plural = verbose_name

    def __str__(self):
        return str(self.order.order_sn)

 

 


四、用戶操作的user_operation表設計

 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
# Create your models here.

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, verbose_name="添加時間")

    class Meta:
        verbose_name = '用戶收藏'
        verbose_name_plural = verbose_name

        # 多個字段作為一個聯合唯一索引
        unique_together = ("user", "goods")

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


class UserAddress(models.Model):
    """
    用戶收貨地址
    """
    user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name="用戶" )
    # province = models.CharField(max_length=100, default="", verbose_name="省份")
    # city = models.CharField(max_length=100, default="", verbose_name="城市")
    district = models.CharField(max_length=100, default="", verbose_name="區域")
    address = models.CharField(max_length=100, default="", verbose_name="詳細地址")
    signer_name = models.CharField(max_length=100, default="", verbose_name="簽收人")
    signer_mobile = models.CharField(max_length=11, default="", verbose_name="電話")
    add_time = models.DateTimeField(default=datetime.now, verbose_name="添加時間")

    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="留言類型: 1(留言),2(投訴),3(詢問),4(售后),5(求購)")
    subject = models.CharField(max_length=100, default="", verbose_name="主題")
    message = models.TextField(default="", verbose_name="留言內容", help_text="留言內容")
    file = models.FileField(upload_to="message/images/", verbose_name="上傳的文件", help_text="上傳的文件")
    add_time = models.DateTimeField(default=datetime.now, verbose_name="添加時間")

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

    def __str__(self):
        return self.subject

 


 

五、migrations原理及表生成

 1)點擊Tools → Run manage.py Task.. → 進入manage.py調試

 

2)在manage.py調試界面,輸入:makemigrations ,生成我們每次數據庫變動的py腳本

   注:makemigrations 只是用來生成這個的。真正的生成數據表必須運行migrate(作用:執行py腳本去數據庫生成數據表)

 

3)輸入:migrate ,執行py腳本去數據庫生成數據表  (migrate appname :只生成單個app的數據表)

生成表數據,可以在Navicat中查看。

注:盡量不要Navicat和migrate混用。


 

 

 

 


免責聲明!

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



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