经过前几小节的介绍,ORM 的基础应用,如何把一张数据表建好,方便各张表之间的数据处理。从第一张用户表开始,就意味着整个站点的数据表能有多大的扩展能力。
此次生鲜电商项目的用户表是继承了 Django 自带的用户模型层,可以看到 Django 自带的用户模型都已经有相应的表字段。
一、用户模型
抽象模型类
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 # 说明是抽象模型类
① 重载用户模型
from django.contrib.auth.models import AbstractUser
from utils.models import BaseModel
class User(AbstractUser, BaseModel):
"""用户"""
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="所属用户", on_delete=models.CASCADE)
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"
二、商品模型
① 商品类别
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="类别", on_delete=models.CASCADE)
goods = models.ForeignKey(Goods, verbose_name="商品", on_delete=models.CASCADE)
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", on_delete=models.CASCADE)
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", on_delete=models.CASCADE)
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="商品类别", on_delete=models.CASCADE)
sku = models.ForeignKey(GoodsSKU, verbose_name="商品SKU", on_delete=models.CASCADE)
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
三、订单模型
① 订单信息
class OrderInfo(BaseModel):
"""订单信息"""
PAY_METHODS = {
1: "货到付款",
2: "支付宝",
}
PAY_METHODS_ENUM = {
"CASH": 1,
"ALIPAY": 2
}
PAY_METHOD_CHOICES = (
(1, "货到付款"),
(2, "支付宝"),
)
ORDER_STATUS = {
1: "待支付",
2: "待发货",
3: "待收货",
4: "待评价",
5: "已完成",
}
ORDER_STATUS_ENUM = {
"UNPAID": 1,
"UNSEND": 2,
"UNRECEIVED": 3,
"UNCOMMENT": 4,
"FINISHED": 5
}
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="下单用户", on_delete=models.CASCADE)
address = models.ForeignKey(Address, verbose_name="收获地址", on_delete=models.CASCADE)
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="订单", on_delete=models.CASCADE)
sku = models.ForeignKey(GoodsSKU, verbose_name="订单商品", on_delete=models.CASCADE)
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"