01 搭建專案配置環境和建立表
先建立一個Django專案
在shop下的__init__中匯入mysql
1 2 |
import pymysql
pymysql.install_as_MySQLdb()
|
cmd命令框建立資料庫
1 |
create database shop;
|
配置mysql 讀寫分離配置
'default': { # 預設的配置的是主資料庫 'ENGINE': 'django.db.backends.mysql','HOST': '127.0.0.1', 'PORT': 3306, 'USER': 'root', 'PASSWORD': "123456", 'NAME': "shop" }, # 配置的是從資料庫 'slave': { 'ENGINE': 'django.db.backends.mysql', 'HOST': '127.0.0.1', 'PORT': 3306, 'USER': 'root', 'PASSWORD': "mysql", 'NAME': "shop" },
在專案的目錄下新建utils/db_router.py檔案:
在 utils/db_router.py中定義一個數據庫路由,實現一個策略來控制特定模型的訪問性
資料庫路由
資料庫路由是一個類,它提供4個方法:
資料庫路由是一個類,它提供4個方法:
- db_for_read(model, **hints)
-
建議model型別的物件的讀操作應該使用的資料庫。
如果一個數據庫操作能夠提供其它額外的資訊可以幫助選擇一個數據庫,它將在hints字典中提供。合法的hints 的詳細資訊在下文給出。
如果沒有建議,則返回None。
- db_for_write(model, **hints)
-
建議Model 型別的物件的寫操作應該使用的資料庫。
如果一個數據庫操作能夠提供其它額外的資訊可以幫助選擇一個數據庫,它將在hints字典中提供。 合法的hints 的詳細資訊在下文給出。
如果沒有建議,則返回None。
- allow_relation(obj1, obj2, **hints)
-
如果obj1 和obj2 之間應該允許關聯則返回True,如果應該防止關聯則返回False,如果路由無法判斷則返回None。這是純粹的驗證操作,外來鍵和多對多操作使用它來決定兩個物件之間是否應該允許一個關聯。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
class MasterSlaveDBRouter( object ):
"""讀寫分離路由"""
def db_for_read( self , model, * * hints):
"""讀資料庫"""
return "slave"
def db_for_write( self , model, * * hints):
"""寫資料庫"""
return "default"
def allow_relation( self , obj1, obj2, * * hints):
"""是否執行關聯操作"""
return True
|
在settings.py配置中宣告讀寫分離路由所在的真正路徑:
1 |
DATABASE_ROUTERS = [ "utils.db_router.MasterSlaveDBRouter" ]
|
為類補充欄位
在utils目錄中建立一個models.py用來'''為模型類補充欄位'''的抽象類, 宣告一個類是抽象類,不遷移,專門給別的表繼承用的
在元選項中增添屬性 abstract=True
from django.db import models class BaseModel(models.Model): '''為模型類補充欄位''' create_time=models.DateTimeField(auto_now_add=True,verbose_name='建立時間') update_time=models.DateTimeField(auto_now=True,verbose_name='更新時間') class Meta: abstract=True # 宣告是抽象模型類,不遷移,專門給別的表繼承用的
建立應用
在專案隊根目錄下建立一個app目錄用來儲存所有的應用:(在app這個資料夾內,摁著Shift鍵再摁滑鼠右鍵,開啟命令框)
輸入命令,分別建立 應用 cart goods orders users
在goods應用中的models中定義如下和商品相關的類:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
from django.db import models
from utils.models import BaseModel
from tinymce.models import HTMLField
# Create your models here.
class GoodsCategory(BaseModel):
"""商品類別表"""
name = models.CharField(max_length = 20 , verbose_name = "名稱" )
logo = models.CharField(max_length = 100 , verbose_name = "標識" )
image = models.ImageField(upload_to = "category" , verbose_name = "圖片" )
class Meta:
db_table = "df_goods_category"
verbose_name = "商品類別" # admin站點使用
verbose_name_plural = verbose_name
def __str__( self ):
return self .name
class Goods(BaseModel):
"""商品SPU表"""
name = models.CharField(max_length = 100 , verbose_name = "名稱" )
# desc = HTMLField(verbose_name="詳細介紹", default="", blank=True) 富文字編輯器
class Meta:
db_table = "df_goods"
verbose_name = "商品"
verbose_name_plural = verbose_name
def __str__( self ):
return self .name
class GoodsSKU(BaseModel):
"""商品SKU表"""
category = models.ForeignKey(GoodsCategory, verbose_name = "類別" )
goods = models.ForeignKey(Goods, verbose_name = "商品" )
name = models.CharField(max_length = 100 , verbose_name = "名稱" )
title = models.CharField(max_length = 200 , verbose_name = "簡介" )
unit = models.CharField(max_length = 10 , verbose_name = "銷售單位" )
price = models.DecimalField(max_digits = 10 , decimal_places = 2 , verbose_name = "價格" )
stock = models.IntegerField(default = 0 , verbose_name = "庫存" )
sales = models.IntegerField(default = 0 , verbose_name = "銷量" )
default_image = models.ImageField(upload_to = "goods" , verbose_name = "圖片" )
status = models.BooleanField(default = True , verbose_name = "是否上線" )
class Meta:
db_table = "df_goods_sku"
verbose_name = "商品SKU"
verbose_name_plural = verbose_name
def __str__( self ):
return self .name
class GoodsImage(BaseModel):
"""商品圖片"""
sku = models.ForeignKey(GoodsSKU, verbose_name = "商品SKU" )
image = models.ImageField(upload_to = "goods" , verbose_name = "圖片" )
class Meta:
db_table = "df_goods_image"
verbose_name = "商品圖片"
verbose_name_plural = verbose_name
def __str__( self ):
return str ( self .sku)
class IndexGoodsBanner(BaseModel):
"""主頁輪播商品展示"""
sku = models.ForeignKey(GoodsSKU, verbose_name = "商品SKU" )
image = models.ImageField(upload_to = "banner" , verbose_name = "圖片" )
index = models.SmallIntegerField(default = 0 , verbose_name = "順序" )
class Meta:
db_table = "df_index_goods"
verbose_name = "主頁輪播商品"
verbose_name_plural = verbose_name
def __str__( self ):
return str ( self .sku)
class IndexCategoryGoodsBanner(BaseModel):
"""主頁分類商品展示"""
DISPLAY_TYPE_CHOICES = (
( 0 , "標題" ),
( 1 , "圖片" )
)
category = models.ForeignKey(GoodsCategory, verbose_name = "商品類別" )
sku = models.ForeignKey(GoodsSKU, verbose_name = "商品SKU" )
display_type = models.SmallIntegerField(choices = DISPLAY_TYPE_CHOICES, verbose_name = "展示型別" )
index = models.SmallIntegerField(default = 0 , verbose_name = "順序" )
class Meta:
db_table = "df_index_category_goods"
verbose_name = "主頁分類展示商品"
verbose_name_plural = verbose_name
def __str__( self ):
return str ( self .sku)
class IndexPromotionBanner(BaseModel):
"""主頁促銷活動展示"""
name = models.CharField(max_length = 50 , verbose_name = "活動名稱" )
url = models.URLField(verbose_name = "活動連線" )
image = models.ImageField(upload_to = "banner" , verbose_name = "圖片" )
index = models.SmallIntegerField(default = 0 , verbose_name = "順序" )
class Meta:
db_table = "df_index_promotion"
verbose_name = "主頁促銷活動"
verbose_name_plural = verbose_name
def __str__( self ):
return self .name
|
在orders應用中的models中定義如下和訂單相關的類:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
from django.db import models
from utils.models import BaseModel
from app.users.models import User, Address
from app.goods.models import GoodsSKU
# Create your models here.
class OrderInfo(BaseModel):
"""訂單資訊"""
PAY_METHOD_CHOICES = (
( 1 , "貨到付款" ),
( 2 , "支付寶" ),
)
ORDER_STATUS_CHOICES = (
( 1 , "待支付" ),
( 2 , "待發貨" ),
( 3 , "待收貨" ),
( 4 , "待評價" ),
( 5 , "已完成" ),
)
order_id = models.CharField(max_length = 64 , primary_key = True , verbose_name = "訂單號" )
user = models.ForeignKey(User, verbose_name = "下單使用者" )
address = models.ForeignKey(Address, verbose_name = "收穫地址" )
total_count = models.IntegerField(default = 1 , verbose_name = "商品總數" )
total_amount = models.DecimalField(max_digits = 10 , decimal_places = 2 , verbose_name = "商品總金額" )
trans_cost = models.DecimalField(max_digits = 10 , decimal_places = 2 , verbose_name = "運費" )
pay_method = models.SmallIntegerField(choices = PAY_METHOD_CHOICES, default = 1 , verbose_name = "支付方式" )
status = models.SmallIntegerField(choices = ORDER_STATUS_CHOICES, default = 1 , verbose_name = "訂單狀態" )
trade_id = models.CharField(max_length = 100 , unique = True , null = True , blank = True , verbose_name = "支付編號" )
class Meta:
db_table = "df_order_info"
class OrderGoods(BaseModel):
"""訂單商品"""
order = models.ForeignKey(OrderInfo, verbose_name = "訂單" )
sku = models.ForeignKey(GoodsSKU, verbose_name = "訂單商品" )
count = models.IntegerField(default = 1 , verbose_name = "數量" )
price = models.DecimalField(max_digits = 10 , decimal_places = 2 , verbose_name = "單價" )
comment = models.TextField(default = " ", verbose_name=" 評價資訊")
class Meta:
db_table = "df_order_goods"
|
在users應用中的models中定義如下和使用者相關的類:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
from django.db import models
from django.contrib.auth.models import AbstractUser
from utils.models import BaseModel
from django.conf import settings
from app.goods.models import GoodsSKU
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
# Create your models here.
# django預設的認證機制,在setting installAPPs中的 'django.contrib.auth',
# 所以我們要宣告自己的認證路徑 去setting配置,AUTH_USER_MODEL = "users.User"
class User(AbstractUser, BaseModel):
"""使用者"""
# 我們自己不用指明欄位,django的預設欄位,都通過繼承AbstractUser它就有了
class Meta:
db_table = "df_users"
def generate_active_token( self ):
"""生成啟用令牌"""
serializer = Serializer(settings.SECRET_KEY, 3600 )
token = serializer.dumps({ "confirm" : self . id }) # 返回bytes型別
return token.decode()
class Address(BaseModel):
"""地址"""
user = models.ForeignKey(User, verbose_name = "所屬使用者" )
receiver_name = models.CharField(max_length = 20 , verbose_name = "收件人" )
receiver_mobile = models.CharField(max_length = 11 , verbose_name = "聯絡電話" )
detail_addr = models.CharField(max_length = 256 , verbose_name = "詳細地址" )
zip_code = models.CharField(max_length = 6 , verbose_name = "郵政編碼" )
class Meta:
db_table = "df_address"
|
使用者認證模型類
在配置檔案中,指定自己定義的認證系統使用的使用者模型路徑在user應用中的User類,django只支援模組和類名之間用.分隔,多了一個點就解析不出來,
如這樣就解析不出來,AUTH_USER_MODEL = "app.users.User",所以要把它變成,users.User,所以將app目錄新增到解析路徑裡
1 2 3 4 5 |
import sys
sys.path.insert( 1 , os.path.join(BASE_DIR, "app" ))
#認證系統使用的使用者模型
AUTH_USER_MODEL = "users.User"
|
把註冊的應用 新