您现在的位置是: 网站首页 >Django >Vue+Django REST framework前后端分离生鲜电商 Django
【Vue+DRF生鲜电商】02.设置users、goods、trade、user_operation数据库并导入原始数据
admin2019年4月21日 11:41 【Django | Vue 】 1837人已围观
Vue+Django REST framework前后端分离生鲜电商简介 Vue+Django REST framework 打造前后端分离的生鲜电商项目(慕课网视频)。 Github地址:https://github.com/xyliurui/DjangoOnlineFreshSupermarket ; Django版本:2.2、djangorestframework:3.9.2。 前端Vue模板可以直接联系我拿。
## 设计数据库 ### 用户:users应用模型 修改 settings.py ,指定认证模型,添加如下内容 ```python AUTH_USER_MODEL = 'users.UserProfile' # 使用自定义的models做认证 ``` #### models.py ```python from django.db import models from django.contrib.auth.models import AbstractUser class UserProfile(AbstractUser): """ 扩展用户,需要在settings设置认证model """ name = models.CharField(max_length=30, blank=True, null=True, verbose_name='姓名', help_text='姓名') birthday = models.DateField(null=True, blank=True, verbose_name='出生年月', help_text='出生年月') mobile = models.CharField(max_length=11, verbose_name='电话', help_text='电话') gender = models.CharField(max_length=6, choices=(('male', '男'), ('female', '女')), default='male', verbose_name='性别', help_text='性别') class Meta: verbose_name_plural = verbose_name = '用户' def __str__(self): # 要判断name是否有值,如果没有,则返回username,否则使用createsuperuser创建用户访问与用户关联的模型会报错, # 页面(A server error occurred. Please contact the administrator.) # 后台(UnicodeDecodeError: 'gbk' codec can't decode byte 0xa6 in position 9737: illegal multibyte sequence) if self.name: return self.name else: return self.username class VerifyCode(models.Model): """ 短信验证码,可以保存在redis等中 """ code = models.CharField(max_length=20, verbose_name='验证码', help_text='验证码') mobile = models.CharField(max_length=11, verbose_name='电话', help_text='电话') add_time = models.DateTimeField(auto_now_add=True, verbose_name='添加时间') class Meta: verbose_name_plural = verbose_name = '短信验证码' def __str__(self): return self.code ``` #### 后台应用名显示中文 修改users应用下 apps.py ```python from django.apps import AppConfig class UsersConfig(AppConfig): name = 'users' verbose_name = '用户' ``` ### 商品:goods应用模型 #### 商品详情富文本ckeditor 后台admin集成ckeditor富文本编辑器 安装依赖包 ```bash >pip install django-ckeditor >pip install pillow ``` 修改 settings.py ,添加应用 ```python INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', # 添加drf应用 'rest_framework', # 注册富文本编辑器ckeditor 'ckeditor', # 注册富文本上传图片ckeditor_uploader 'ckeditor_uploader', ] ``` 配置文件上传路径,修改 settings.py ```python # 配置媒体文件 MEDIA_URL = '/media/' MEDIA_ROOT = os.path.join(BASE_DIR, 'media') # 配置富文本上传路径 CKEDITOR_UPLOAD_PATH = 'upload/' ``` 配置富文本路由,修改主 urls.py ```python from django.contrib import admin from django.urls import path, include from django.conf.urls.static import static # 上传的文件能直接通过url打开,以及setting中设置 from django.conf import settings urlpatterns = [ path('admin/', admin.site.urls), path('api-auth/', include('rest_framework.urls')), path('ckeditor/', include('ckeditor_uploader.urls')), # 配置富文本编辑器url ] # 上传的文件能直接通过url打开 if settings.DEBUG: urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) ``` ![BLOG_20190421_114427_16](/media/blog/images/2019/04/BLOG_20190421_114427_16.png "博客图集BLOG_20190421_114427_16.png") #### models.py ```python from django.db import models from ckeditor.fields import RichTextField # 文本编辑器 from ckeditor_uploader.fields import RichTextUploadingField # 富文本可上传图片 class GoodsCategory(models.Model): """ 商品类别 """ CATEGORY_TYPE = ( (1, '一级类目'), (2, '二级类目'), (3, '三级类目'), ) name = models.CharField(max_length=30, default='', verbose_name='类别名称', help_text='商品类别名称') # help_text说明,生成文档很有用 code = models.CharField(max_length=30, default='', verbose_name='类别编码', help_text='商品类别编码') desc = models.TextField(default='', verbose_name='类别描述', help_text='类别描述') category_type = models.SmallIntegerField(choices=CATEGORY_TYPE, default=1, verbose_name='类目级别', help_text='商品类目的级别') is_tab = models.BooleanField(default=False, verbose_name='是否导航', help_text='类别是否导航') add_time = models.DateTimeField(auto_now_add=True, verbose_name='添加时间') parent_category = models.ForeignKey('self', null=True, blank=True, verbose_name='父级目录', help_text='父级目录', on_delete=models.CASCADE, related_name='sub_category') class Meta: verbose_name_plural = verbose_name = '商品类别' def __str__(self): return self.name class GoodsCategoryBrand(models.Model): """ 品牌 """ category = models.ForeignKey(GoodsCategory, null=True, blank=True, on_delete=models.CASCADE, verbose_name='商品类别', help_text='商品类别') name = models.CharField(max_length=30, default='', verbose_name='品牌名称', help_text='品牌名称') desc = models.TextField(default='', max_length=200, verbose_name='品牌描述', help_text='品牌描述') image = models.ImageField(max_length=200, upload_to='brand/images/', verbose_name='品牌图片', help_text='品牌图片') add_time = models.DateTimeField(auto_now_add=True, verbose_name='添加时间') class Meta: verbose_name_plural = verbose_name = '品牌' def __str__(self): return self.name class Goods(models.Model): """ 商品 """ category = models.ForeignKey(GoodsCategory, on_delete=models.CASCADE, verbose_name='商品类别', help_text='商品类别') goods_sn = models.CharField(max_length=100, default='', verbose_name='商品编码', help_text='商品唯一货号') name = models.CharField(max_length=300, verbose_name='商品名称', help_text='商品名称') click_num = models.IntegerField(default=0, verbose_name='点击数', help_text='点击数') sold_num = models.IntegerField(default=0, verbose_name='销售量', help_text='销售量') fav_num = models.IntegerField(default=0, verbose_name='收藏数', help_text='收藏数') goods_num = models.IntegerField(default=0, verbose_name='库存量', help_text='库存量') market_price = models.FloatField(default=0, verbose_name='市场价格', help_text='市场价格') shop_price = models.FloatField(default=0, verbose_name='本店价格', help_text='本店价格') goods_brief = models.TextField(max_length=500, verbose_name='简短描述', help_text='商品简短描述') goods_desc = RichTextUploadingField(verbose_name='详情描述', help_text='详情描述') ship_free = models.BooleanField(default=True, verbose_name='是否免运费', help_text='是否免运费') goods_front_image = models.ImageField(upload_to='goods/front/', null=True, blank=True, verbose_name='封面图', help_text='封面图') is_new = models.BooleanField(default=False, verbose_name='是否新品', help_text='是否新品') is_hot = models.BooleanField(default=False, verbose_name='是否热销', help_text='是否热销') add_time = models.DateTimeField(auto_now_add=True, verbose_name='添加时间') class Meta: verbose_name_plural = verbose_name = '商品' def __str__(self): return self.name class GoodsImage(models.Model): """ 商品图片 """ goods = models.ForeignKey(Goods, verbose_name='商品', help_text='商品', on_delete=models.CASCADE, related_name='images') image = models.ImageField(upload_to='goods/images/', verbose_name='图片', help_text='图片') add_time = models.DateTimeField(auto_now_add=True, verbose_name='添加时间') class Meta: verbose_name_plural = verbose_name = '商品图片' def __str__(self): return self.goods.name class Banner(models.Model): """ 首页轮播图 """ goods = models.ForeignKey(Goods, verbose_name='商品', help_text='商品', on_delete=models.CASCADE, related_name='banners') image = models.ImageField(upload_to='goods/banners/', verbose_name='图片', help_text='图片') index = models.IntegerField(default=0, verbose_name='轮播顺序', help_text='轮播顺序') add_time = models.DateTimeField(auto_now_add=True, verbose_name='添加时间') class Meta: verbose_name_plural = verbose_name = '首页轮播图' def __str__(self): return self.goods.name ``` #### 后台应用名显示中文 修改 apps.py ```python from django.apps import AppConfig class GoodsConfig(AppConfig): name = 'goods' verbose_name = '商品' ``` ### 交易:trade应用模型 #### models.py ```python from django.db import models from goods.models import Goods # from users.models import UserProfile # 但是某些情况下我们不知道用户的模型,可以直接使用下方的方法获取用户model from django.contrib.auth import get_user_model User = get_user_model() class ShoppingCart(models.Model): """ 购物车 """ user = models.ForeignKey(User, verbose_name='用户', help_text='用户', on_delete=models.CASCADE, related_name='shopping_carts') goods = models.ForeignKey(Goods, verbose_name='商品', help_text='商品', on_delete=models.CASCADE) nums = models.IntegerField(default=0, verbose_name='购买数量', help_text='购买数量') add_time = models.DateTimeField(auto_now_add=True, verbose_name='添加时间') class Meta: verbose_name_plural = verbose_name = '购物车' def __str__(self): return "{}({})".format(self.goods.name, self.nums) class OrderInfo(models.Model): """ 订单 """ ORDER_STATUS = ( ('success', '成功'), ('cancel', '取消'), ('topaid', '待支付') ) user = models.ForeignKey(User, verbose_name='用户', help_text='用户', on_delete=models.CASCADE, related_name='order_infos') order_sn = models.CharField(max_length=30, unique=True, verbose_name='订单号', help_text='订单号') trade_no = models.CharField(max_length=100, unique=True, null=True, blank=True, verbose_name='支付') pay_status = models.CharField(choices=ORDER_STATUS, max_length=20, verbose_name='订单状态', help_text='订单状态') post_script = models.CharField(max_length=50, blank=True, null=True, verbose_name='订单留言', help_text='订单留言') order_amount = models.FloatField(default=0.0, verbose_name='订单金额', help_text='订单金额') pay_time = models.DateTimeField(null=True, blank=True, verbose_name='支付时间', help_text='支付时间') # 用户信息 address = models.CharField(max_length=200, default='', verbose_name='收货地址', help_text='收货地址') signer_name = models.CharField(max_length=20, default='', verbose_name='签收人', help_text='签收人') signer_mobile = models.CharField(max_length=11, verbose_name='联系电话', help_text='联系电话') add_time = models.DateTimeField(auto_now_add=True, verbose_name='添加时间') class Meta: verbose_name_plural = verbose_name = '订单' def __str__(self): return "{}".format(self.order_sn) class OrderGoods(models.Model): """ 订单商品详情 """ order = models.ForeignKey(OrderInfo, on_delete=models.CASCADE, verbose_name='订单信息', help_text='订单信息', related_name='order_goods') goods = models.ForeignKey(Goods, verbose_name='商品', help_text='商品', blank=True, null=True, on_delete=models.SET_NULL) goods_nums = models.IntegerField(default=0, verbose_name='购买数量', help_text='购买数量') add_time = models.DateTimeField(auto_now_add=True, verbose_name='添加时间') class Meta: verbose_name_plural = verbose_name = '订单商品' def __str__(self): return str(self.order.order_sn) ``` #### 后台应用名显示中文 修改 apps.py ```python from django.apps import AppConfig class TradeConfig(AppConfig): name = 'trade' verbose_name = '交易' ``` ### 操作:user_operation应用模型 #### models.py ```python from django.db import models from goods.models import Goods from django.contrib.auth import get_user_model User = get_user_model() class UserFav(models.Model): """ 用户收藏 """ user = models.ForeignKey(User, verbose_name='用户', help_text='用户', on_delete=models.CASCADE, related_name='favs') goods = models.ForeignKey(Goods, on_delete=models.CASCADE, verbose_name='商品', help_text='商品') add_time = models.DateTimeField(auto_now_add=True, verbose_name='添加时间') class Meta: verbose_name_plural = verbose_name = '用户收藏' def __str__(self): return self.user.name class UserLeavingMessage(models.Model): """ 用户留言 """ MESSAGE_TYPE = ( (1, '留言'), (2, '投诉'), (3, '询问'), (4, '售后'), (5, '求购') ) user = models.ForeignKey(User, verbose_name='用户', help_text='用户', on_delete=models.CASCADE, related_name='leaving_msgs') message_type = models.IntegerField(default=1, choices=MESSAGE_TYPE, verbose_name='留言类型', help_text='留言类型:1-留言,2-投诉, 3-询问, 4-售后, 5-求购') subject = models.CharField(max_length=100, default='', verbose_name='主题', help_text='主题') message = models.TextField(default='', verbose_name='留言内容', help_text='留言内容') file = models.FileField(upload_to='upload/leaving_msg/', blank=True, null=True, verbose_name='上传文件', help_text='上传文件') add_time = models.DateTimeField(auto_now_add=True, verbose_name='添加时间') class Meta: verbose_name_plural = verbose_name = '用户留言' def __str__(self): return '{} {}:{}'.format(self.user.name, self.get_message_type_display(), self.subject) class UserAddress(models.Model): """ 用户收货地址 """ user = models.ForeignKey(User, verbose_name='用户', help_text='用户', on_delete=models.CASCADE, related_name='addresses') district = models.CharField(max_length=100, default='', verbose_name='区域', help_text='区域') address = models.CharField(max_length=200, default='', verbose_name='收货地址', help_text='收货地址') signer_name = models.CharField(max_length=20, default='', verbose_name='签收人', help_text='签收人') signer_mobile = models.CharField(max_length=11, verbose_name='联系电话', help_text='联系电话') add_time = models.DateTimeField(auto_now_add=True, verbose_name='添加时间') class Meta: verbose_name_plural = verbose_name = '收货地址' def __str__(self): return self.address ``` #### 后台应用名显示中文 修改 apps.py ```python from django.apps import AppConfig class UserOperationConfig(AppConfig): name = 'user_operation' verbose_name = '操作' ``` ## migrate表生成 ### 应用添加到apps中 修改 settings.py ,加上面的app添加到配置中 ```python INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', # 添加drf应用 'rest_framework', # 注册富文本编辑器ckeditor 'ckeditor', # 注册富文本上传图片ckeditor_uploader 'ckeditor_uploader', 'users.apps.UsersConfig', 'goods.apps.GoodsConfig', 'trade.apps.TradeConfig', 'user_operation.apps.UserOperationConfig' ] ``` ### 执行同步 用于生成数据表 ```bash manage.py@DjangoOnlineFreshSupermarket > makemigrations manage.py@DjangoOnlineFreshSupermarket > migrate # 就开始报错了 django.db.migrations.exceptions.InconsistentMigrationHistory: Migration admin.0001_initial is applied before its dependency users.0001_initial on database 'default'. ``` 删除数据库中 除了`auth_user`的其他表,然后重新来一次,如果不行再继续删除所有的表后再次重来; 大概原因是因为admin的模型依赖了之前默认的user模型,且之前还在user中添加了`admin`用户,然后又使用了`AbstractUser`继承导致出错。 ![BLOG_20190421_114345_68](/media/blog/images/2019/04/BLOG_20190421_114345_68.png "博客图集BLOG_20190421_114345_68.png") ## 初步注册到admin后台 采用批量注册方式,修改各自应用对应的 admin.py ### users ```python from django.contrib import admin from .models import UserProfile, VerifyCode from django.apps import apps all_models = apps.get_app_config('users').get_models() for model in all_models: try: admin.site.register(model) except: pass ``` ### goods ```python from django.contrib import admin from .models import GoodsCategory, Goods from django.apps import apps all_models = apps.get_app_config('goods').get_models() for model in all_models: try: admin.site.register(model) except: pass ``` ### trade ```python from django.contrib import admin from django.apps import apps all_models = apps.get_app_config('trade').get_models() for model in all_models: try: admin.site.register(model) except: pass ``` ### user_opration ```python from django.contrib import admin from django.apps import apps all_models = apps.get_app_config('user_operation').get_models() for model in all_models: try: admin.site.register(model) except: pass ``` ![BLOG_20190421_114338_53](/media/blog/images/2019/04/BLOG_20190421_114338_53.png "博客图集BLOG_20190421_114338_53.png")
很赞哦! (3)
相关文章
当前用户
未登录,点击 登录专题目录
- 【Vue+DRF生鲜电商】01.课程结构介绍,开发环境搭建
- 【Vue+DRF生鲜电商】02.设置users、goods、trade、user_operation数据库并导入原始数据
- 【Vue+DRF生鲜电商】03.Restful API基础
- 【Vue+DRF生鲜电商】04.Vue项目结构介绍
- 【Vue+DRF生鲜电商】05.商品列表序列化普通方法
- 【Vue+DRF生鲜电商】06.DRF环境配置,使用Serializer类序列化商品列表
- 【Vue+DRF生鲜电商】07.序列化商品分页功能
- 【Vue+DRF生鲜电商】08.ViewSets & Routers显示商品列表
- 【Vue+DRF生鲜电商】09.使用DRF的filter过滤商品列表
- 【Vue+DRF生鲜电商】10.商品分类层级获取,Vue跨域请求商品分类
- 【Vue+DRF生鲜电商】11.Vue展示左侧分类、面包屑、排序、商品列表、分页
- 【Vue+DRF生鲜电商】12.用户登录之DRF Token认证登录原理和使用方法
- 【Vue+DRF生鲜电商】13.JWT用户认证原理配置,Vue登录接口调试
- 【Vue+DRF生鲜电商】14.用户注册发送短信验证码、登录字段验证
- 【Vue+DRF生鲜电商】15.用户注册使用信号量实现密码加密
- 【Vue+DRF生鲜电商】16.Vue中注册、退出功能交互
- 【Vue+DRF生鲜电商】17.DRF实现商品详情及热卖商品接口,Vue中显示商品详情和热卖
- 【Vue+DRF生鲜电商】18.用户收藏、取消收藏商品接口实现
- 【Vue+DRF生鲜电商】19.用户添加、删除收藏权限处理,根据商品id显示收藏,在Vue中实现收藏功能
- 【Vue+DRF生鲜电商】20.使用DRF自动生成文档的功能
- 【Vue+DRF生鲜电商】21.用户中心个人资料的展示,并在Vue中实现个人资料更新
- 【Vue+DRF生鲜电商】22.个人中心显示用户收藏功能,对收藏进行删除
- 【Vue+DRF生鲜电商】23.个人中心用户留言功能
- 【Vue+DRF生鲜电商】24.用户收货地址功能
- 【Vue+DRF生鲜电商】25.商品添加购物车接口功能,Vue和购物车联调
- 【Vue+DRF生鲜电商】26.使用Pycharm远程代码调试服务器Django代码
- 【Vue+DRF生鲜电商】26.订单接口功能,Vue和订单接口联调
- 【Vue+DRF生鲜电商】27.支付宝公钥,私钥,沙箱环境配置
- 【Vue+DRF生鲜电商】28.支付宝支付接口类解读,支付逻辑编辑
- 【Vue+DRF生鲜电商】29.线上服务支付宝接口和Vue联调,Django代理Vue运行
- 【Vue+DRF生鲜电商】30.首页轮播图、新品展示功能
- 【Vue+DRF生鲜电商】31.首页商品按分类显示推荐功能
- 【Vue+DRF生鲜电商】32.商品操作后计数更改,热搜榜关键字功能实现
- 【Vue+DRF生鲜电商】33.数据缓存、接口访问限速功能
- 【Vue+DRF生鲜电商】34.第三方登录(微博、qq和微信)之微博登录登录测试
- 【Vue+DRF生鲜电商】35.使用social-app-django集成第三方登录