前言
学无止境,无止境学。大家好,我是张大鹏,之前在抖音有5万多粉丝,不过现在不拍视频,专心写公众号了。笔者目前是高级Python工程师,之前是全栈工程师,主要擅长Golang和Python开发,对于Java,Vue,React也有一些研究。工作之余,喜欢学习和分享,希望能够通过此公众号”张大鹏520″,将自己学到的东西分享给大家,和大家一起交流,一起成长,一起进步。
今天要给大家分享的是《Django加Vue电商项目实战17 创建商城系统模型》,这是一个系列的教程,从零基础到项目实战。在本教程中,我会给大家介绍如何创建商城系统的基础模型。比如抽象基类,用户表,订单表,购物车表,商品表,商品分类表等。还会配套相关的练习,大家学完以后可以自行通过练习题巩固和加深对知识点的理解。
如果大家需要本教程的PDF电子书或者完整的源码,可以在文末找到获取方式哈。
创建应用
创建多个应用
python manage.py startapp basic
python manage.py startapp goods
python manage.py startapp users
python manage.py startapp order
注册应用
首先,创建一个apps的Python包,然后将刚才创建的应用都移动到该包下。
修改基础配置:
# 基础配置
BASE_DIR = Path(__file__).resolve().parent.parent
# 秘钥
SECRET_KEY = 'django-insecure-hqk4c1#kggt@=u@owtbvdgutl&b!=pp*y($1s1z0cw^=a*g#(j'
# 是否为开发环境
DEBUG = True
# 允许访问的主机
ALLOWED_HOSTS = ["*"]
# 路由
ROOT_URLCONF = 'z08_shop_admin.urls'
# wsgi应用
WSGI_APPLICATION = 'z08_shop_admin.wsgi.application'
# 默认自增字段
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
# 设置apps包为搜索路径
sys.path.insert(0, os.path.join(BASE_DIR, 'apps'))
修改应用配置:
# 应用配置
INSTALLED_APPS = [
# 后台应用
'django.contrib.admin',
# 权限应用
'django.contrib.auth',
'django.contrib.contenttypes',
# session应用,用来记录session
'django.contrib.sessions',
# message应用,用来发送消息
'django.contrib.messages',
# 静态文件应用,用来处理静态文件
'django.contrib.staticfiles',
# 入口应用
'index',
# 自定义应用
'apps.basic',
'apps.goods',
'apps.order',
'apps.users',
]
创建模型
安装依赖
pip install django
pip install django-ckeditor
pip install pillow
配置ckeditor富文本
添加应用:
# 应用配置
INSTALLED_APPS = [
# 后台应用
'django.contrib.admin',
# 权限应用
'django.contrib.auth',
'django.contrib.contenttypes',
# session应用,用来记录session
'django.contrib.sessions',
# message应用,用来发送消息
'django.contrib.messages',
# 静态文件应用,用来处理静态文件
'django.contrib.staticfiles',
# 第三方应用
'ckeditor',
'ckeditor_uploader',
# 入口应用
'index',
# 自定义应用
'apps.basic',
'apps.goods',
'apps.order',
'apps.users',
]
添加配置:
# 富文本编辑器ckeditor配置
CKEDITOR_UPLOAD_PATH = 'content/ckeditor/'
CKEDITOR_CONFIGS = {
'default': {
'toolbar': (
['div', 'Source', '-', 'Save', 'NewPage', 'Preview', '-', 'Templates'],
['Cut', 'Copy', 'Paste', 'PasteText', 'PasteFromWord', '-', 'Print', 'SpellChecker', 'Scayt'],
['Undo', 'Redo', '-', 'Find', 'Replace', '-', 'SelectAll', 'RemoveFormat'],
['Form', 'Checkbox', 'Radio', 'TextField', 'Textarea', 'Select', 'Button', 'ImageButton', 'HiddenField'],
['Bold', 'Italic', 'Underline', 'Strike', '-', 'Subscript', 'Superscript'],
['NumberedList', 'BulletedList', '-', 'Outdent', 'Indent', 'Blockquote'],
['JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock'],
['Link', 'Unlink', 'Anchor'],
['Image', 'Flash', 'Table', 'HorizontalRule', 'Smiley', 'SpecialChar', 'PageBreak'],
['Styles', 'Format', 'Font', 'FontSize'],
['TextColor', 'BGColor'],
['Maximize', 'ShowBlocks', '-', 'About', 'pbckcode'],
['Blockquote', 'CodeSnippet'],
),
'width': 'auto',
},
}
基础模型
from django.db import models
class BaseModel(models.Model):
"""抽象基类"""
id = models.AutoField(verbose_name='编号', primary_key=True)
create_time = models.DateTimeField(verbose_name="创建时间", auto_now_add=True)
update_time = models.DateTimeField(verbose_name="更新时间", auto_now=True)
delete_time = models.DateTimeField(verbose_name="删除时间", auto_now=True)
recover_time = models.DateTimeField(verbose_name="恢复时间", auto_now=True)
class Meta:
# 指定抽象基类
abstract = True
用户模型
from django.contrib.auth.models import AbstractUser
from django.db import models
from basic.models import BaseModel
class User(AbstractUser, BaseModel):
"""自定义用户模型"""
# 性别
GENDER = (
(0, '男'),
(1, '女'),
)
# VIP等级
LEVEL = (
(1, '黑金卡会员'),
(2, '钻石卡会员'),
(3, '黄金卡会员'),
(4, '白银卡会员'),
)
# 状态
STATUS = (
(0, '正常'),
(1, '异常'),
)
true_name = models.CharField(verbose_name='真实姓名', blank=True, max_length=50)
mobile = models.CharField(verbose_name='手机号码', max_length=11, default="")
gender = models.IntegerField(verbose_name="性别", default=0, choices=GENDER)
birthday = models.DateField(verbose_name="生日", blank=True, null=True)
avatar = models.ImageField(verbose_name="头像", upload_to="avatar", default="")
level = models.IntegerField(verbose_name="会员等级", default=4, choices=LEVEL)
status = models.IntegerField(verbose_name="状态", default=0, choices=STATUS)
def __str__(self):
return self.username
class Meta(AbstractUser.Meta):
db_table = 'user'
permissions = (
['check_user', '审核用户信息'],
)
商品分类模型
from ckeditor_uploader.fields import RichTextUploadingField
from django.db import models
from basic.models import BaseModel
from users.models import User
class GoodsCategory(BaseModel):
"""商品分类"""
name = models.CharField(verbose_name='分类名称', max_length=50, default='')
parent = models.ForeignKey(verbose_name="父类", to="self", null=True, blank=True, on_delete=models.DO_NOTHING,
related_name="sub_cat")
logo = models.ImageField(verbose_name="分类logo图片", upload_to="uploads/goods/category/logo/")
is_nav = models.BooleanField(verbose_name='是否显示在导航栏', default=False)
sort = models.IntegerField(verbose_name='排序', default=0)
def __str__(self):
return self.name
class Meta:
verbose_name = '商品分类'
verbose_name_plural = '商品分类'
db_table = 'goods_category'
商品模型
from ckeditor_uploader.fields import RichTextUploadingField
from django.db import models
from basic.models import BaseModel
from users.models import User
class Goods(BaseModel):
"""商品表"""
STATUS = (
(0, '正常'),
(1, '下架'),
)
name = models.CharField(verbose_name='商品名称', max_length=50, default='')
category = models.ForeignKey(verbose_name='商品分类', to=GoodsCategory, blank=True, null=True,
on_delete=models.DO_NOTHING)
market_price = models.DecimalField(verbose_name='市场价格', max_digits=8, default=0, decimal_places=2)
price = models.DecimalField(verbose_name='实际价格', max_digits=8, decimal_places=2, default=0)
unit = models.CharField(verbose_name='计量单位', max_length=10, blank=True, null=True)
click_num = models.IntegerField(verbose_name="点击数", default=0)
amount = models.IntegerField(verbose_name="销售量", default=0)
stock_num = models.IntegerField(verbose_name="库存数", default=0)
fav_num = models.IntegerField(verbose_name="收藏数", default=0)
goods_desc = RichTextUploadingField(verbose_name='商品详情', default='')
status = models.IntegerField(verbose_name='状态', default=0, choices=STATUS)
main_img = models.ImageField(verbose_name='商品主图', blank=True, null=True,
upload_to='uploads/goods/goods/images/')
is_recommend = models.BooleanField(verbose_name="是否推荐", default=False)
user = models.ForeignKey(verbose_name="用户", to=User, blank=True, null=True, on_delete=models.DO_NOTHING)
def __str__(self):
return self.name
class Meta:
verbose_name = '商品信息'
verbose_name_plural = verbose_name
db_table = 'goods'
轮播图模型
from ckeditor_uploader.fields import RichTextUploadingField
from django.db import models
from basic.models import BaseModel
from users.models import User
class Slide(BaseModel):
"""首页轮播图"""
goods = models.ForeignKey(verbose_name='商品', to=Goods, on_delete=models.DO_NOTHING)
images = models.ImageField(verbose_name='轮播图片', upload_to='uploads/slide')
sort = models.IntegerField(verbose_name='排列顺序', default=0)
class Meta:
verbose_name = '首页轮播'
verbose_name_plural = '首页轮播'
db_table = 'slide'
购物车模型
from django.db import models
from basic.models import BaseModel
from goods.models import Goods
from users.models import User
class Cart(BaseModel):
"""购物车"""
user = models.ForeignKey(verbose_name='用户', to=User, null=True, blank=True, on_delete=models.DO_NOTHING)
goods = models.ForeignKey(verbose_name='商品', to=Goods, null=True, blank=True, on_delete=models.DO_NOTHING)
goods_num = models.IntegerField(verbose_name='购物车中商品数量', default=1)
def __str__(self):
return str(self.goods.id)
class Meta:
verbose_name = '购物车信息'
verbose_name_plural = verbose_name
managed = True
db_table = 'cart'
订单模型
from django.db import models
from basic.models import BaseModel
from goods.models import Goods
from users.models import User
class Order(BaseModel):
"""订单表"""
ORDER_STATUS = (
("paying", "待支付"),
("payed", "已支付"),
("shipping", "配送中"),
("complete", "订单结束"),
("cancel", "订单取消"),
)
order_sn = models.CharField(verbose_name="订单号", max_length=50, null=True, blank=True)
order_total = models.IntegerField(verbose_name="商品总件数", default=0)
order_price = models.DecimalField(verbose_name="订单总金额", default=0, max_digits=10, decimal_places=2)
address = models.CharField(verbose_name="收货地址", max_length=100, default="")
contact_name = models.CharField(verbose_name="联系人", max_length=20, default="")
contact_mobile = models.CharField(verbose_name="联系电话", max_length=11, default="")
pay_method = models.IntegerField(verbose_name="支付方式", default=0)
memo = models.CharField(verbose_name="订单备注", max_length=200, default='')
order_state = models.CharField(verbose_name="用户", max_length=20, choices=ORDER_STATUS, default='paying')
user = models.ForeignKey(verbose_name="用户", to=User, on_delete=models.DO_NOTHING)
class Meta:
verbose_name = '订单信息'
verbose_name_plural = '订单信息'
managed = True
db_table = 'order'
订单商品映射模型
from django.db import models
from basic.models import BaseModel
from goods.models import Goods
from users.models import User
class OrderGoodsMap(BaseModel):
"""订单商品关联表"""
order = models.ForeignKey(verbose_name="订单主表", to=Order, on_delete=models.DO_NOTHING)
goods = models.ForeignKey(verbose_name="商品表", to=Goods, on_delete=models.DO_NOTHING)
goods_num = models.IntegerField(verbose_name="商品数量", default=0)
# 保留下订单时的价格快照,因为会发生变化
price = models.DecimalField(verbose_name="商品价格", max_digits=10, decimal_places=2)
class Meta:
verbose_name = '订单商品信息'
verbose_name_plural = verbose_name
managed = True
db_table = 'order_goods_map'
路由设计
总路由
from django.contrib import admin
from django.urls import path, include, re_path
from django.views.static import serve
from . import settings
urlpatterns = [
path('admin/', admin.site.urls),
path('user/', include("users.urls")),
path('', include("index.urls")),
# 配置媒体文件目录
re_path('^media/(?P<path>.*)$', serve, {'document_root': settings.MEDIA_ROOT})
]
index路由
from django.urls import path
from . import views, views_page as page
app_name = 'index'
urlpatterns = [
# 首页
path('', views.index, name='index'),
# 页面元素
path('ui/buttons/', page.ui_buttons, name='ui_buttons'),
path('ui/typography/', page.ui_typography, name='ui_typography'),
path('icons/mdi/', page.icons_mdi, name='icons_mdi'),
path('forms/basic/', page.forms_basic, name='forms_basic'),
path('charts/chartjs/', page.charts_chartjs, name='charts_chartjs'),
path('tables/basic/', page.tables_basic, name='tables_basic'),
path('examples/blank/', page.examples_blank, name='examples_blank'),
path('examples/login/', page.examples_login, name='examples_login'),
path('examples/register/', page.examples_register, name='examples_register'),
path('examples/404/', page.examples_404, name='examples_404'),
path('examples/500/', page.examples_500, name='examples_500'),
]
users路由
from django.urls import path
from . import views
app_name = 'user'
urlpatterns = [
# 用户注册
path('register/', views.register, name='register'),
# 用户登录
path('login/', views.login_view, name='login'),
# 用户注销
path('logout/', views.logout_view, name='logout'),
]
迁移数据
先清空原本数据库中的数据,再执行下面的命令:
python manage.py makemigrations
python manage.py migrate
结语
关注我不迷路,欢迎关注我的微信公众号”张大鹏520″,如果您对此文章感兴趣,欢迎点赞收藏,留言评论。
文中所有代码,只需要打赏20元,然后留言评论“已打赏”,即可获取哦。
本文的PDF电子书版,只需要打赏3元,然后留言评论“已打赏”,即可获取哦。
写文章不容易,不喜勿喷哈,如果有想要学编程,学项目,或者在工作中有项目难以单独完成需要提供帮助的同学,欢迎私信我哈。生活不易,想要利用学到的编程知识,业余赚点零花钱。
接项目:网站开发,APP开发,各种管理系统开发。
带徒弟:Python编程教学,Golang编程教学,前端编程教学。
谢谢您!!!
原文始发于微信公众号(张大鹏520):Django加Vue电商项目实战17 创建商城系统模型
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/48585.html