zoukankan      html  css  js  c++  java
  • Django REST framework+Vue 打造生鲜电商项目(笔记一)

      首先,这系列随笔是我个人在学习Bobby老师的Django实战项目中,记录的觉得对自己来说比较重要的知识点,不是完完整整的项目步骤过程....如果有小伙伴想找完整的教程,可以看看这个(https://www.cnblogs.com/derek1184405959/p/8768059.html)

    一、配置Mysql

    setting.py中的设置

    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'NAME': 'mxshop',
            'USER': 'root',
            'PASSWORD': 'root',
            'HOST': '127.0.0.1',
            "OPTIONS":{"init_command":"SET storage_engine=INNODB;"} #这个是为了后面第三方登陆而指定使用的mysql数据库的引擎,否则第三方登陆的makemigrations将会失败。
         # 注意,如果你的MYSQL版本>=5.6,改成
    "OPTIONS":{"init_command":"SET default_storage_engine=INNODB;"} } }

    安装驱动Mysqlclient   (否则不能使用Mysql)

    下载地址为“https://www.lfd.uci.edu/~gohlke/pythonlibs/”,找到你电脑对应的版本

    二、项目目录结构搭建

     1、创建包appsextra_apps

      这点值得学习,通过创建两个包可以更加方便的管理我们自定义的app和引入的第三方app。

    #setting.py
    
    import os
    import sys
    
    # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
    BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    sys.path.insert(0, BASE_DIR)
    sys.path.insert(0, os.path.join(BASE_DIR, 'apps'))
    sys.path.insert(0, os.path.join(BASE_DIR, 'extra_apps'))

     

    2、创建文件夹media(保存图片等)db_tools(放脚本用的)

     

    #setting.py
    
    # 设置上传文件的路径
    MEDIA_URL="/media/"
    MEDIA_ROOT=os.path.join(BASE_DIR,"media")
    # urls.py
    
    from django.urls import path
    from django.views.static import serve
    from MxShop.settings import MEDIA_ROOT urlpatterns = [ # 文件 path('media/<path:path>', serve, {'document_root': MEDIA_ROOT}), ]

    三、关于Users app的设计

    其实Django内部已经自动提供给我们有关user表的设计了,我们可以通过继承它,在原基础上进行修改,添加我们自己自定义的属性,这样既避免是重复造轮子,同时官方提供给我们的相对我们自己写的安全性上更加完善。

    # users app 下的models
    # 引入AbstractUser
    
    from django.contrib.auth.models import 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.username # 这里用的username是AbstractUser里面的,如果用我们自己定义的name的话,因为我们设定该字段是可以为空的,这样后面在用drf等陆时会出错,因为在我们进行调式时候,只创建了超级用户,普通用户还没有创建。如果用的是self.username,它会自动获取我们超级用户的账号。
    # setting.py
    
    AUTH_USER_MODEL = 'users.UserProfile' #在setting中把替换系统用户,改为我们自定义的

    四、商品类别的models设计

    这里有个知识点,就是如何通过一个model设计出从属关系,让我们可以灵活的自定义一个类的级别。因为在这个项目中商品有三个等级划分,如果创建三张表来表示每一级的话,未免太不灵活,一旦增加或者删除将很麻烦。解决办法是models.ForeignKey("self")指向自己。

    五、如何在一个app里继承另一个app的model下的类

     例如项目中关于购物的app里,我们需要继承用户User,这样才能和购物的行为绑定起来。一般的做法是直接from users.model import User导入的。这里再介绍另一种方法,就是当我们在开发第三方时,是不知道别人定好的用户类具体放在哪里,叫什么名字,这时还用以前的做法就没有用处了。这时我们可以用:

    # get_user_model方法会去setting中找AUTH_USER_MODEL
    from django.contrib.auth import get_user_model
    User = get_user_model()

    六、migrations原理

    注意,因为我们自定义了UserProfile,因此在数据库生成的时候也就是这张表,原本会自动生成的auth_user就不会出现了,这时如果使用admin是会报错的,因为admin默认使用auth_user。
    在进行第二次或者更多次数据迁移的时候,migrate是如何确定把migrations文件夹刚生成的新的py文件更新到数据库的呢?是因为在django_migrations这张表里详细记录了之前migrations已运行的的py文件。因此在migrate之前会先去这张表里查询哪些是已经运行过的了。

    七、自动导入商品数据

    #如何初始化数据,将图片、文字导入到数据库里
    #知识点:独立使用django的model
    我们目前创建好了各种数据表,但数据库中现在什么数据都还没有,如果想要手动往数据库中添加数据,工作量未免太大。这时我们写个脚本导入数据。

    1、db_tools下新建文件夹data,然后把前端的json文件(category_data和product_data)拷贝到里面

    2、把brands和goods图片拷贝到media目录下

    db_tools下新建文件 import_category_data.py

    代码如下:(代码来自https://www.cnblogs.com/derek1184405959/p/8747961.html)

    # db_tools/data/import_category_data.py
    
    #独立使用django的model
    import sys
    import os
    
    #获取当前文件的路径(运行脚本)
    pwd = os.path.dirname(os.path.realpath(__file__))
    #获取项目的跟目录
    sys.path.append(pwd+"../")
    #要想单独使用django的model,必须指定一个环境变量,会去settings配置找
    #参照manage.py里面就知道为什么这样设置了
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "MxShop.settings")
    
    import django
    django.setup()
    
    from goods.models import GoodsCategory
    
    from db_tools.data.category_data import row_data
    
    #一级类
    for lev1_cat in row_data:
        lev1_intance = GoodsCategory()
        lev1_intance.code = lev1_cat["code"]
        lev1_intance.name = lev1_cat["name"]
        lev1_intance.category_type = 1
        #保存到数据库
        lev1_intance.save()
    #二级类
        for lev2_cat in lev1_cat["sub_categorys"]:
            lev2_intance = GoodsCategory()
            lev2_intance.code = lev2_cat["code"]
            lev2_intance.name = lev2_cat["name"]
            lev2_intance.category_type = 2
            lev2_intance.parent_category = lev1_intance
            lev2_intance.save()
    #三级类
            for lev3_cat in lev2_cat["sub_categorys"]:
                lev3_intance = GoodsCategory()
                lev3_intance.code = lev3_cat["code"]
                lev3_intance.name = lev3_cat["name"]
                lev3_intance.category_type = 3
                lev3_intance.parent_category = lev2_intance
                lev3_intance.save()

    然后运行脚本 import_category_data.py  数据就可以保存到数据库了

    同样,导入商品。在data目录下新建import_goods_data.py

    import sys
    import os
    
    pwd = os.path.dirname(os.path.realpath(__file__))
    sys.path.append(pwd+"../")
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "MxShop.settings")
    
    import django
    django.setup()
    
    from goods.models import Goods, GoodsCategory, GoodsImage
    
    from db_tools.data.product_data import row_data
    
    for goods_detail in row_data:
        goods = Goods()
        goods.name = goods_detail["name"]
        #前端中是“¥232”,数据库中是float类型,所以要替换掉 (这里好像是作者在爬取数据时,拿到的数据格式和我们自己在model中设定的不一样,所以修改一下)
        goods.market_price = float(int(goods_detail["market_price"].replace("", "").replace("", "")))
        goods.shop_price = float(int(goods_detail["sale_price"].replace("", "").replace("", "")))
        goods.goods_brief = goods_detail["desc"] if goods_detail["desc"] is not None else ""
        goods.goods_desc = goods_detail["goods_desc"] if goods_detail["goods_desc"] is not None else ""
        # 取第一张作为封面图
        goods.goods_front_image = goods_detail["images"][0] if goods_detail["images"] else ""
        #取最后一个
        category_name = goods_detail["categorys"][-1]
        # 取出当前子类对应的GoodsCategory对象,filter没有匹配的会返回空数组,不会抛异常。
        category = GoodsCategory.objects.filter(name=category_name)
        if category:
            goods.category = category[0]
        goods.save()
    
        for goods_image in goods_detail["images"]:
            goods_image_instance = GoodsImage()
            goods_image_instance.image = goods_image
            goods_image_instance.goods = goods
            goods_image_instance.save()

    然后运行,把商品生产到数据库中

  • 相关阅读:
    对于大流量的网站,您采用什么样的方法来解决访问量问题?
    div section article区分--20150227
    不懂的code整理学习
    常用又容易忘记的代码
    【转】机器学习中常用损失函数
    姿态估计的两个数据集COCO和MPII的认识
    用caffe训练openpose过程中,出现异常
    编译caffe的诸多注意事项
    Win7下Anaconda3+Tensorflow
    论文阅读(Zhe Cao——【CVPR2017】Realtime Multi-Person 2D Pose Estimation using Part Affinity Fields )
  • 原文地址:https://www.cnblogs.com/linyuhong/p/9872997.html
Copyright © 2011-2022 走看看