您现在的位置是: 网站首页 >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)

文章交流

  • emoji
2人参与,1条评论
sss 2019年9月24日 17:53
删除数据库中 除了auth_user的其他表,然后重新来一次 错了,应该把表全部删除
吾星喵 @ sss 2019年9月24日 18:04
如果还报错把所有表删了重建

当前用户

未登录,点击   登录

站点信息

  • 建站时间:网站已运行2247天
  • 系统信息:Linux
  • 后台程序:Python: 3.8.10
  • 网站框架:Django: 3.2.6
  • 文章统计:257 篇
  • 文章评论:60 条
  • 腾讯分析网站概况-腾讯分析
  • 百度统计网站概况-百度统计
  • 公众号:微信扫描二维码,关注我们
  • QQ群:QQ加群,下载网站的学习源码
返回
顶部
标题 换行 登录
网站