- 創建子應用
- goods 商品模塊
python ../../manage.py startapp goods
- contents 首頁廣告模塊
python ../../manage.py startapp contents
- goods 商品模塊
- 模型類創建並遷移
- goods模型類
from django.db import models from md.utils.models import BaseModel # Create your models here. class GoodsCategory(BaseModel): """ 商品類別 """ name = models.CharField(max_length=10, verbose_name='名稱') parent = models.ForeignKey('self', null=True, blank=True, on_delete=models.CASCADE, verbose_name='父類別') class Meta: db_table = 'tb_goods_category' verbose_name = '商品類別' verbose_name_plural = verbose_name def __str__(self): return self.name class GoodsChannel(BaseModel): """ 商品頻道 """ group_id = models.IntegerField(verbose_name='組號') category = models.ForeignKey(GoodsCategory, on_delete=models.CASCADE, verbose_name='頂級商品類別') url = models.CharField(max_length=50, verbose_name='頻道頁面鏈接') sequence = models.IntegerField(verbose_name='組內順序') class Meta: db_table = 'tb_goods_channel' verbose_name = '商品頻道' verbose_name_plural = verbose_name def __str__(self): return self.category.name class Brand(BaseModel): """ 品牌 """ name = models.CharField(max_length=20, verbose_name='名稱') logo = models.ImageField(verbose_name='Logo圖片') first_letter = models.CharField(max_length=1, verbose_name='品牌首字母') class Meta: db_table = 'tb_brand' verbose_name = '品牌' verbose_name_plural = verbose_name def __str__(self): return self.name class Goods(BaseModel): """ 商品SPU """ name = models.CharField(max_length=50, verbose_name='名稱') brand = models.ForeignKey(Brand, on_delete=models.PROTECT, verbose_name='品牌') category1 = models.ForeignKey(GoodsCategory, on_delete=models.PROTECT, related_name='cat1_goods', verbose_name='一級類別') category2 = models.ForeignKey(GoodsCategory, on_delete=models.PROTECT, related_name='cat2_goods', verbose_name='二級類別') category3 = models.ForeignKey(GoodsCategory, on_delete=models.PROTECT, related_name='cat3_goods', verbose_name='三級類別') sales = models.IntegerField(default=0, verbose_name='銷量') comments = models.IntegerField(default=0, verbose_name='評價數') class Meta: db_table = 'tb_goods' verbose_name = '商品' verbose_name_plural = verbose_name def __str__(self): return self.name class GoodsSpecification(BaseModel): """ 商品規格 """ goods = models.ForeignKey(Goods, on_delete=models.CASCADE, verbose_name='商品') name = models.CharField(max_length=20, verbose_name='規格名稱') class Meta: db_table = 'tb_goods_specification' verbose_name = '商品規格' verbose_name_plural = verbose_name def __str__(self): return '%s: %s' % (self.goods.name, self.name) class SpecificationOption(BaseModel): """ 規格選項 """ spec = models.ForeignKey(GoodsSpecification, on_delete=models.CASCADE, verbose_name='規格') value = models.CharField(max_length=20, verbose_name='選項值') class Meta: db_table = 'tb_specification_option' verbose_name = '規格選項' verbose_name_plural = verbose_name def __str__(self): return '%s - %s' % (self.spec, self.value) class SKU(BaseModel): """ 商品SKU """ name = models.CharField(max_length=50, verbose_name='名稱') caption = models.CharField(max_length=100, verbose_name='副標題') goods = models.ForeignKey(Goods, on_delete=models.CASCADE, verbose_name='商品') category = models.ForeignKey(GoodsCategory, on_delete=models.PROTECT, verbose_name='從屬類別') price = models.DecimalField(max_digits=10, decimal_places=2, verbose_name='單價') cost_price = models.DecimalField(max_digits=10, decimal_places=2, verbose_name='進價') market_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='銷量') comments = models.IntegerField(default=0, verbose_name='評價數') is_launched = models.BooleanField(default=True, verbose_name='是否上架銷售') default_image_url = models.CharField(max_length=200, default='', null=True, blank=True, verbose_name='默認圖片') class Meta: db_table = 'tb_sku' verbose_name = '商品SKU' verbose_name_plural = verbose_name def __str__(self): return '%s: %s' % (self.id, self.name) class SKUImage(BaseModel): """ SKU圖片 """ sku = models.ForeignKey(SKU, on_delete=models.CASCADE, verbose_name='sku') image = models.ImageField(verbose_name='圖片') class Meta: db_table = 'tb_sku_image' verbose_name = 'SKU圖片' verbose_name_plural = verbose_name def __str__(self): return '%s %s' % (self.sku.name, self.id) class SKUSpecification(BaseModel): """ SKU具體規格 """ sku = models.ForeignKey(SKU, on_delete=models.CASCADE, verbose_name='sku') spec = models.ForeignKey(GoodsSpecification, on_delete=models.PROTECT, verbose_name='規格名稱') option = models.ForeignKey(SpecificationOption, on_delete=models.PROTECT, verbose_name='規格值') class Meta: db_table = 'tb_sku_specification' verbose_name = 'SKU規格' verbose_name_plural = verbose_name def __str__(self): return '%s: %s - %s' % (self.sku, self.spec.name, self.option.value)
- contents模型類
from django.db import models from md.utils.models import BaseModel # Create your models here. class ContentCategory(BaseModel): """ 廣告內容類別 """ name = models.CharField(max_length=50, verbose_name='名稱') key = models.CharField(max_length=50, verbose_name='類別鍵名') class Meta: db_table = 'tb_content_category' verbose_name = '廣告內容類別' verbose_name_plural = verbose_name def __str__(self): return self.name class Content(BaseModel): """ 廣告內容 """ category = models.ForeignKey(ContentCategory, on_delete=models.PROTECT, verbose_name='類別') title = models.CharField(max_length=100, verbose_name='標題') url = models.CharField(max_length=300, verbose_name='內容鏈接') image = models.ImageField(null=True, blank=True, verbose_name='圖片') text = models.TextField(null=True, blank=True, verbose_name='內容') sequence = models.IntegerField(verbose_name='排序') status = models.BooleanField(default=True, verbose_name='是否展示') class Meta: db_table = 'tb_content' verbose_name = '廣告內容' verbose_name_plural = verbose_name def __str__(self): return self.category.name + ': ' + self.title
- 註冊應用
INSTALLED_APPS = [ """""" 'contents.apps.ContentsConfig', # 主頁模塊 'goods.apps.GoodsConfig', # 商品模塊 ]
- 實現遷移
python manage.py makemigrations python manage.py migrate
- goods模型類
- 對接fastdfs
- 導入模塊fdfs_client-py github地址
""" fdfs_client-py 使用源碼安裝直接從 github 下載 """ pip install fdfs_client-py-master.zip pip install mutagen pip isntall requests
- 在utils下創建fastdfs目錄(python package)然後添加client.conf配置文件
- 更改django配置
# FastDFS配置信息 FDFS_CLIENT_CONF = os.path.join(BASE_DIR, 'utils/fastdfs/client.conf')
- 更改client.conf配置
# FastDFS客戶端存放日誌文件的目錄 base_path=/home/python/Downloads # tracker的ip和端口 tracker_server=192.168.1.102:22122
- 導入模塊fdfs_client-py github地址
- 自定義文件存儲系統
- 在fastdfs創建file_storage.py 實現官方文檔django自定義文件存儲中文翻譯
- 實現
from django.core.files.storage import Storage from fdfs_client.client import Fdfs_client from django.conf import settings class FastDFSStorage(Storage): """自定義文件存儲系統""" def __init__(self, client_conf=None, base_url=None): """初始化文件存儲對象的構造方法""" # if client_conf == None: # self.client_conf = settings.FDFS_CLIENT_CONF # 如果client_conf參數爲None,就讀取or後面的值 self.client_conf = client_conf or settings.FDFS_CLIENT_CONF self.base_url = base_url or settings.FDFS_BASE_URL def _open(self, name, mode='rb'): """ 儲存類用於打開文件:因爲必須實現,但是此處是文件存儲不需要打開文件,所以重寫沒用到,所以pass :param name: 要打開的文件的名字 :param mode: 打開的模式,read bytes :return: None """ pass def _save(self, name, content): """ 實現文件存儲:在這個方法裏面將文件轉存到FastDFS服務器 :param name: 要存儲的文件的名字 :param content: 要存儲的文件對象,File類型的對象,將來使用content.read()讀取對象中的文件二進制 :return: file_id """ # 創建對接fdfs的客戶端對象 # client = Fdfs_client('md/utils/fastdfs/client.conf') # client = Fdfs_client(settings.FDFS_CLIENT_CONF) client = Fdfs_client(self.client_conf) # 將文件轉存到fdfs # ret = client.upload_by_filename('/Users/zhangjie/Desktop/01.jpeg') ret = client.upload_by_buffer(content.read()) # 判斷文件上傳是否成功 if ret.get('Status') != 'Upload successed.': raise Exception('upload file failed') # 能夠執行到這裏說明上傳成功 file_id = ret.get('Remote file_id') # 在自定義了文件存儲系統之後,我們只需要返回file_id即可 # 將來文件存儲系統會"自動的"將file_id存儲到對應的ImageFiled字段中 # file_id == 'group1/M00/00/00/wKhnhluSuYeAIc39AAC4j90Tziw56.jpeg' return file_id def exists(self, name): """ 判斷文件是否存在,判斷本地是否存儲了該文件,如果存儲了就不會再存儲,如果沒有存儲就調用_save() :param name: 要判斷的文件的名字 :return: True(文件存在) / False(文件不存在) """ return False def url(self, name): """ 返回文件的絕對路徑的,下載圖片時使用的 :param name: 是要讀取的文件的名字,name==file_id :return: 文件絕對路徑 http://192.168.1.102:8888/group1/M00/00/00/wKhnhluTuniAezl6AAC4j90Tziw02.jpeg """ # return 'http://192.168.1.102:8888/' + name return self.base_url + name """ { 'Group name': 'group1', 'Remote file_id': 'group1/M00/00/00/wKhnhluSuYeAIc39AAC4j90Tziw56.jpeg', 'Status': 'Upload successed.', 'Local file name': '****/Desktop/01.jpeg', 'Uploaded size': '46.00KB', 'Storage IP': '192.168.1.102' } """
- 添加配置
# django文件存儲 DEFAULT_FILE_STORAGE = 'meiduo_mall.utils.fastdfs.file_storage.FastDFSStorage' # FastDFS配置信息 FDFS_BASE_URL = 'http://192.168.103.132:8888/' FDFS_CLIENT_CONF = os.path.join(BASE_DIR, 'utils/fastdfs/client.conf')
做一個Django項目(2.4、商品和首頁廣告模塊並對接fastdfs用於保存文件)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.