Django REST framework+Vue 打造生鮮電商項目(筆記一)


  首先,這系列隨筆是我個人在學習Bobby老師的Django實戰項目中,記錄的覺得對自己來說比較重要的知識點,不是完完整整的項目步驟過程....如果有小伙伴想找完整的教程,可以看看這個(https://www.cnblogs.com/derek1184405959/p/8768059.html)

一、配置Mysql

setting.py中的設置

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'mxshop',
        'USER': 'root',
        'PASSWORD': 'root',
        'HOST': '127.0.0.1',
        "OPTIONS":{"init_command":"SET storage_engine=INNODB;"} #這個是為了后面第三方登陸而指定使用的mysql數據庫的引擎,否則第三方登陸的makemigrations將會失敗。
     # 注意,如果你的MYSQL版本>=5.6,改成
"OPTIONS":{"init_command":"SET default_storage_engine=INNODB;"} } }

安裝驅動Mysqlclient   (否則不能使用Mysql)

下載地址為“https://www.lfd.uci.edu/~gohlke/pythonlibs/”,找到你電腦對應的版本

二、項目目錄結構搭建

 1、創建包appsextra_apps

  這點值得學習,通過創建兩個包可以更加方便的管理我們自定義的app和引入的第三方app。

#setting.py

import os
import sys

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
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'))

 

2、創建文件夾media(保存圖片等)db_tools(放腳本用的)

 

#setting.py

# 設置上傳文件的路徑
MEDIA_URL="/media/"
MEDIA_ROOT=os.path.join(BASE_DIR,"media")
# urls.py

