(生鲜项目)02. app与model设计
第一步: 设计app
1. 根据业务需求,设计合适的app板块,这里,我们将拥有goods,trade,user_operation, users四个app
2. 然后去注册app
第二步: 设计users.models
1. users.models.py
from datetime import datetime # 用于addtime字段
from django.db import models
from django.contrib.auth.models import AbstractUser
# 用户信息,继承django自带的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.name
# 手机验证码,可以放在redis内存中,也可以存在数据库中,这里我们存在数据库中
class VerifyCode(models.Model):
code = models.CharField(max_length=10, verbose_name="验证码")
mobile = models.DateField(max_length=11, verbose_name="电话")
# 千万不要写成datetime.now(),否则在编译的时候就添加时间了
add_time = models.DateTimeField(default=datetime.now, verbose_name="添加时间")
class Meta:
verbose_name = "短信验证码"
verbose_name_plural = verbose_name
def __str__(self):
return self.code
2. 千万别忘记这个设置, 有了这个,django才知道你要用自己的user表
settings.py
AUTH_USER_MODEL='users.UserProfile'
第三步: 设计goods.models
首先分析goods需要多少个类,可发现从分类上来看有三类,第一类与第二类是一对多的关系,第二类与第三类也是一对多的关系,因此需要创建三个类,但是这种做法并不灵活,如果以后要改成2个类,或者改成4个类,就很麻烦,这里有一种方法可以实现一个类就可以无限分类的目的
1. goods.models.py
from datetime import datetime
from django.db import models
from DjangoUeditor.models import UEditorField
# 商品类别
class GoodsCategory(models.Model):
"""
商品类别
name 商品中文名
code 商品英文名
"""
CATEGORY_TYPE = (
(1, "一级类目"),
(2, "二级类目"),
(3, "三级类目"),
)
# help_text 用在后面生成文档中
name = models.CharField(default="", max_length=30, verbose_name="类别名", help_text="类别名")
code = models.CharField(default="", max_length=30, verbose_name="类别code", help_text="类别code")
desc = models.TextField(default="", verbose_name="类别描述", help_text="类别描述")
category_type = models.IntegerField(choices=CATEGORY_TYPE, verbose_name="类目级别", help_text="类目级别")
# "self"关键字就可以实现自己外键自己,从而达到无限分类的目的
parent_category = models.ForeignKey("self", null=True, blank=True, verbose_name="父类目级别", help_text="父类目级别",
# 后面查询的时候会用到related_name
related_name="sub_cat")
is_tab = models.BooleanField(default=False, 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.name
# 品牌信息
class GoodsCategoryBrand(models.Model):
"""
品牌名与品牌图片
"""
# 这个外键指定了哪些类别才拥有品牌信息
category = models.ForeignKey(GoodsCategory, null=True, blank=True, verbose_name="商品类目")
name = models.CharField(max_length=30, default="", verbose_name="品牌名", help_text="品牌名")
desc = models.TextField(max_length=200, default="", verbose_name="品牌描述", help_text="品牌描述")
image = models.ImageField(max_length=200, upload_to="brand/images")
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 Goods(models.Model):
category = models.ForeignKey(GoodsCategory, 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(default=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="", 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, 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
# 首页的轮播商品
class Banner(models.Model):
goods = models.ForeignKey(Goods, 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需要多少个表,电商里面有两个概念很重要: 购物车, 和订单
1. 同一个商品对同一个用户来说, 只有一条记录,只是数量不一样
2. 一旦点击去结算, 那么购物车就会被清空,而变成订单
from datetime import datetime
from django.db import models
from django.contrib.auth import get_user_model
from goods.models import Goods
User=get_user_model()
# 购物车
class ShoppingCart(models.Model):
uer=models.ForeignKey(User,verbose_name="用户")
goods=models.ForeignKey(Goods,verbose_name="商品")
nums=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 f"{self.goods.name}({self.nums})"
# 订单详情
class OrderInfo:
ORDER_STATUS=(
("success","成功"),
("cancel","取消"),
("cancel","待支付"),
)
user=models.ForeignKey(User)
order_sn=models.CharField(max_length=30,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,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, verbose_name="订单信息", related_name="goods")
goods = models.ForeignKey(Goods, 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)
4. 会自动生成文件夹 ,node_modules,里面
第五步: 设计useroperation.models
首先分析需要多少个表, 用户收藏, 用户收货地址, 用户评论
from datetime import datetime
from django.db import models
from django.contrib.auth import get_user_model
from goods.models import Goods
User = get_user_model()
# 用户收藏
class UserFav(models.Model):
user = models.ForeignKey(User, verbose_name="用户")
goods = models.ForeignKey(Goods, 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.user.name
# 用户留言
class UserLeavingMessage(models.Model):
MESSAGE_CHOICES = (
(1, "留言"),
(2, "投诉"),
(3, "询问"),
(4, "售后"),
(5, "求购")
)
user = models.ForeignKey(User, 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
# 用户收货地址
class UserAddress(models.Model):
user = models.ForeignKey(User, 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
第六步: makemigrations和migrate
不赘述, 补充一点的就是如果遇到migrate不生效, 应该如何解决? 见下图, 删除后, 重新makemigrations和migrate即可
------ over -----------
settings.py
AUTH_USER_MODEL='users.UserProfile'
4. 会自动生成文件夹 ,node_modules,里面
settings.py
AUTH_USER_MODEL='users.UserProfile'
4. 会自动生成文件夹 ,node_modules,里面