第一步: 设计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,里面

(生鲜项目)02. app与model设计的更多相关文章

  1. 3- vue django restful framework 打造生鲜超市 - model设计和资源导入

    3- vue django restful framework 打造生鲜超市 - model设计和资源导入 使用Python3.6与Django2.0.2(Django-rest-framework) ...

  2. Java生鲜电商平台-API接口设计之token、timestamp、sign 具体架构与实现(APP/小程序,传输安全)

    Java生鲜电商平台-API接口设计之token.timestamp.sign 具体设计与实现 说明:在实际的业务中,难免会跟第三方系统进行数据的交互与传递,那么如何保证数据在传输过程中的安全呢(防窃 ...

  3. Java生鲜电商平台-小程序或者APP优惠券的设计与源码实战

    Java生鲜电商平台-小程序或者APP优惠券的设计与源码实战 说明:Java生鲜电商平台-小程序或者APP优惠券的设计与源码实战,优惠券是一种常见的促销方式,在规定的周期内购买对应商品类型和额度的商品 ...

  4. [转]Android App整体架构设计的思考

    1. 架构设计的目的 对程序进行架构设计的原因,归根到底是为了提高生产力.通过设计使程序模块化,做到模块内部的高聚合和模块之间的低耦合.这样做的好处是使得程序在开发的过程中,开发人员只需要专注于一点, ...

  5. Java开源生鲜电商平台-通知模块设计与架构(源码可下载)

    Java开源生鲜电商平台-通知模块设计与架构(源码可下载) 说明:对于一个生鲜的B2B平台而言,通知对于我们实际的运营而言来讲分为三种方式:           1. 消息推送:(采用极光推送)   ...

  6. Java生鲜电商平台-系统报表设计与架构

    Java生鲜电商平台-系统报表设计与架构 说明:任何一个运行的平台都需要一个很清楚的报表来显示,那么作为Java开源生鲜电商平台而言,我们应该如何设计报表呢?或者说我们希望报表来看到什么数据呢?   ...

  7. 网站开发学习Python实现-Django的models学习-生鲜项目(6.3.2)

    @ 目录 1.说明 2.模型类的设计 3.代码的具体实现 4.详情地址 关于作者 1.说明 models是django的很重要的部分,所以深入研究. 本文章的所研究项目为黑马教育python课程中的项 ...

  8. 15款优秀移动APP产品原型设计工具

    一新来小盆友问:“移动产品原型设计都用啥工具?” 答:“@#¥……&%*” 又问:“能详细说下各个工具吗?我比较一下” “……” 好吧,谁让我那么的爱分享而你又是小美女呢 ———————正文开 ...

  9. Android App的架构设计:从VM、MVC、MVP到MVVM

    随着Android应用开发规模的扩大,客户端业务逻辑也越来越复杂,已然不是简单的数据展示了.如同后端开发遇到瓶颈时采用的组件拆分思想,客户端也需要进行架构设计,拆分视图和数据,解除模块之间的耦合,提高 ...

随机推荐

  1. HTML——MP4视频不能播放

    前言 HTML5中提供了video标签,但是为什么有的MP4视频可以播放,有的不能播放呢? 简介 当然是因为编码的问题咯~ 视频格式 标签属性 DOM参考 HTML 5 视频/音频参考手册 使用 &l ...

  2. 浏览器报400-Bad Request异常

    今天在使用ie浏览器在测试程序的时候,报这个错误,后台日志打印出来显示的是:连接一个远程主机失败 解决Invalid character found in the request target. Th ...

  3. if语句的嵌套:从键盘输入3个实数,利用条件表达式求其最大者。

    #include<stdio.h>void main(){ float a,b,c,max; scanf("%f%f%f",&a,&b,&c); ...

  4. LeetCode 1135. Connecting Cities With Minimum Cost

    原题链接在这里:https://leetcode.com/problems/connecting-cities-with-minimum-cost/ 题目: There are N cities nu ...

  5. 47、Spark SQL核心源码深度剖析(DataFrame lazy特性、Optimizer优化策略等)

    一.源码分析 1. ###入口org.apache.spark.sql/SQLContext.scala sql()方法: /** * 使用Spark执行一条SQL查询语句,将结果作为DataFram ...

  6. 微信小程序与云开发

    微信小程序基础概念 小程序云开发的三大基础能力:云数据库.云函数.云存储 Java.NodeJS.JavaScript.HTML5.CSS3.VueJs.ReactJs.前端工程化.前端架构 小程序开 ...

  7. 第12组 Beta冲刺(4/5)

    Header 队名:To Be Done 组长博客 作业博客 团队项目进行情况 燃尽图(组内共享) 展示Git当日代码/文档签入记录(组内共享) 注: 由于GitHub的免费范围内对多人开发存在较多限 ...

  8. 第12组 Alpha事后诸葛亮

    Header 组长博客 Postmortem 设想和目标 我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描述? 要解决的是喜欢记录分享旅游生活的人群的行迹记录和分享问题, ...

  9. Android中创建自定义控件

    1.创建一个TitleLayout继承LinearLayout: //创建自定义控件 public class TitleLayout extends LinearLayout { private f ...

  10. TreeMap用法总结

    TreeMap用法总结 public class TreeMap<K,V> extends AbstractMap<K,V> implements NavigableMap&l ...