from django.urls import path
from django.views.static import serve
from MxShop.settings import MEDIA_ROOT urlpatterns = [ # 文件 path('media/<path:path>', serve, {'document_root': MEDIA_ROOT}), ]

三、關於Users app的設計

其實Django內部已經自動提供給我們有關user表的設計了,我們可以通過繼承它,在原基礎上進行修改,添加我們自己自定義的屬性,這樣既避免是重復造輪子,同時官方提供給我們的相對我們自己寫的安全性上更加完善。

# users app 下的models
# 引入AbstractUser

from django.contrib.auth.models import AbstractUser

class UserProfile(AbstractUser):
    """
    用戶
    """
    name = models.CharField(max_length=30, null=True, blank=True, verbose_name="姓名")
    birthday = models.DateField(null=True, blank=True, verbose_name="出生年月")
    gender = models.CharField(max_length=6, choices=(("male", ""), ("female", "")), default="female", verbose_name="性別")
    mobile = models.CharField(max_length=11, verbose_name="電話")
    email = models.EmailField(max_length=100, null=True, blank=True, verbose_name="郵箱")

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

    def __str__(self):
        return self.username # 這里用的username是AbstractUser里面的,如果用我們自己定義的name的話,因為我們設定該字段是可以為空的,這樣后面在用drf等陸時會出錯,因為在我們進行調式時候,只創建了超級用戶,普通用戶還沒有創建。如果用的是self.username,它會自動獲取我們超級用戶的賬號。
# setting.py

AUTH_USER_MODEL = 'users.UserProfile' #在setting中把替換系統用戶,改為我們自定義的

四、商品類別的models設計

這里有個知識點,就是如何通過一個model設計出從屬關系,讓我們可以靈活的自定義一個類的級別。因為在這個項目中商品有三個等級划分,如果創建三張表來表示每一級的話,未免太不靈活,一旦增加或者刪除將很麻煩。解決辦法是models.ForeignKey("self")指向自己。

五、如何在一個app里繼承另一個app的model下的類

 例如項目中關於購物的app里,我們需要繼承用戶User,這樣才能和購物的行為綁定起來。一般的做法是直接from users.model import User導入的。這里再介紹另一種方法,就是當我們在開發第三方時,是不知道別人定好的用戶類具體放在哪里,叫什么名字,這時還用以前的做法就沒有用處了。這時我們可以用:

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

六、migrations原理

注意,因為我們自定義了UserProfile,因此在數據庫生成的時候也就是這張表,原本會自動生成的auth_user就不會出現了,這時如果使用admin是會報錯的,因為admin默認使用auth_user。
在進行第二次或者更多次數據遷移的時候,migrate是如何確定把migrations文件夾剛生成的新的py文件更新到數據庫的呢?是因為在django_migrations這張表里詳細記錄了之前migrations已運行的的py文件。因此在migrate之前會先去這張表里查詢哪些是已經運行過的了。

七、自動導入商品數據

#如何初始化數據,將圖片、文字導入到數據庫里
#知識點:獨立使用django的model
我們目前創建好了各種數據表,但數據庫中現在什么數據都還沒有,如果想要手動往數據庫中添加數據,工作量未免太大。這時我們寫個腳本導入數據。

1、db_tools下新建文件夾data,然后把前端的json文件(category_data和product_data)拷貝到里面

2、把brands和goods圖片拷貝到media目錄下

db_tools下新建文件 import_category_data.py

代碼如下:(代碼來自https://www.cnblogs.com/derek1184405959/p/8747961.html)

# db_tools/data/import_category_data.py

#獨立使用django的model
import sys
import os

#獲取當前文件的路徑(運行腳本)
pwd = os.path.dirname(os.path.realpath(__file__))
#獲取項目的跟目錄
sys.path.append(pwd+"../")
#要想單獨使用django的model,必須指定一個環境變量,會去settings配置找
#參照manage.py里面就知道為什么這樣設置了
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "MxShop.settings")

import django
django.setup()

from goods.models import GoodsCategory

from db_tools.data.category_data import row_data

#一級類
for lev1_cat in row_data:
    lev1_intance = GoodsCategory()
    lev1_intance.code = lev1_cat["code"]
    lev1_intance.name = lev1_cat["name"]
    lev1_intance.category_type = 1
    #保存到數據庫
    lev1_intance.save()
#二級類
    for lev2_cat in lev1_cat["sub_categorys"]:
        lev2_intance = GoodsCategory()
        lev2_intance.code = lev2_cat["code"]
        lev2_intance.name = lev2_cat["name"]
        lev2_intance.category_type = 2
        lev2_intance.parent_category = lev1_intance
        lev2_intance.save()
#三級類
        for lev3_cat in lev2_cat["sub_categorys"]:
            lev3_intance = GoodsCategory()
            lev3_intance.code = lev3_cat["code"]
            lev3_intance.name = lev3_cat["name"]
            lev3_intance.category_type = 3
            lev3_intance.parent_category = lev2_intance
            lev3_intance.save()

然后運行腳本 import_category_data.py  數據就可以保存到數據庫了

同樣,導入商品。在data目錄下新建import_goods_data.py

import sys
import os

pwd = os.path.dirname(os.path.realpath(__file__))
sys.path.append(pwd+"../")
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "MxShop.settings")

import django
django.setup()

from goods.models import Goods, GoodsCategory, GoodsImage

from db_tools.data.product_data import row_data

for goods_detail in row_data:
    goods = Goods()
    goods.name = goods_detail["name"]
    #前端中是“¥232”,數據庫中是float類型,所以要替換掉 (這里好像是作者在爬取數據時,拿到的數據格式和我們自己在model中設定的不一樣,所以修改一下)
    goods.market_price = float(int(goods_detail["market_price"].replace("", "").replace("", "")))
    goods.shop_price = float(int(goods_detail["sale_price"].replace("", "").replace("", "")))
    goods.goods_brief = goods_detail["desc"] if goods_detail["desc"] is not None else ""
    goods.goods_desc = goods_detail["goods_desc"] if goods_detail["goods_desc"] is not None else ""
    # 取第一張作為封面圖
    goods.goods_front_image = goods_detail["images"][0] if goods_detail["images"] else ""
    #取最后一個
    category_name = goods_detail["categorys"][-1]
    # 取出當前子類對應的GoodsCategory對象,filter沒有匹配的會返回空數組,不會拋異常。
    category = GoodsCategory.objects.filter(name=category_name)
    if category:
        goods.category = category[0]
    goods.save()

    for goods_image in goods_detail["images"]:
        goods_image_instance = GoodsImage()
        goods_image_instance.image = goods_image
        goods_image_instance.goods = goods
        goods_image_instance.save()

然后運行,把商品生產到數據庫中

 


免責聲明!

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



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