路飞学城之 luffy (2 )

目录
  • 路飞学城之 luffy (2 )
  • 一、各类配置
    • 1.pip源
    • pip安装源
      • 介绍
      • 永久配置安装源
        • Windows
        • MacOS、Linux
        • 配置文件内容
    • 2.虚拟环境的搭建
      • 虚拟环境的搭建
      • 优点
      • windows
        • 安装
        • 配置虚拟环境管理器工作目录
      • MacOS、Linux
        • 安装
        • 工作文件
        • 配置
      • 使用
      • pycharm使用
        • 新建项目
        • 添加环境
        • 使用环境
    • 3.luffy后台
      • 后台:Django项目创建
      • 环境
      • 创建项目
      • 重构项目目录
      • 配置开发环境
      • 配置日志
    • 4.luffy后台配置
      • 环境变量
        • dev.py
        • 在写项目直接导入utils文件夹也不''错误提示''
      • 封装logger
        • dev.py
        • utils/logging.py
      • 封装项目异常处理
        • utils/exception.py
        • settings.py
      • 二次封装Response模块
        • utils/response.py
    • 5.luffy数据库
      • 数据库配置
      • 创建数据库
      • 为指定数据库配置指定账户
      • Django 2.x 一些版本pymysql兼容问题
        • Django不采用2.0.7版本很可能出现以下问题,需要修改源代码
    • 6.user模块User表
      • user模块User表
      • 创建user模块
      • 创建User表对应的model:user/models.py
      • 注册user模块,配置User表:dev.py
      • 配置media
        • media配置:dev.py
        • media目录配置
        • 主路由:luffyapi/urls.py
        • 子路由:user/urls.py
    • 7.luffy前台
    • 前台
      • vue环境
      • 创建项目
      • 重构项目目录
      • 文件修订:目录中非配置文件的多余文件可以移除
        • App.vue
        • router/index.js
        • Home.vue
      • 全局配置:全局样式、配置文件
        • global.css
        • settings.js
        • main.js
    • 8.luffy前台配置
    • luffy前台配置
      • axios前后台交互
        • 安装:前端项目目录下的终端
        • 配置:main.js
      • cookies操作
        • 安装:前端项目目录下的终端
        • 配置:main.js
      • element-ui页面组件框架
        • 安装:前端项目目录下的终端
        • 配置:main.js
      • bootstrap页面组件框架
        • 安装:前端项目目录下的终端
        • 配置jquery:vue.config.js
        • 配置bootstrap:main.js
    • 9.luffy前台主页
    • 前端主页
      • 图片准备
      • 页头组件:components/Header.vue
      • 轮播图组件:components/Banner.vue
      • 页脚组件:components/Footer.vue
      • 主页组件:views/Home.vue
    • 10.后台主页模块设计
    • home模块
      • 创建home模块
      • 路由分发
        • 主路由:luffyapi/urls.py
        • 子路由:home/urls.py
      • Banner数据表model设计
        • utils/model.py
        • home/models.py
        • 数据迁移:在大luffyapi路径下的终端
      • 注册home模块:dev.py
      • 设计Banner数据接口
        • home/serializers.py
        • home/views.py
        • home/urls.py
        • 接口
    • 11.前后台分离跨域交互
    • 分离的前后台交互
      • 后台处理跨域
        • 安装插件
        • 项目配置:dev.py
      • 前台请求Banner数据
        • 修订Banner.vue
    • 12.xadmin后台管理
    • xadmin后台管理
      • 安装:luffy虚拟环境下
      • 注册app:dev.py
      • xadmin:需要自己的数据库模型类,完成数据库迁移
      • 设置主路由替换掉admin:主urls.py
      • 创建超级用户:大luffyapi路径终端
      • 完成xadmin全局配置:新建home/adminx.py
      • 在adminx.py中注册model:home/adminx.px
      • 修改app:home的名字:xadmin页面上的显示效果
    • 笔记巩固
      • 知识点巩固
      • 总结
      • A作业(必做)
      • B作业(选做)
  • 二、git
    • 版本控制器
    • git
      • 简介
      • git与svn比较
      • git的工作流程
      • git分支管理
    • git使用
      • 安装
      • 基础命令
        • 将已有的文件夹 - 初始化为git仓库
        • 在指定目录下 - 初始化git仓库
        • 在仓库目录终端下 - 设置全局用户
        • 在仓库目录终端下 - 设置局部用户
        • 查看仓库状态
        • 工作区操作
        • 撤销工作区操作:改、删
        • 工作区内容提交到暂存区
        • 撤销暂存区提交:add的逆运算
        • 提交暂存区内容到版本库
        • 撤销版本库提交:commit的逆运算
      • 过滤文件
    • 创建远程gitee仓库
      • 选择线上仓库
    • 用本地仓库首次初始化远程仓库
      • 本地仓库与远程仓库建立源连接
      • 创建电脑的公钥私钥
      • 提交本地代码到远程仓库
    • remote源操作
      • 多分支开发
        • 分支操作
        • 线上分支合并
    • 安装
    • 知识点复习与归纳
      • 知识复习
      • 版本控制器:SVN、GIT
      • 知识点总结
      • A作业(必做)
      • B作业(选做)
  • 三、页面设计
    • 登录页面设计
    • 注册页面设计
    • 知识点回顾与归纳
      • 日考
      • 知识点总结
      • A作业(必做)
      • B作业(选做)
      • 总结
  • 四、导航模态登录注册
    • 前提:基于element-ui环境
    • 模态登录组件
    • 模态注册组件
    • 导航条:结合实际情况完成样式
    • 知识点归纳
      • 知识点总结
      • A作业(必做)
      • B作业(选做)
  • 五、celery和redis操作
  • Celery
    • 官方
    • Celery架构
      • 消息中间件
      • 任务执行单元
      • 任务结果存储
    • 使用场景
    • Celery的安装配置
    • Celery执行异步任务
      • 包架构封装
      • 基本使用
        • celery.py
        • tasks.py
        • add_task.py
        • get_result.py
      • 高级使用
        • celery.py
        • tasks.py
        • get_result.py
      • django中使用
        • celery.py
        • tasks.py
  • redis操作
    • redis VS mysql
    • redis VS memcache
    • Redis操作
    • redis数据库
    • python使用redis
      • 依赖
      • 直接使用
      • 连接池使用
      • 缓存使用:要额外安装 django-redis
    • 知识点归纳与练习
      • 日考
      • 知识点总结
      • A作业(必做)
      • B作业(选做)
  • 六、
    • 1.课程页页面
      • 课程组件
    • 2.修订课程主页
    • 3.课程详情页
      • 1.详情页前台
      • 详情页组件
        • 依赖:在luffycity目录下的命令
        • 配置:main.js
        • 资源:图片放置assrts/img文件夹
        • 路由:router.js
        • 组件
      • 2.详情页后台
      • 详情页后台
        • 路由:source/urls.py
        • 视图:source/views.py
        • 序列化:source/serializers.py
        • 视图字段:source/model.py
      • 运用图片
    • 支付
      • 支付宝支付
      • 支付流程
      • aliapy二次封装包
        • 依赖
        • 结构
        • setting.py
        • _init_.py
        • alipay_public_key.pem
        • app_private_key.pem
        • 补充:dev.py
      • 支付模块
        • order/models.py
      • 后台接口
      • 订单序列化模块
      • 支付接口生成支付链接
      • 前台回调接口的页面
      • 支付完成订单校验的接口
    • 上线
      • 购买服务器
      • 连接服务器
      • 服务器命令
        • 管理员权限
        • 配置终端
    • 重要
      • 更新系统软件包
      • 安装软件管理包和可能使用的依赖
      • 安装Mysql
      • 安装Redis
      • 安装Python3.6
      • 配置pip源:阿里云不用配置,默认配置阿里源
      • 安装uwsgi
      • 安装虚拟环境
      • 服务器运行测试Django项目
      • 安装Nginx
      • Nginx命令
      • Nginx & uwsgi 运行Django
      • 路飞项目部署:Nginx + uwsgi + django + vue
      • 配置前台项目
        • 上线前配置
          • settings.js
        • 上线
      • 路飞后台部署
        • 上线前配置
        • 上线
      • pip导入导出依赖
      • 数据库设置 + django2.0源码(2.0.7不用修改源码)
      • 后台样式问题
        • 设置文件中配置STATIC_ROOT
        • 迁移静态样式:项目目录下
        • Nginx配置静态路径
        • 重启服务
      • 重点 重点 重点
      • 添加测试数据
    • 课堂笔记
      • 复习
      • 课程内容
      • A作业(必做)
      • B作业(选做)
  • 七、
    • 上线
    • 支付
    • 搜索
      • Header搜索组件
    • 课堂笔记
      • 日考
      • 复习
      • 课程内容
      • A作业(必做)
      • B作业(选做)
  • 八、
    • 上线
    • 支付
    • 课堂笔记
      • 复习
      • 课程总结
      • vue
      • drf
      • 课程内容
      • A作业(必做)
      • B作业(选做)

路飞学城之 luffy (2 )

一、各类配置

1.pip源

pip安装源

介绍

"""
1、采用国内源,加速下载模块的速度
2、常用pip源:
	-- 豆瓣:https://pypi.douban.com/simple
	-- 阿里:https://mirrors.aliyun.com/pypi/simple
3、加速安装的命令:
	-- >: pip install -i https://pypi.douban.com/simple 模块名
"""

永久配置安装源

Windows
"""
1、文件管理器文件路径地址栏敲:%APPDATA% 回车,快速进入 C:\Users\电脑用户\AppData\Roaming 文件夹中
2、新建 pip 文件夹并在文件夹中新建 pip.ini 配置文件
3、新增 pip.ini 配置文件内容
"""
MacOS、Linux
"""
1、在用户根目录下 ~ 下创建 .pip 隐藏文件夹,如果已经有了可以跳过
	-- mkdir ~/.pip
2、进入 .pip 隐藏文件夹并创建 pip.conf 配置文件
	-- cd ~/.pip && touch pip.conf
3、启动 Finder(访达) 按 cmd+shift+g 来的进入,输入 ~/.pip 回车进入
4、新增 pip.conf 配置文件内容
"""
配置文件内容
"""
[global]
index-url = http://pypi.douban.com/simple
[install]
use-mirrors =true
mirrors =http://pypi.douban.com/simple/
trusted-host =pypi.douban.com
"""

2.虚拟环境的搭建

虚拟环境的搭建

优点

1、使不同应用开发环境相互独立
2、环境升级不影响其他应用,也不会影响全局的python环境
3、防止出现包管理混乱及包版本冲突

windows

安装
# 建议使用pip3安装到python3环境下
pip3 install virtualenv
pip3 install virtualenvwrapper-win
配置虚拟环境管理器工作目录
# 配置环境变量:
# 控制面板 => 系统和安全 => 系统 => 高级系统设置 => 环境变量 => 系统变量 => 点击新建 => 填入变量名与值
变量名:WORKON_HOME  变量值:自定义存放虚拟环境的绝对路径
eg: WORKON_HOME: D:\Virtualenvs

# 同步配置信息:
# 去向Python3的安装目录 => Scripts文件夹 => virtualenvwrapper.bat => 双击

MacOS、Linux

安装
# 建议使用pip3安装到python3环境下
pip3 install -i https://pypi.douban.com/simple virtualenv
pip3 install -i https://pypi.douban.com/simple virtualenvwrapper
工作文件
# 先找到virtualenvwrapper的工作文件 virtualenvwrapper.sh,该文件可以刷新自定义配置,但需要找到它
# MacOS可能存在的位置 /Library/Frameworks/Python.framework/Versions/版本号文件夹/bin
# Linux可能所在的位置 /usr/local/bin  |  ~/.local/bin  |  /usr/bin
# 建议不管virtualenvwrapper.sh在哪个目录,保证在 /usr/local/bin 目录下有一份
# 如果不在 /usr/local/bin 目录,如在 ~/.local/bin 目录,则复制一份到 /usr/local/bin 目录
	-- sudo cp -rf ~/.local/bin/virtualenvwrapper.sh /usr/local/bin

配置
# 在 ~/.bash_profile 完成配置,virtualenvwrapper的默认默认存放虚拟环境路径是 ~/.virtualenvs
# WORKON_HOME=自定义存放虚拟环境的绝对路径,需要自定义就解注
VIRTUALENVWRAPPER_PYTHON=/usr/local/bin/python3
source /usr/local/bin/virtualenvwrapper.sh

# 在终端让配置生效:
	-- source ~/.bash_profile

使用

# 在终端工作的命令

# 1、创建虚拟环境到配置的WORKON_HOME路径下
# 选取默认Python环境创建虚拟环境:
	-- mkvirtualenv 虚拟环境名称
# 基于某Python环境创建虚拟环境:
	-- mkvirtualenv -p python2.7 虚拟环境名称
	-- mkvirtualenv -p python3.6 虚拟环境名称

# 2、查看已有的虚拟环境
	-- workon

# 3、使用某个虚拟环境
	-- workon 虚拟环境名称
	
# 4、进入|退出 该虚拟环境的Python环境
	-- python | exit()

# 5、为虚拟环境安装模块
	-- pip或pip3 install 模块名

# 6、退出当前虚拟环境
	-- deactivate

# 7、删除虚拟环境(删除当前虚拟环境要先退出)
	-- rmvirtualenv 虚拟环境名称

pycharm使用

新建项目

路飞学城之 luffy (2 )_第1张图片

添加环境

路飞学城之 luffy (2 )_第2张图片

使用环境

路飞学城之 luffy (2 )_第3张图片

3.luffy后台

后台:Django项目创建

环境

"""
为luffy项目创建一个虚拟环境
>: mkvirtualenv luffy
"""

"""
按照基础环境依赖
>: pip install django==2.0.7
>: pip install djangorestframework
>: pip install pymysql
"""

创建项目

"""
前提:在目标目录新建luffy文件夹
>: cd 建立的luffy文件夹
>: django-admin startproject luffyapi

开发:用pycharm打开项目,并选择提前备好的虚拟环境
"""

重构项目目录

"""
├── luffyapi
	├── logs/				# 项目运行时/开发时日志目录 - 包
    ├── manage.py			# 脚本文件
    ├── luffyapi/      		# 项目主应用,开发时的代码保存 - 包
     	├── apps/      		# 开发者的代码保存目录,以模块[子应用]为目录保存 - 包
        ├── libs/      		# 第三方类库的保存目录[第三方组件、模块] - 包
    	├── settings/  		# 配置目录 - 包
			├── dev.py   	# 项目开发时的本地配置
			└── prod.py  	# 项目上线时的运行配置
		├── urls.py    		# 总路由
		└── utils/     		# 多个模块[子应用]的公共函数类库[自己开发的组件]
    └── scripts/       		# 保存项目运营时的脚本文件 - 文件夹
"""

配置开发环境

"""
1.修改 wsgi.py 与 manage.py 两个文件:
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'luffyapi.settings.dev')

2.将settings.py删除或改名,内容拷贝到settings/dev.py中

3.修改dev.py文件内容
LANGUAGE_CODE = 'zh-hans'
TIME_ZONE = 'Asia/Shanghai'
USE_TZ = False

4.修改启动配置:见插图

5.在任何一个__init__.py文件中测试默认配置文件是否是dev.py文件
from django.conf import settings
print(settings)
"""

路飞学城之 luffy (2 )_第4张图片

配置日志

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'verbose': {
            'format': '%(levelname)s %(asctime)s %(module)s %(lineno)d %(message)s'
        },
        'simple': {
            'format': '%(levelname)s %(module)s %(lineno)d %(message)s'
        },
    },
    'filters': {
        'require_debug_true': {
            '()': 'django.utils.log.RequireDebugTrue',
        },
    },
    'handlers': {
        'console': {
            'level': 'DEBUG',
            'filters': ['require_debug_true'],
            'class': 'logging.StreamHandler',
            'formatter': 'simple'
        },
        'file': {
            # 实际开发建议使用WARNING
            'level': 'INFO',
            'class': 'logging.handlers.RotatingFileHandler',
            # 日志位置,日志文件名,日志保存目录必须手动创建,注:这里的文件路径要注意BASE_DIR代表的是小luffyapi
            'filename': os.path.join(os.path.dirname(BASE_DIR), "logs", "luffy.log"),
            # 日志文件的最大值,这里我们设置300M
            'maxBytes': 300 * 1024 * 1024,
            # 日志文件的数量,设置最大日志数量为10
            'backupCount': 10,
            # 日志格式:详细格式
            'formatter': 'verbose',
            # 文件内容编码
            'encoding': 'utf-8'
        },
    },
    # 日志对象
    'loggers': {
        'django': {
            'handlers': ['console', 'file'],
            'propagate': True, # 是否让日志信息继续冒泡给其他的日志处理系统
        },
    }
}

4.luffy后台配置

环境变量

dev.py
# 环境变量操作:小luffyapiBASE_DIR与apps文件夹都要添加到环境变量
import sys
sys.path.insert(0, BASE_DIR)
APPS_DIR = os.path.join(BASE_DIR, 'apps')
sys.path.insert(1, APPS_DIR)

在写项目直接导入utils文件夹也不''错误提示''

封装logger

dev.py
# 真实项目上线后,日志文件打印级别不能过低,因为一次日志记录就是一次文件io操作
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'verbose': {
            'format': '%(levelname)s %(asctime)s %(module)s %(lineno)d %(message)s'
        },
        'simple': {
            'format': '%(levelname)s %(module)s %(lineno)d %(message)s'
        },
    },
    'filters': {
        'require_debug_true': {
            '()': 'django.utils.log.RequireDebugTrue',
        },
    },
    'handlers': {
        'console': {
            # 实际开发建议使用WARNING
            'level': 'DEBUG',
            'filters': ['require_debug_true'],
            'class': 'logging.StreamHandler',
            'formatter': 'simple'
        },
        'file': {
            # 实际开发建议使用ERROR
            'level': 'INFO',
            'class': 'logging.handlers.RotatingFileHandler',
            # 日志位置,日志文件名,日志保存目录必须手动创建,注:这里的文件路径要注意BASE_DIR代表的是小luffyapi
            'filename': os.path.join(os.path.dirname(BASE_DIR), "logs", "luffy.log"),
            # 日志文件的最大值,这里我们设置300M
            'maxBytes': 300 * 1024 * 1024,
            # 日志文件的数量,设置最大日志数量为10
            'backupCount': 10,
            # 日志格式:详细格式
            'formatter': 'verbose',
            # 文件内容编码
            'encoding': 'utf-8'
        },
    },
    # 日志对象
    'loggers': {
        'django': {
            'handlers': ['console', 'file'],
            'propagate': True, # 是否让日志信息继续冒泡给其他的日志处理系统
        },
    }
}

utils/logging.py
import logging
logger = logging.getLogger('django')

封装项目异常处理

utils/exception.py
from rest_framework.views import exception_handler as drf_exception_handler
from rest_framework.views import Response
from rest_framework import status
from utils.logging import logger
def exception_handler(exc, context):
    response = drf_exception_handler(exc, context)
    # 异常模块就是记录项目的错误日志
    logger.error('%s - %s - %s' % (context['view'], context['request'].method, exc))
    if response is None:
        return Response({
            'detail': '%s' % exc
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR, exception=True)
    return response

settings.py
REST_FRAMEWORK = {
    'EXCEPTION_HANDLER': 'utils.exception.exception_handler',
}

二次封装Response模块

utils/response.py
from rest_framework.response import Response

class APIResponse(Response):
    def __init__(self, data_status=0, data_msg='ok', results=None, http_status=None, headers=None, exception=False, **kwargs):
        data = {
            'status': data_status,
            'msg': data_msg,
        }
        if results is not None:
            data['results'] = results
        data.update(kwargs)

        super().__init__(data=data, status=http_status, headers=headers, exception=exception)

5.luffy数据库

数据库配置

创建数据库

"""
1.管理员连接数据库
>: mysql -uroot -proot

2.创建数据库
>: create database luffy default charset=utf8;

3.查看用户
>: select user,host,password from mysql.user;
"""

为指定数据库配置指定账户

"""
设置权限账号密码
# 授权账号命令:grant 权限(create, update) on 库.表 to '账号'@'host' identified by '密码'

1.配置任意ip都可以连入数据库的账户
>: grant all privileges on luffy.* to 'luffy'@'%' identified by 'Luffy123?';

2.由于数据库版本的问题,可能本地还连接不上,就给本地用户单独配置
>: grant all privileges on luffy.* to 'luffy'@'localhost' identified by 'Luffy123?';

3.刷新一下权限
>: flush privileges;

只能操作luffy数据库的账户
账号:luffy
密码:Luffy123?
"""

Django 2.x 一些版本pymysql兼容问题

Django不采用2.0.7版本很可能出现以下问题,需要修改源代码

路飞学城之 luffy (2 )_第5张图片

路飞学城之 luffy (2 )_第6张图片

6.user模块User表

user模块User表

创建user模块

前提:在 luffy 虚拟环境下

1.终端从项目根目录进入apps目录
>: cd luffyapi & cd apps

2.创建app
>: python ../../manage.py startapp user

创建User表对应的model:user/models.py

from django.db import models
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
    mobile = models.CharField(max_length=11, unique=True)
    icon = models.ImageField(upload_to='icon', default='icon/default.png')

    class Meta:
        db_table = 'luffy_user'
        verbose_name = '用户表'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.username

注册user模块,配置User表:dev.py

INSTALLED_APPS = [
    # ...
    'user',
]

# 自定义User表
AUTH_USER_MODEL = 'user.User'

配置media

media配置:dev.py
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

media目录配置
"""
├── luffyapi
    └──	luffyapi/
       	└──	media/  	
			└──	icon 
				└── default.png
"""

主路由:luffyapi/urls.py
from django.contrib import admin
from django.urls import path, re_path, include
from django.views.static import serve
from django.conf import settings
urlpatterns = [
    path('admin/', admin.site.urls),

    path('user/', include('user.urls')),

    re_path('^media/(?P.*)', serve, {'document_root': settings.MEDIA_ROOT})
]

子路由:user/urls.py
from django.urls import path, re_path
urlpatterns = [

]

7.luffy前台

前台

vue环境

1.傻瓜式安装node: 
官网下载:https://nodejs.org/zh-cn/

2.安装cnpm: 
>: npm install -g cnpm --registry=https://registry.npm.taobao.org

3.安装vue最新脚手架: 
>: cnpm install -g @vue/cli

注:如果2、3步报错,清除缓存后重新走2、3步
>: npm cache clean --force

创建项目

"""
前提:在目标目录新建luffy文件夹
>: cd 建立的luffy文件夹
>: vue create luffycity
"""

重构项目目录

"""
├── luffycity
	├── public/          			# 项目共有资源
		├── favicon.ico				# 站点图标
		└── index.html				# 主页
    ├── src/      					# 项目主应用,开发时的代码保存
    	├── assets/      			# 前台静态资源总目录
    		├── css/				# 自定义css样式
    			└── global.css		# 自定义全局样式
    		├── js/					# 自定义js样式
				└── settings.js		# 自定义配置文件
			└── img/				# 前台图片资源
		├── components/    			# 小组件目录
		├── views/  				# 页面组件目录
		├── App.vue	    			# 根路由
		├── main.js	    			# 入口脚本文件
		├── router    		
			└── index.js			# 路由脚本文件
		store	    		
			└── index.js			# 仓库脚本文件
    ├── vue.config.js	    		# 项目配置文件
    └── *.*							# 其他配置文件
"""

文件修订:目录中非配置文件的多余文件可以移除

App.vue


router/index.js
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'

Vue.use(VueRouter);

const routes = [
    {
        path: '/',
        name: 'home',
        component: Home
    },
];

const router = new VueRouter({
    mode: 'history',
    base: process.env.BASE_URL,
    routes
});

export default router

Home.vue




全局配置:全局样式、配置文件

global.css
/* 声明全局样式和项目的初始化样式 */
body, h1, h2, h3, h4, p, table, tr, td, ul, li, a, form, input, select, option, textarea {
    margin: 0;
    padding: 0;
    font-size: 15px;
}

a {
    text-decoration: none;
    color: #333;
}

ul {
    list-style: none;
}

table {
    border-collapse: collapse; /* 合并边框 */
}

settings.js
export default {
    base_url: 'http://127.0.0.1:8000'
}

main.js
// 配置全局样式
import '@/assets/css/global.css'

// 配置全局自定义设置
import settings from '@/assets/js/settings'
Vue.prototype.$settings = settings;
// 在所有需要与后台交互的组件中:this.$settings.base_url + '再拼接具体后台路由'


8.luffy前台配置

luffy前台配置

axios前后台交互

安装:前端项目目录下的终端
>: cnpm install axios

配置:main.js
import axios from 'axios'
Vue.prototype.$axios = axios;

cookies操作

安装:前端项目目录下的终端
>: cnpm install vue-cookies

配置:main.js
import cookies from 'vue-cookies'
Vue.prototype.$cookies = cookies;

element-ui页面组件框架

安装:前端项目目录下的终端
>: cnpm install element-ui

配置:main.js
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);

bootstrap页面组件框架

安装:前端项目目录下的终端
>: cnpm install jquery
>: cnpm install bootstrap@3

配置jquery:vue.config.js
const webpack = require("webpack");

module.exports = {
    configureWebpack: {
        plugins: [
            new webpack.ProvidePlugin({
                $: "jquery",
                jQuery: "jquery",
                "window.jQuery": "jquery",
                "window.$": "jquery",
                Popper: ["popper.js", "default"]
            })
        ]
    }
};

配置bootstrap:main.js
import 'bootstrap'
import 'bootstrap/dist/css/bootstrap.min.css'


9.luffy前台主页

前端主页

图片准备

将提供的资料中的图片移植到项目的img文件夹下

页头组件:components/Header.vue







轮播图组件:components/Banner.vue






页脚组件:components/Footer.vue







主页组件:views/Home.vue





10.后台主页模块设计

home模块

创建home模块

前提:在 luffy 虚拟环境下

1.终端从项目根目录进入apps目录
>: cd luffyapi & cd apps

2.创建app
>: python ../../manage.py startapp home

路由分发

主路由:luffyapi/urls.py
from django.urls import path, re_path, include
urlpatterns = [
	# ...
    path('user/', include('home.urls')),
    # ...
]

子路由:home/urls.py
from django.urls import path, re_path
urlpatterns = [

]

Banner数据表model设计

utils/model.py
from django.db import models

class BaseModel(models.Model):
    orders = models.IntegerField(verbose_name='显示顺序')
    is_show = models.BooleanField(verbose_name="是否上架", default=False)
    is_delete = models.BooleanField(verbose_name="逻辑删除", default=False)

    class Meta:
        abstract = True

home/models.py
from django.db import models
from utils.model import BaseModel

class Banner(BaseModel):
    image = models.ImageField(upload_to='banner', verbose_name='轮播图', null=True, blank=True)
    name = models.CharField(max_length=150, verbose_name='轮播图名称')
    note = models.CharField(max_length=150, verbose_name='备注信息')
    link = models.CharField(max_length=150, verbose_name='轮播图广告地址')

    class Meta:
        db_table = 'luffy_banner'
        verbose_name = '轮播图'
        verbose_name_plural = verbose_name

    def __str__(self):
        return self.name

数据迁移:在大luffyapi路径下的终端
>: python manage.py makemigrations
>: python manage.py migrate

注册home模块:dev.py

INSTALLED_APPS = [
    # ...
    'rest_framework',
    'home',
]


设计Banner数据接口

home/serializers.py
from rest_framework.serializers import ModelSerializer
from . import models
class BannerModelSerializer(ModelSerializer):
    class Meta:
        model = models.Banner
        fields = ('name', 'note', 'image', 'link')

home/views.py
from rest_framework.generics import ListAPIView
from utils.response import APIResponse
from . import models, serializers
class BannerListAPIView(ListAPIView):
    queryset = models.Banner.objects.filter(is_delete=False, is_show=True).order_by('-orders')
    serializer_class = serializers.BannerModelSerializer


home/urls.py
from django.urls import path, re_path
from . import views
urlpatterns = [
    path('banners/', views.BannerListAPIView.as_view())
]


接口
http://api.luffy.cn:8000/home/banner/


11.前后台分离跨域交互

分离的前后台交互

后台处理跨域

安装插件
>: pip install django-cors-headers

插件参考地址:https://github.com/ottoyiu/django-cors-headers/

项目配置:dev.py
# 注册app
INSTALLED_APPS = [
	...
	'corsheaders'
]

# 添加中间件
MIDDLEWARE = [
	...
	'corsheaders.middleware.CorsMiddleware'
]

# 允许跨域源
CORS_ORIGIN_ALLOW_ALL = True

前台请求Banner数据

修订Banner.vue





12.xadmin后台管理

xadmin后台管理

安装:luffy虚拟环境下
# >: pip install https://codeload.github.com/sshwsfc/xadmin/zip/django2

注册app:dev.py
INSTALLED_APPS = [
    # ...
    # xamin主体模块
    'xadmin',
    # 渲染表格模块
    'crispy_forms',
    # 为模型通过版本控制,可以回滚数据
    'reversion',
]

xadmin:需要自己的数据库模型类,完成数据库迁移
python manage.py makemigrations
python manage.py migrate

设置主路由替换掉admin:主urls.py
# xadmin的依赖
import xadmin
xadmin.autodiscover()
# xversion模块自动注册需要版本控制的 Model
from xadmin.plugins import xversion
xversion.register_models()

urlpatterns = [
    # ...
    path(r'xadmin/', xadmin.site.urls),
]

创建超级用户:大luffyapi路径终端
# 在项目根目录下的终端
python manage.py createsuperuser
# 账号密码设置:admin | Admin123

完成xadmin全局配置:新建home/adminx.py
# home/adminx.py
# xadmin全局配置
import xadmin
from xadmin import views

class GlobalSettings(object):
    """xadmin的全局配置"""
    site_title = "路飞学城"  # 设置站点标题
    site_footer = "路飞学城有限公司"  # 设置站点的页脚
    menu_style = "accordion"  # 设置菜单折叠

xadmin.site.register(views.CommAdminView, GlobalSettings)

在adminx.py中注册model:home/adminx.px
from . import models
# 注册
xadmin.site.register(models.Banner)

修改app:home的名字:xadmin页面上的显示效果
# home/__init__.py
default_app_config = "home.apps.HomeConfig"

# home/apps.py
from django.apps import AppConfig
class HomeConfig(AppConfig):
    name = 'home'
    verbose_name = '我的首页'

笔记巩固

知识点巩固

"""
1、jwt认证:三段式的格式、每一段的内容、由后台签发到前台存储再到传给后台校验的认证流水线
	头.载荷.签名:头、载荷(base64)| 签名(HS256)
	
				头:{基础信息:公司项目组等信息,加密方式}
				载荷:{核心信息:用户信息,过期时间}
				签名:{安全信息:头+载荷+秘钥的md5加密结果}
				
				服务器签发(login) -> web传给前端存储 -> 请求需要登录的结果再携带给后台 -> 服务器校验(认证组件) => 权限管理
				
				服务器压力小,集群部署更友善

2、drf-jwt插件:
	三个接口:签发token、校验token、刷新token
	自定义jwt插件的配置:在路由配置签发token的视图类接口、在全局或局部配置认证类
	
3、使用jwt插件完成多方式登录
	视图类:将请求数据交给序列化类完成校验,然后返回用户信息和token(从序列化对象中拿到)
	序列化类:自定义反序列化字段,全局钩子校验数据得到user和token,并保存在序列化类对象中
		token可以用jwt插件的rest_framework_jwt.serializers中
			jwt_payload_handler,jwt_encode_handler
		完成签发

4、自定义频率类完成视图类的频率限制
	1)定义类继承SimpleRateThrottle,重写get_cache_key方法,设置scope类属性
	2)scope就是一个认证字符串,在配置文件中配置scope字符串对应的频率设置
	3)get_cache_key的返回值是字符串,该字符串是缓存访问次数的缓存key	
"""

"""
请求生命周期:as_view、dispatch
基础模块:请求、响应、解析、渲染、异常
核心模块:序列化、视图家族、三大认证、过滤
"""

"""
路飞项目

前后台项目创建 => 项目目录规范(项目管理)=> 前后台跨域交互 => 
	主页页面逻辑接口与展示 => 课程页 => 用户的登录注册 => 课程购买(支付模块) 
=> 项目上线(线上测试支付回调)

开发技术点:git、redis、celery、短信接口、支付宝支付、阿里云服务器
"""

总结

"""
1、项目准备:pip换源、项目虚拟环境

2、后台项目创建,项目目录重构,项目配置:环境变量、日志、异常、响应、数据库、媒体文件、国际化、前后台跨越、xadmin

3、前台项目创建,项目目录重构,项目配置:全局样式与设置、axios、vue-cookies、element-ui、bs+jq
	
4、后台创建用户模块user:自定义User表、配置User表、路由分发

5、前台自定义主页组件和页头、轮播图小组件

6、核心:后台重构、后台配置、数据库
"""

A作业(必做)

"""
1、整理今天所学知识点

2、建立前后台luffy项目:luffyapi、luffycity,并按照课堂要求完成前后台配置

3、打通前后台跨越交互,按照课堂内容完成主页设计
"""

B作业(选做)

"""
1、后台设计轮播图表,确定都要哪些字段(核心:一定要先自己设计一下,然后明天对比一下)
2、完善主页的前台设计,在后台设计一个Banner表,轮播图数据由后台提供给前台
"""

二、git

版本控制器

"""
完成 协同开发 项目,帮助程序员整合代码

软件:SVN 、 GIT

git:集群化、多分支
"""

git

简介

"""
什么是git:版本控制器 - 控制的对象是开发的项目代码
代码开发时间轴:需求1 > 版本库1 > 需求2 > 版本库2 > 版本库1 > 版本库2 
"""

git与svn比较

路飞学城之 luffy (2 )_第7张图片

路飞学城之 luffy (2 )_第8张图片

git的工作流程

路飞学城之 luffy (2 )_第9张图片

git分支管理

路飞学城之 luffy (2 )_第10张图片

git使用

安装

# 1.下载对应版本:https://git-scm.com/download
# 2.安装git:在选取安装路径的下一步选取 Use a TrueType font in all console windows 选项

基础命令

将已有的文件夹 - 初始化为git仓库
"""
>: cd 目标文件夹内部
>: git init
"""

在指定目录下 - 初始化git仓库
"""
>: cd 目标目录
>: git init 仓库名
"""

在仓库目录终端下 - 设置全局用户
"""
>: git config --global user.name '用户名'
>: git config --global user.email '用户邮箱'

注:在全局文件 C:\Users\用户文件夹\.gitconfig新建用户信息,在所有仓库下都可以使用
"""

在仓库目录终端下 - 设置局部用户
"""
>: git config user.name '用户名'
	-- 用户名
>: git config user.email '用户邮箱'
	-- 用户邮箱
	
注:在当前仓库下的config新建用户信息,只能在当前仓库下使用
注:一个仓库有局部用户,优先使用局部用户,没有配置再找全局用户
"""

查看仓库状态
"""
# 当仓库中有文件增加、删除、修改,都可以在仓库状态中查看
>: git status  
	-- 查看仓库状态
>: git status -s  
	-- 查看仓库状态的简约显示
"""

工作区操作
# 通过任何方式完成的文件删与改
# 空文件夹不会被git记录


撤销工作区操作:改、删
"""
>: git checkout .
	-- 撤销所有暂存区的提交
>: git checkout 文件名
	-- 撤销某一文件的暂存区提交
"""


工作区内容提交到暂存区
"""
>: git add .  
	-- 添加项目中所有文件
>: git add 文件名  
	-- 添加指定文件
"""


撤销暂存区提交:add的逆运算
"""
>: git reset HEAD .
	-- 撤销所有暂存区的提交
>: git reset 文件名
	-- 撤销某一文件的暂存区提交
"""


提交暂存区内容到版本库
# git commit -m "版本描述信息"


撤销版本库提交:commit的逆运算
"""
回滚暂存区已经提交到版本库的操作:
    查看历史版本:
        >: git log
        >: git reflog
    查看时间点之前|之后的日志:
        >: git log --after 2018-6-1
        >: git log --before 2018-6-1
        >: git reflog --after 2018-6-1
        >: git reflog --before 2018-6-1
    查看指定开发者日志
        >: git log --author author_name
        >: git reflog --author author_name
    回滚到指定版本:
        回滚到上一个版本:
            >: git reset --hard HEAD^
            >: git reset --hard HEAD~
        回滚到上三个版本:
            >: git reset --hard HEAD^^^
            >: git reset --hard HEAD~3
        回滚到指定版本号的版本:
            >: git reset --hard 版本号
            >: eg: git reset --hard 35cb292
"""


过滤文件

# .gitignore 文件
# 1)在仓库根目录下创建该文件
# 2)文件与文件夹均可以被过滤
# 3)文件过滤语法

""" 过滤文件内容
文件或文件夹名:代表所有目录下的同名文件或文件夹都被过滤
/文件或文件夹名:代表仓库根目录下的文件或文件夹被过滤

eg:
a.txt:项目中所有a.txt文件和文件夹都会被过滤
/a.txt:项目中只有根目录下a.txt文件和文件夹会被过滤
/b/a.txt:项目中只有根目录下的b文件夹下的a.txt文件和文件夹会被过滤
*x*:名字中有一个x的都会被过滤(*代表0~n个任意字符)
空文件夹不会被提交,空包会被提交
"""


创建远程gitee仓库

选择线上仓库

"""
1.注册码云账号并登录:https://gitee.com/
2.创建仓库(课堂截图)
3.本地与服务器仓库建立连接
"""
"""
1)本地配置线上的账号与邮箱
>: git config --global user.name "doctor_owen"
>: git config --global user.email "[email protected]"

2)在本地初始化仓库(git init),并完成项目的初步搭建(项目架构)(一般都是项目负责人完成项目启动)
# 这个过程就是git的基础部分的本地操作

3)采用 https协议 或 ssh协议 与远程git仓库通信提交提交代码(一般都是项目负责人完成)
	i) https协议方式,无需配置,但是每次提交都有验证管理员账号密码
	>: git remote add origin https://gitee.com/doctor_owen/luffy.git  # 配置远程源
	>: git push -u origin master  # 提交本地仓库到远程源
	
	ii) ssh协议,需要配置,配置完成之后就可以正常提交代码
	>: git remote add origin [email protected]:doctor_owen/luffy.git  # 配置远程源
	>: git push -u origin master  # 提交本地仓库到远程源
	
	iii)查看源及源链接信息
	>: git remote
	>: git remote -v
	
	iv)删除源链接
	>: git remote remove 源名字 
	
注:origin远程源的源名,可以自定义;master是分支名,是默认的主分支
"""


路飞学城之 luffy (2 )_第11张图片

用本地仓库首次初始化远程仓库

本地仓库与远程仓库建立源连接
前提:本地仓库已经创建且初始化完毕(代码已经提交到本地版本库)

本机命令,添加远程源:git remote add origin ssh@*.git
	采用ssh协议的remote源


创建电脑的公钥私钥
官网:https://gitee.com/help/articles/4181#article-header0

本机命令,生成公钥:ssh-keygen -t rsa -C "*@*.com"
	邮箱可以任意填写
本机命令,查看公钥:cat ~/.ssh/id_rsa.pub

码云线上添加公钥:项目仓库 => 管理 => 部署公钥管理 => 添加公钥 => 添加个人公钥


提交本地代码到远程仓库
命令:git push origin master


路飞学城之 luffy (2 )_第12张图片

remote源操作

"""
1)查看仓库已配置的远程源
>: git remote
>: git remote -v

2)查看remote命令帮助文档
>: git remote -h

3)删除远程源
>: git remote remove 源名
eg: git remote remove origin

4)添加远程源
>: git remote add 源名 源地址
>: git remote add orgin git@*.git
"""


多分支开发

分支操作
"""
1.创建分支
>: git branch 分支名

2.查看分支
>: git branch

3.切换分支
>: git checkout 分支名

4.创建并切换到分支
>: git checkout -b 分支名

5.删除分支
>: git branch -d 分支名

6.查看远程分支
>: git branch -a

7.合并分支
>: git merge 分支名
"""


线上分支合并

路飞学城之 luffy (2 )_第13张图片

安装

路飞学城之 luffy (2 )_第14张图片

知识点复习与归纳

知识复习

"""
1、项目准备:pip换源、项目虚拟环境

2、后台项目创建,项目目录重构,项目配置:环境变量、日志、异常、响应、数据库、媒体文件、国际化、前后台跨越、xadmin
	环境变量:多app开发,将所有app放在apps中进行管理,所有apps文件夹要添加到环境变量 => app可以直接用名字注册
	import logging   logging.getLogger('django')
	用户权限,只能给开发者提供本项目操作权限(及以下)的账户

3、前台项目创建,项目目录重构,项目配置:全局样式与设置、axios、vue-cookies、element-ui、bs+jq
	
4、后台创建用户模块user:自定义User表、配置User表、路由分发

5、前台自定义主页组件和页头、轮播图小组件

6、核心:后台重构、后台配置、数据库
"""

版本控制器:SVN、GIT

"""
版本控制器:操作开发阶段代码版本迭代的工具
为什么要用版本控制器:
	代码不同阶段需求完成,该代码的时间节点应该被保留
	项目一般都是进行团队开发,版本控制器可以帮助自动整合代码
	问题:只能整合代码,但是不能避免冲突 => 冲突解决
	
使用:安装 => 本地使用(基础命令) => 线上使用(团队开发) => 冲突解决
"""

知识点总结

"""
1、前台导航组件完成各页面跳转

2、前后台主页轮播图接口实现

3、版本控制器:GIT vs SVN(GIT的优势)
	
4、git本地基本操作:初始化仓库、状态查看、工作区 暂存区 版本库基本操作、git仓库过滤文件

5、线上仓库的创建与连接:源操作

6、团队开发、版本冲突解决
"""

A作业(必做)

"""
1、整理今天所学知识点

2、完成luffy导航栏的封装、主页轮播图表的设计与接口的设计

3、安装git、属性git的基本操作、线上操作、团队开发、冲突解决
"""

B作业(选做)

"""
1、安装文档测试git如何操作分支,完成多分支开发
2、根据菜鸟教育学校redis数据库
"""

三、页面设计

登录页面设计

路飞学城之 luffy (2 )_第15张图片

注册页面设计

路飞学城之 luffy (2 )_第16张图片

知识点回顾与归纳

日考

1.核心关键字:版本管理器、集群部署、多分支
操作开发阶段代码版本迭代的工具,每个git应用都可以作为客户端或服务端,可以拥有多分支

2.
git status 查看状态
git init 初始化仓库
git add . 添加所有文件到暂存区
git commit -m '' 暂存区信息完成提交到版本库
git remote add 源名 地址 添加仓库源

3.
同时开发相同文件
一个开发者先提交给服务器,第二个开发者拉取代码时,如果出现同一文件同一位置会出现冲突
冲突需要开发者们线下沟通解决,保证所有开发者开发进度正常进行

知识点总结

"""
1、git实际开发版本冲突解决:
	更新代码到本地版本库 => 拉远程 => 出现冲突 => 解决冲突并更新本地版本库 => 拉远程
		如果还出现冲突,就重复上方过程
		如果成功,就提交代码到远程仓库

2、分支管理(branch):创建分支、切换分支、删除分支、合并分支(线上线下)
	注:各个分支相互独立

3、多方式登录的接口
	
4、手机号注册验证接口

5、短信服务的开通与代码的二次封装

6、发送短信接口
"""

A作业(必做)

"""
1、整理今天所学知识点

2、熟练掌握git的线上线下所有操作,熟知git团队开发,解决合并冲突

3、开通个人短信服务账号,完成短信功能的二次封装

4、完成多方式登录、手机号验证、发送验证码接口

5、完成短信验证码登录、短信验证码注册接口(一定认真用序列化类完成,有对比学习才有质的改变)
"""

B作业(选做)

"""
1、完成前台登录页面(多方式登录与短信登录)、注册页面
2、并方式前后台登录注册页面逻辑的交互、
3、根据10期预习视频学习redis数据库,在django中配置redis缓存数据库,存储短信验证码

4、预习接口缓存与celery异步任务框架
"""

总结

"""
1、git实际开发版本冲突解决:
	更新代码到本地版本库 => 拉远程 => 出现冲突 => 解决冲突并更新本地版本库 => 拉远程
		如果还出现冲突,就重复上方过程
		如果成功,就提交代码到远程仓库

2、分支管理(branch):创建分支、切换分支、删除分支、合并分支(线上线下)
	注:各个分支相互独立

3、多方式登录的接口:username可以携带不同信息,后台校验信息格式匹配登录方式
	
4、手机号注册验证接口:提供手机、手机数据库验证

5、短信服务的开通与代码的二次封装:腾讯云短信服务、将配置与发送短信的函数封装成包

6、发送短信接口:手机号换验证码 - 自己的后台产生验证码,交给第三方发送,后台缓存验证码,返回前台发送成功信息
"""

四、导航模态登录注册

前提:基于element-ui环境

模态登录组件







模态注册组件







导航条:结合实际情况完成样式







知识点归纳

知识点总结

"""
1、手机验证码登录接口

2、手机验证码注册接口

3、登录注册模态页面布局
	
4、登录注册5个接口前后台交互

5、前台登录状态cookies缓存已经用户注销

6、接口缓存
"""

A作业(必做)

"""
1、整理今天所学知识点

2、完成后台登录请求的5个接口

3、依照课件,完成前台登录注册页面的布局(Header组件可以参考项目代码)

4、完成前台登录、注册、注销业务

5、掌握并完成接口缓存

6、安装并学习redis数据库,掌握redis数据库操作字符串的方法
"""

B作业(选做)

"""
1、预习redis数据库操作五大数据类型,已经django中如何使用redis数据库

2、搞清楚celery框架的概念(celery是怎么工作的,解决什么问题的),建一个celery测试的demo项目,跑一下celery
"""

五、celery和redis操作

Celery

官方

Celery 官网:http://www.celeryproject.org/

Celery 官方文档英文版:http://docs.celeryproject.org/en/latest/index.html

Celery 官方文档中文版:http://docs.jinkan.org/docs/celery/

Celery架构

Celery的架构由三部分组成,消息中间件(message broker)、任务执行单元(worker)和 任务执行结果存储(task result store)组成。

路飞学城之 luffy (2 )_第17张图片

消息中间件

Celery本身不提供消息服务,但是可以方便的和第三方提供的消息中间件集成。包括,RabbitMQ, Redis等等

任务执行单元

Worker是Celery提供的任务执行的单元,worker并发的运行在分布式的系统节点中。

任务结果存储

Task result store用来存储Worker执行的任务的结果,Celery支持以不同方式存储任务的结果,包括AMQP, redis等

使用场景

异步任务:将耗时操作任务提交给Celery去异步执行,比如发送短信/邮件、消息推送、音视频处理等等

定时任务:定时执行某件事情,比如每天数据统计

Celery的安装配置

pip install celery

消息中间件:RabbitMQ/Redis

app=Celery('任务名', broker='xxx', backend='xxx')

Celery执行异步任务

包架构封装

project
    ├── celery_task  	# celery包
    │   ├── __init__.py # 包文件
    │   ├── celery.py   # celery连接和配置相关文件,且名字必须交celery.py
    │   └── tasks.py    # 所有任务函数
    ├── add_task.py  	# 添加任务
    └── get_result.py   # 获取结果

基本使用

celery.py
# 1)创建app + 任务

# 2)启动celery(app)服务:
# 非windows
# 命令:celery worker -A celery_task -l info
# windows:
# pip3 install eventlet
# celery worker -A celery_task -l info -P eventlet

# 3)添加任务:手动添加,要自定义添加任务的脚本,右键执行脚本

# 4)获取结果:手动获取,要自定义获取任务的脚本,右键执行脚本


from celery import Celery

broker = 'redis://127.0.0.1:6379/1'
backend = 'redis://127.0.0.1:6379/2'
app = Celery(broker=broker, backend=backend, include=['celery_task.tasks'])

tasks.py
from .celery import app
import time
@app.task
def add(n, m):
    print(n)
    print(m)
    time.sleep(10)
    print('n+m的结果:%s' % (n + m))
    return n + m

@app.task
def low(n, m):
    print(n)
    print(m)
    print('n-m的结果:%s' % (n - m))
    return n - m

add_task.py
from celery_task import tasks

# 添加立即执行任务
t1 = tasks.add.delay(10, 20)
t2 = tasks.low.delay(100, 50)
print(t1.id)


# 添加延迟任务
from datetime import datetime, timedelta
def eta_second(second):
    ctime = datetime.now()
    utc_ctime = datetime.utcfromtimestamp(ctime.timestamp())
    time_delay = timedelta(seconds=second)
    return utc_ctime + time_delay

tasks.low.apply_async(args=(200, 50), eta=eta_second(10))

get_result.py
from celery_task.celery import app

from celery.result import AsyncResult

id = '21325a40-9d32-44b5-a701-9a31cc3c74b5'
if __name__ == '__main__':
    async = AsyncResult(id=id, app=app)
    if async.successful():
        result = async.get()
        print(result)
    elif async.failed():
        print('任务失败')
    elif async.status == 'PENDING':
        print('任务等待中被执行')
    elif async.status == 'RETRY':
        print('任务异常后正在重试')
    elif async.status == 'STARTED':
        print('任务已经开始被执行')

高级使用

celery.py
# 1)创建app + 任务

# 2)启动celery(app)服务:
# 非windows
# 命令:celery worker -A celery_task -l info
# windows:
# pip3 install eventlet
# celery worker -A celery_task -l info -P eventlet

# 3)添加任务:自动添加任务,所以要启动一个添加任务的服务
# 命令:celery beat -A celery_task -l info

# 4)获取结果


from celery import Celery

broker = 'redis://127.0.0.1:6379/1'
backend = 'redis://127.0.0.1:6379/2'
app = Celery(broker=broker, backend=backend, include=['celery_task.tasks'])


# 时区
app.conf.timezone = 'Asia/Shanghai'
# 是否使用UTC
app.conf.enable_utc = False

# 任务的定时配置
from datetime import timedelta
from celery.schedules import crontab
app.conf.beat_schedule = {
    'low-task': {
        'task': 'celery_task.tasks.low',
        'schedule': timedelta(seconds=3),
        # 'schedule': crontab(hour=8, day_of_week=1),  # 每周一早八点
        'args': (300, 150),
    }
}

tasks.py
from .celery import app

import time
@app.task
def add(n, m):
    print(n)
    print(m)
    time.sleep(10)
    print('n+m的结果:%s' % (n + m))
    return n + m


@app.task
def low(n, m):
    print(n)
    print(m)
    print('n-m的结果:%s' % (n - m))
    return n - m

get_result.py
from celery_task.celery import app

from celery.result import AsyncResult

id = '21325a40-9d32-44b5-a701-9a31cc3c74b5'
if __name__ == '__main__':
    async = AsyncResult(id=id, app=app)
    if async.successful():
        result = async.get()
        print(result)
    elif async.failed():
        print('任务失败')
    elif async.status == 'PENDING':
        print('任务等待中被执行')
    elif async.status == 'RETRY':
        print('任务异常后正在重试')
    elif async.status == 'STARTED':
        print('任务已经开始被执行')

django中使用

celery.py
# 重点:要将 项目名.settings 所占的文件夹添加到环境变量
# import sys
# sys.path.append(r'项目绝对路径')

# 开启django支持
import os
os.environ.setdefault('DJANGO_SETTINGS_MODULE', '项目名.settings')
import django
django.setup()



# 1)创建app + 任务

# 2)启动celery(app)服务:
# 非windows
# 命令:celery worker -A celery_task -l info
# windows:
# pip3 install eventlet
# celery worker -A celery_task -l info -P eventlet

# 3)添加任务:自动添加任务,所以要启动一个添加任务的服务
# 命令:celery beat -A celery_task -l info

# 4)获取结果


from celery import Celery

broker = 'redis://127.0.0.1:6379/1'
backend = 'redis://127.0.0.1:6379/2'
app = Celery(broker=broker, backend=backend, include=['celery_task.tasks'])


# 时区
app.conf.timezone = 'Asia/Shanghai'
# 是否使用UTC
app.conf.enable_utc = False

# 任务的定时配置
from datetime import timedelta
from celery.schedules import crontab
app.conf.beat_schedule = {
    'django-task': {
        'task': 'celery_task.tasks.test_django_celery',
        'schedule': timedelta(seconds=3),
        'args': (),
    }
}


tasks.py
from .celery import app
# 获取项目中的模型类
from api.models import Banner
@app.task
def test_django_celery():
    banner_query = Banner.objects.filter(is_delete=False).all()
    print(banner_query)


redis操作

redis VS mysql
"""
redis: 内存数据库(读写快)、非关系型(操作数据方便)
mysql: 硬盘数据库(数据持久化)、关系型(操作数据间关系)

大量访问的临时数据,才有redis数据库更优
"""

redis VS memcache
"""
redis: 操作字符串、列表、字典、无序集合、有序集合 | 支持数据持久化(数据丢失可以找回、可以将数据同步给mysql) | 高并发支持
memcache: 操作字符串 | 不支持数据持久化 | 并发量小
"""

Redis操作
"""
基础操作:
	启动服务:redis-server &
	连接数据库:redis-cli
    连接指定数据库:redis-cli -h 127.0.0.1 -p 6379 -n 1
    切换数据库:select 1

数据操作:字符串、列表、字典、无序集合、有序(排序)集合
	有序集合:游戏排行榜
	
"""

redis数据库

# 1.安装redis与可视化操作工具

# 2.在服务中管理redis服务器的开启关闭

# 3.命令行简单使用redis:
	-- redis-cli  # 启动客户端
    -- set key value  # 设置值
    -- get key  # 取出值
    
# 4.redis支持:字符串、字典、列表、集合、有序集合
# https://www.runoob.com/redis/redis-tutorial.html

# 5.特点:可持久化、单线程单进程并发

python使用redis

依赖
>: pip3 install redis

直接使用
import redis
r = redis.Redis(host='127.0.0.1', port=6379, db=1)

连接池使用
import redis
pool = redis.ConnectionPool(host='127.0.0.1', port=6379, db=10, max_connections=100)
r = redis.Redis(connection_pool=pool)

缓存使用:要额外安装 django-redis
# 1.将缓存存储位置配置到redis中:settings.py
CACHES = {
    "default": {
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": "redis://127.0.0.1:6379",
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
            "CONNECTION_POOL_KWARGS": {"max_connections": 100}
        }
    }
}

# 2.操作cache模块直接操作缓存:views.py
from django.core.cache import cache  # 结合配置文件实现插拔式
# 存放token,可以直接设置过期时间
cache.set('token', 'header.payload.signature', 10)
# 取出token
token = cache.get('token')

知识点归纳与练习

日考

"""
序列化:
	Serializer: 自己声明序列化反序列化字段、自定义钩子校验规则、重写create、update方法完成入库
	ModelSerializer:model绑定、fields字段(extra_kwargs)、自定义钩子校验规则、继承create、update
	ListSerializer:提供群增群改(必须重写update)、在ModelSerializer中设置list_rerializer_class进行关联

认证组件:
	校验前台携带的认证信息:没有,返回None(游客) | 认证失败,抛异常(非法用户403) | 认证成功,返回(user, token)
	
视图基类:
	APIView:继承View|as_view局部禁用csrf|dispatch封装request、三大认证、响应模块|类属性完成局部配置
	GenericAPIView:继承APIView|三个属性三个方法
"""

知识点总结

"""
1、redis数据库:优势、基础使用、五种数据类型的操作

2、redis数据库在Python中的使用、Django中的使用

3、celery异步任务框架:
	celery(broker、backend、tasks)封装配置、
	添加 立即任务、延迟任务、周期任务(自动添加)
	worker服务的启动命令:celery worker -A celery_task -l info -P eventlet
		worker服务是用来执行任务的服务器
	beat服务的启动命令:celery beat -A celery_task -l info
		beat服务是用来自动添加app.conf.beat_schedule配置中配置的任务的
"""

A作业(必做)

"""
1、整理今天所学知识点

2、将项目的缓存配置成redis数据库,来关联缓存

3、利用celery框架完成异步定时更新轮播图接口缓存
"""

B作业(选做)

"""
1、将发生短信接口,改写为让celery来管理

2、工具路飞官网,设计课程业务相关表
"""

六、

1.课程页页面

课程组件









2.修订课程主页

路飞学城之 luffy (2 )_第18张图片

3.课程详情页

1.详情页前台

详情页组件

依赖:在luffycity目录下的命令
>: cnpm install vue-video-player

配置:main.js
// vue-video播放器
require('video.js/dist/video-js.css');
require('vue-video-player/src/custom-theme.css');
import VideoPlayer from 'vue-video-player'
Vue.use(VideoPlayer);

资源:图片放置assrts/img文件夹
"""
enum.svg
chapter-player.svg
cart-yellow.svg
"""

路由:router.js
import CourseDetail from './views/CourseDetail.vue'
export default new Router({
    routes: [
        // ...
        {
            path: '/course/detail/:pk',
            name: 'course-detail',
            component: CourseDetail
        }
    ]
}

组件






2.详情页后台

详情页后台

路由:source/urls.py
re_path("(?P\d+)/", views.CourseRetrieveAPIView.as_view()),
path("chapters/", views.CourseChapterListAPIView.as_view()),

视图:source/views.py
from .models import Course
from .models import CourseChapter
from rest_framework.generics import ListAPIView
from rest_framework.generics import RetrieveAPIView
from . import serializers
from django_filters.rest_framework.backends import DjangoFilterBackend

class CourseRetrieveAPIView(RetrieveAPIView):
    """课程详情信息"""
    queryset = Course.objects.filter(is_delete=False, is_show=True)
    serializer_class = serializers.CourseRetrieveModelSSerializer

class CourseChapterListAPIView(ListAPIView):
    """课程详情信息"""
    queryset = CourseChapter.objects.filter(is_delete=False, is_show=True).order_by("chapter")
    serializer_class = serializers.CourseChapterModelSerializer
    filter_backends = [DjangoFilterBackend]
    filter_fields = ['course', ]

序列化:source/serializers.py
from . import models
from rest_framework.serializers import ModelSerializer
class CourseRetrieveModelSSerializer(ModelSerializer):
    # 课程详情的序列化器
    teacher = TeacherSerializer()
    class Meta:
        model = models.Course
        fields = ["id", "name", "course_img", "students", "sections", "pub_sections", "price", "teacher", "level_name"]

class CourseSessionModelSerializer(ModelSerializer):
    class Meta:
        model = models.CourseSection
        fields = ["id", "name", "duration", "free_trail", "orders"]

class CourseChapterModelSerializer(ModelSerializer):
    coursesections = CourseSessionModelSerializer(many=True)

    class Meta:
        model = models.CourseChapter
        fields = ["chapter", "name", "summary", "coursesections"]

视图字段:source/model.py
class Course(BaseModel):
    # ...
    @property
    def level_name(self):
        # 难度名
        return self.level_choices[self.level][1]

运用图片

路飞学城之 luffy (2 )_第19张图片
路飞学城之 luffy (2 )_第20张图片
路飞学城之 luffy (2 )_第21张图片

支付

支付宝支付

# 1、在沙箱环境下实名认证:https://openhome.alipay.com/platform/appDaily.htm?tab=info

# 2、电脑网站支付API:https://docs.open.alipay.com/270/105898/

# 3、完成RSA密钥生成:https://docs.open.alipay.com/291/105971

# 4、在开发中心的沙箱应用下设置应用公钥:填入生成的公钥文件中的内容

# 5、Python支付宝开源框架:https://github.com/fzlee/alipay
# >: pip install python-alipay-sdk --upgrade

# 7、公钥私钥设置
"""
# alipay_public_key.pem
-----BEGIN PUBLIC KEY-----
支付宝公钥
-----END PUBLIC KEY-----

# app_private_key.pem
-----BEGIN RSA PRIVATE KEY-----
用户私钥
-----END RSA PRIVATE KEY-----
"""

# 8、支付宝链接
"""
开发:https://openapi.alipay.com/gateway.do
沙箱:https://openapi.alipaydev.com/gateway.do
"""

支付流程

路飞学城之 luffy (2 )_第22张图片

aliapy二次封装包

依赖
>: pip install python-alipay-sdk --upgrade

结构
libs
    ├── iPay  							# aliapy二次封装包
    │   ├── __init__.py 				# 包文件
    │   ├── keys						# 密钥文件夹
    │   │   ├── alipay_public_key.pem  	# 支付宝公钥
    │   │   └── app_private_key.pem  	# 应用私钥
    └── └── settings.py  				# 应用配置  

setting.py
import os
# 支付宝应用id
APP_ID = '2016093000631831'
# 默认异步回调的地址,通常设置None就行
APP_NOTIFY_URL = None
# 应用私钥文件路径
APP_PRIVATE_KEY_PATH = os.path.join(os.path.dirname(__file__), 'keys', 'app_private_key.pem')
# 支付宝公钥文件路径
ALIPAY_PUBLIC_KEY_PATH = os.path.join(os.path.dirname(__file__), 'keys', 'alipay_public_key.pem')
# 签名方式
SIGN_TYPE = 'RSA2'
# 是否是测试环境
DEBUG = True

_init_.py
from alipay import AliPay
from .settings import *
# 对外提供
from .settings import RETURN_URL, NOTIFY_URL
# 对外提供支付对象
alipay = AliPay(
    appid=APP_ID,
    app_notify_url=APP_NOTIFY_URL,
    app_private_key_path=APP_PRIVATE_KEY_PATH,
    alipay_public_key_path=ALIPAY_PUBLIC_KEY_PATH,
    sign_type=SIGN_TYPE,
    debug=DEBUG
)

alipay_public_key.pem
-----BEGIN PUBLIC KEY-----
支付宝公钥
-----END PUBLIC KEY-----

app_private_key.pem
-----BEGIN RSA PRIVATE KEY-----
应用私钥
-----END RSA PRIVATE KEY-----

补充:dev.py
# 上线后必须换成官网地址
# 同步回调的接口(get),前后台分离时一般设置前台页面url
RETURN_URL = 'http://127.0.0.1:8080/pay/success'
# 异步回调的接口(post),一定设置为后台服务器接口
NOTIFY_URL = 'http://127.0.0.1:8000/order/success/'

支付模块

order/models.py
"""
订单:订单号、流水号、价格、用户
订单详情(自定义关系表):订单、课程
"""

from django.db import models
from utils.model import BaseModel
from user.models import User
from course.models import Course


class Order(BaseModel):
    """订单模型"""
    status_choices = (
        (0, '未支付'),
        (1, '已支付'),
        (2, '已取消'),
        (3, '超时取消'),
    )
    pay_choices = (
        (1, '支付宝'),
        (2, '微信支付'),
    )
    subject = models.CharField(max_length=150, verbose_name="订单标题")
    total_amount = models.DecimalField(max_digits=10, decimal_places=2, verbose_name="订单总价", default=0)
    out_trade_no = models.CharField(max_length=64, verbose_name="订单号", unique=True)
    trade_no = models.CharField(max_length=64, null=True, verbose_name="流水号")
    order_status = models.SmallIntegerField(choices=status_choices, default=0, verbose_name="订单状态")
    pay_type = models.SmallIntegerField(choices=pay_choices, default=1, verbose_name="支付方式")
    pay_time = models.DateTimeField(null=True, verbose_name="支付时间")
    user = models.ForeignKey(User, related_name='user_orders', on_delete=models.DO_NOTHING, db_constraint=False,
                             verbose_name="下单用户")

    # 多余字段
    orders = models.IntegerField(verbose_name='显示顺序', default=0)

    class Meta:
        db_table = "luffy_order"
        verbose_name = "订单记录"
        verbose_name_plural = "订单记录"

    def __str__(self):
        return "%s - ¥%s" % (self.subject, self.total_amount)

    @property
    def courses(self):
        data_list = []
        for item in self.order_courses.all():
            data_list.append({
                "id": item.id,
                "course_name": item.course.name,
                "real_price": item.real_price,
            })

        return data_list


class OrderDetail(BaseModel):
    """订单详情"""
    order = models.ForeignKey(Order, related_name='order_courses', on_delete=models.CASCADE, db_constraint=False,
                              verbose_name="订单")
    course = models.ForeignKey(Course, related_name='course_orders', on_delete=models.CASCADE, db_constraint=False,
                               verbose_name="课程")
    price = models.DecimalField(max_digits=6, decimal_places=2, verbose_name="课程原价")
    real_price = models.DecimalField(max_digits=6, decimal_places=2, verbose_name="课程实价")

    class Meta:
        db_table = "luffy_order_detail"
        verbose_name = "订单详情"
        verbose_name_plural = "订单详情"

    def __str__(self):
        return "%s订单(%s)" % (self.course.name, self.order.order_number)



后台接口

from django.urls import path
from . import views
urlpatterns = [
    path('pay/', views.PayAPIView.as_view()),
    path('success/', views.SuccessAPIView.as_view()),
]


订单序列化模块

from rest_framework import serializers
from . import models
class OrderModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Order
        fields = ('subject', 'total_amount', 'out_trade_no', 'pay_type', 'user')
        extra_kwargs = {
            'pay_type': {
                'required': True
            },
            'total_amount': {
                'required': True
            },
        }


支付接口生成支付链接

import time
from rest_framework.views import APIView
from utils.response import APIResponse
from libs.iPay import alipay
from . import authentications, serializers
from rest_framework.permissions import IsAuthenticated
from django.conf import settings
# 获取前台 商品名、价格,产生 订单、支付链接
class PayAPIView(APIView):
    authentication_classes = [authentications.JWTAuthentication]
    permission_classes = [IsAuthenticated]
    def post(self, request, *args, **kwargs):
        # 前台提供:商品名、总价、支付方式
        request_data = request.data
        # 后台产生:订单号、用户
        out_trade_no = '%d' % time.time() * 2
        request_data['out_trade_no'] = out_trade_no
        request_data['user'] = request.user.id

        # 反序列化数据,用于订单生成前的校验
        order_ser = serializers.OrderModelSerializer(data=request_data)
        if order_ser.is_valid():
            # 生成订单,订单默认状态为:未支付
            order = order_ser.save()
            # 支付链接的参数
            order_string = alipay.api_alipay_trade_page_pay(
                subject=order.subject,
                out_trade_no=order.out_trade_no,
                total_amount='%.2f' % order.total_amount,
                return_url=settings.RETURN_URL,
                notify_url=settings.NOTIFY_URL
            )
            # 形成支付链接:alipay._gateway根据字符环境DEBUG配置信息,决定是沙箱还是真实支付环境
            pay_url = '%s?%s' % (alipay._gateway, order_string)
            return APIResponse(0, 'ok', pay_url=pay_url)


        return APIResponse(1, 'no ok', results=order_ser.errors)


前台回调接口的页面

{
  	path: '/pay/success',
    name: 'pay-success',
    component: PaySuccess
},









支付完成订单校验的接口

from . import models
from utils.logging import logger
from rest_framework.response import Response
class SuccessAPIView(APIView):
    # 不能认证,别人支付宝异步回调就进不来了
    # authentication_classes = [authentications.JWTAuthentication]
    # permission_classes = [IsAuthenticated]
    def patch(self, request, *args, **kwargs):
        # 默认是QueryDict类型,不能使用pop方法
        request_data = request.query_params.dict()
        # 必须将 sign、sign_type(内部有安全处理) 从数据中取出,拿sign与剩下的数据进行校验
        sign = request_data.pop('sign')
        result = alipay.verify(request_data, sign)
        if result:  # 同步回调:修改订单状态
            try:
                out_trade_no = request_data.get('out_trade_no')
                order = models.Order.objects.get(out_trade_no=out_trade_no)
                if order.order_status != 1:
                    order.order_status = 1
                    order.save()
            except:
                pass
            return APIResponse(0, '支付成功')
        return APIResponse(1, '支付失败')

    # 支付宝异步回调
    def post(self, request, *args, **kwargs):
        # 默认是QueryDict类型,不能使用pop方法
        request_data = request.data.dict()
        # 必须将 sign、sign_type(内部有安全处理) 从数据中取出,拿sign与剩下的数据进行校验
        sign = request_data.pop('sign')
        result = alipay.verify(request_data, sign)
        # 异步回调:修改订单状态
        if result and request_data["trade_status"] in ("TRADE_SUCCESS", "TRADE_FINISHED" ):
            out_trade_no = request_data.get('out_trade_no')
            logger.critical('%s支付成功' % out_trade_no)
            try:
                order = models.Order.objects.get(out_trade_no=out_trade_no)
                if order.order_status != 1:
                    order.order_status = 1
                    order.save()
            except:
                pass
            # 支付宝八次异步通知,订单成功一定要返回 success
            return Response('success')
        return Response('failed')


上线

购买服务器

# 购买阿里云服务器
# 短期或是测试使用,创建 按量收费 服务器,可以随时删除,删除后不再计费,但要保证账户余额100元以上

连接服务器

1)账号
>: ssh [email protected]

2)密码
>: ********

服务器命令

管理员权限
1)以下所有的服务器命令均可以在管理员权限下执行
>: sudo 命令

配置终端
1)编辑配置文件
>: vim ~/.bash_profile

2)将原来内容全部删除掉
>: ggdG

3)进入编辑状态:填入下方两行
>: i

export PATH=$PATH:$HOME/bin
PS1='Path:\w\n>:'

4)退出编辑状态
>: esc

5)保存修改并退出
>: :wq

6)生效配置
>: source ~/.bash_profile

重要

更新系统软件包
>: yum update -y

安装软件管理包和可能使用的依赖
>: yum -y groupinstall "Development tools"
>: yum install openssl-devel bzip2-devel expat-devel gdbm-devel readline-devel sqlite-devel psmisc libffi-devel

安装Mysql

1)前往用户根目录
>: cd ~

2)下载mysql57
>: wget http://dev.mysql.com/get/mysql57-community-release-el7-10.noarch.rpm

也可以本地上传,这条命令要在本地终端上执行
>: scp -r C:\Users\dell\Desktop\pkg\mysql57-community-release-el7-10.noarch.rpm [email protected]:~

3)安装mysql57
>: yum -y install mysql57-community-release-el7-10.noarch.rpm
>: yum -y install mysql-community-server

4)启动mysql57并查看启动状态
>: systemctl start mysqld.service
>: systemctl status mysqld.service

5)查看默认密码并登录
>: grep "password" /var/log/mysqld.log
>: mysql -uroot -p

6)修改密码
>: ALTER USER 'root'@'localhost' IDENTIFIED BY 'new password';
>: ALTER USER 'root'@'localhost' IDENTIFIED BY 'Owen1234?';

安装Redis

1)前往用户根目录
>: cd ~

2)下载redis-5.0.5
>: wget http://download.redis.io/releases/redis-5.0.5.tar.gz
>: scp -r C:\Users\dell\Desktop\pkg\redis-5.0.5.tar.gz [email protected]:~

3)解压安装包
>: tar -xf redis-5.0.5.tar.gz

4)进入目标文件
>: cd redis-5.0.5

5)编译环境
>: make

6)复制环境到指定路径完成安装
>: cp -r ~/redis-5.0.5 /usr/local/redis

7)配置redis可以后台启动:修改下方内容
>: vim /usr/local/redis/redis.conf

daemonize yes

8)完成配置修改
>: esc
>: :wq

9)建立软连接
>: ln -s /usr/local/redis/src/redis-server /usr/bin/redis-server
>: ln -s /usr/local/redis/src/redis-cli /usr/bin/redis-cli

10)后台运行redis
>: redis-server &
ctrl + c

11)测试redis环境
>: redis-cli
ctrl + c

12)关闭redis服务
>: pkill -f redis -9

安装Python3.6

1)前往用户根目录
>: cd ~

2)下载 或 上传 Python3.6.7
>: wget https://www.python.org/ftp/python/3.6.7/Python-3.6.7.tar.xz
>: scp -r 本地Python-3.6.7.tar.xz ssh [email protected]:服务器路径
>: scp -r C:\Users\dell\Desktop\pkg\Python-3.6.7.tar.xz ssh [email protected]:~

3)解压安装包
>: tar -xf Python-3.6.7.tar.xz

4)进入目标文件
>: cd Python-3.6.7

5)配置安装路径:/usr/local/python3
>: ./configure --prefix=/usr/local/python3

6)编译并安装
>: make && sudo make install

7)建立软连接:终端命令 python3,pip3
>: ln -s /usr/local/python3/bin/python3.6 /usr/bin/python3
>: ln -s /usr/local/python3/bin/pip3.6 /usr/bin/pip3

8)删除安装包与文件:
>: rm -rf Python-3.6.7
>: rm -rf Python-3.6.7.tar.xz

配置pip源:阿里云不用配置,默认配置阿里源

1)创建pip配置路径
>: mkdir ~/.pip

2)进入目录编辑配置文件:填入下方内容
cd ~/.pip && vim pip.conf

[global]
index-url = http://pypi.douban.com/simple
[install]
use-mirrors =true
mirrors =http://pypi.douban.com/simple/
trusted-host =pypi.douban.com

安装uwsgi

1)在真实环境下安装
pip3 install uwsgi

2)建立软连接
ln -s /usr/local/python3/bin/uwsgi /usr/bin/uwsgi

安装虚拟环境

1)安装依赖
>: pip3 install virtualenv
>: pip3 install virtualenvwrapper

2)建立虚拟环境软连接
>: ln -s /usr/local/python3/bin/virtualenv /usr/bin/virtualenv

3)配置虚拟环境:填入下方内容
>: vim ~/.bash_profile

VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3
source /usr/local/python3/bin/virtualenvwrapper.sh

4)退出编辑状态
>: esc

5)保存修改并退出
>: :wq

6)更新配置文件内容
>: source ~/.bash_profile

7)虚拟环境默认根目录:~/.virtualenvs

服务器运行测试Django项目

1)创建虚拟环境
>: mkvirtualenv test_venv

2)安装依赖
>: pip install django

3)前往目标目录,创建项目工作目录,再进入
>: cd /home
>: mkdir project
>: cd project

4)创建Django项目,并进入
>: django-admin startproject test_site
>: cd test_site

5)完成项目配置:修改下方几行内容
>: vim /home/project/test_site/test_site/settings.py

ALLOWED_HOSTS = ['*']
#DATABASES = {
#    'default': {
#        'ENGINE': 'django.db.backends.sqlite3',
#        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
#    }
#}

6)跑原生服务
>: python3 manage.py runserver 0.0.0.0:80

安装Nginx

1)前往用户根目录
>: cd ~

2)下载nginx1.13.7
>: wget http://nginx.org/download/nginx-1.13.7.tar.gz

3)解压安装包
>: tar -xf nginx-1.13.7.tar.gz

4)进入目标文件
>: cd nginx-1.13.7

5)配置安装路径:/usr/local/nginx
>: ./configure --prefix=/usr/local/nginx

6)编译并安装
>: make && sudo make install

7)建立软连接:终端命令 nginx
>: ln -s /usr/local/nginx/sbin/nginx /usr/bin/nginx

8)删除安装包与文件:
>: rm -rf nginx-1.13.7
>: rm -rf nginx-1.13.7.tar.xz

9)测试Nginx环境,服务器运行nginx,本地访问服务器ip
>: nginx
>: 服务器绑定的域名 或 ip:80

Nginx命令

1)启动
>: nginx

2)关闭nginx
>: nginx -s stop

3)重启nginx
>: nginx -s reload

4)查看端口,强行关闭
>: ps -aux|grep nginx
>: kill 

Nginx & uwsgi 运行Django

1)在项目的虚拟环境安装uwsgi
>: workon test_venv
>: pip install uwsgi

2)项目根目录配置uwsgi:填入下方内容
>: vim /home/project/test_site/test_site.xml

    
   127.0.0.1:8808  
   /home/project/test_site/             
   test_site.wsgi   
   4      
   uwsgi.log 


3)完成项目配置:修改下方几行内容
>: vim /home/project/test_site/test_site/settings.py

DEBUG = False
ALLOWED_HOSTS = ['*']

4)去向Nginx配置目录,备份配置,完全更新配置:填入下方内容
>: cd /usr/local/nginx/conf
>: cp nginx.conf nginx.conf.bak
>: vim nginx.conf
>: ggdG
>: i

events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    server {
        listen 8000;
        server_name  127.0.0.1; # 改为自己的域名,没域名修改为127.0.0.1:80
        charset utf-8;
        location / {
           include uwsgi_params;
           uwsgi_pass 127.0.0.1:8808;  # 端口要和uwsgi里配置的一样
           uwsgi_param UWSGI_SCRIPT test_site.wsgi;  #wsgi.py所在的目录名+.wsgi
           uwsgi_param UWSGI_CHDIR /home/project/test_site/; # 项目路径
        }
    }
}

5)启动uwsgi
>: uwsgi -x /home/project/test_site/test_site.xml

6)启动nginx
>: nginx

7)浏览器测试:http://39.98.144.221/admin

8)关闭uwsgi所有进程
>: pkill -f uwsgi -9

路飞项目部署:Nginx + uwsgi + django + vue

配置前台项目

上线前配置

settings.js
base_url: 'http://39.98.144.221:8000',  // 设置公网ip

上线

1)本地项目打包,前往luffycity项目目录下
>: cnpm run build

2)上传
>: scp -r dist [email protected]:~

3)移动并重命名
mv ~/dist /home/html

4)去向Nginx配置目录,备份配置,完全更新配置:填入下方内容
>: cd /usr/local/nginx/conf
>: cp nginx.conf nginx.conf.bak
>: vim nginx.conf
>: ggdG
>: i

events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    server {
        listen 80;
        server_name  127.0.0.1; # 改为自己的域名,没域名修改为127.0.0.1:80
        charset utf-8;
        location / {
            root /home/html; # html访问路径
            index index.html; # html文件名称
            try_files $uri $uri/ /index.html; # 解决单页面应用刷新404问题
        }
    }
}                                                                   

路飞后台部署

上线前配置

prod.py:上线的配置文件,内容拷贝dev.py,前身就是settings.py

1)需要做上线修改的内容
DEBUG = False
ALLOWED_HOSTS = [
    '39.98.144.221'  # 公网ip地址
]

CORS_ORIGIN_ALLOW_ALL = True  # 允许所有跨域
CORS_ORIGIN_WHITELIST = [
]

wsgi.py 和 manage.py

1)需要做上线修改的内容
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'luffyapi.settings.prod')

上线

1)在项目的虚拟环境安装uwsgi
>: mkvirtualenv luffy
>: workon luffy
# 走下方 pip导入导出依赖 说明,将本地的环境依赖同步到服务器环境中
>: pip install uwsgi

2)项目根目录配置uwsgi:填入下方内容
>: mkdir /home/project

# 注:将后台项目移至到/home/project,可以上传,也可以git,项目设置公开(私密需要配置ssl)
>: cd /home/project && git clone https://gitee.com/doctor_owen/luffyapi.git 
>: vim /home/project/luffyapi/luffyapi.xml

    
   127.0.0.1:8808  
   /home/project/luffyapi/             
   luffyapi.wsgi   
   4      
   uwsgi.log 


####  3)配置上线项目的settings:见后台项目部署准备视频

4)去向Nginx配置目录,备份配置,完全更新配置:填入下方内容
>: vim /usr/local/nginx/conf/nginx.conf

5)在原来基础上添加一个server
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    server {
        listen 8000;
        server_name  127.0.0.1; # 改为自己的域名,没域名修改为127.0.0.1:80
        charset utf-8;
        location / {
           include uwsgi_params;
           uwsgi_pass 127.0.0.1:8808;  # 端口要和uwsgi里配置的一样
           uwsgi_param UWSGI_SCRIPT luffyapi.wsgi;  #wsgi.py所在的目录名+.wsgi
           uwsgi_param UWSGI_CHDIR /home/project/luffyapi/; # 项目路径
        }
    }
}

见下方配置:pip环境 + 数据库设置 + django2.0源码

5)启动uwsgi
>: uwsgi -x /home/project/luffyapi/luffyapi.xml

6)启动nginx
>: nginx -s stop
>: nginx
>: nginx -s reload

7)浏览器测试:http://39.98.144.221:8000/xadmin

8)关闭uwsgi所有进程
>: pkill -f uwsgi -9

pip导入导出依赖

1) 本地导出项目环境,上传线上,导入到线上环境中

本地操作
# 桌面新建env文件夹,开启终端进入文件夹,执行下方命名
>: cd Desktop\env
>: pip3 freeze > packages.txt
# 注:把xadmin删掉
>: scp -r packages.txt [email protected]:~

服务器操作
# 进入虚拟环境
>: workon luffy
# 导入
>: pip3 install -r packages.txt
# 安装xadmin
>: pip install https://codeload.github.com/sshwsfc/xadmin/zip/django2

数据库设置 + django2.0源码(2.0.7不用修改源码)

1.管理员连接数据库
>: mysql -uroot -pOwen1234?

2.创建数据库
>: create database luffy default charset=utf8;

# 3.设置权限账号密码
# 拥有公网或局域网,其他主机连mysql
>: grant all privileges on luffy.* to 'luffy'@'%' identified by 'Luffy123?';
# 要是本机连mysql连不上,再增加localhost域,本机就可以登录了
>: grant all privileges on luffy.* to 'luffy'@'localhost' identified by 'Luffy123?';
# 设置完有权限限制的账号后一定要刷新权限
>: flush privileges;

4.退出mysql
quit

5.修改 prod.py | manage.py
>: vim /home/project/luffyapi/luffyapi/settings/prod.py

"PASSWORD": "Luffy123?"

>: vim /home/project/luffyapi/manage.py

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'luffyapi.settings.prod')

6.源码修改
>: vim /root/.virtualenvs/luffy/lib/python3.6/site-packages/django/db/backends/mysql/base.py

# 36,37行注释

>: vim /root/.virtualenvs/luffy/lib/python3.6/site-packages/django/db/backends/mysql/operations.py

# 146行添加
	query = query.encode()

7.数据库迁移
>: cd /home/project/luffyapi/
>: python manage.py makemigrations
>: python manage.py migrate

8.创建超级用户
>: python manage.py createsuperuser
# 账号密码:admin|admin

后台样式问题

设置文件中配置STATIC_ROOT
# >: vim /home/project/luffyapi/luffyapi/settings/prod.py
# 在STATIC_URL下方再添加两句
STATIC_URL = '/static/'
STATIC_ROOT = '/home/project/luffyapi/luffyapi/static'  # 服务器的绝对路径
STATICFILES_DIRS = (os.path.join(BASE_DIR, "static"),)
# >: esc
# >: :wq

迁移静态样式:项目目录下
可能错误
>: mkdir /home/project/luffyapi/luffyapi/static
>: python /home/project/luffyapi/manage.py collectstatic

Nginx配置静态路径
>: vim /usr/local/nginx/conf/nginx.conf

events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    server {
        listen 8000;
        server_name  127.0.0.1; # 改为自己的域名,没域名修改为127.0.0.1:80
        charset utf-8;
        location / {
           include uwsgi_params;
           uwsgi_pass 127.0.0.1:8808;  # 端口要和uwsgi里配置的一样
           uwsgi_param UWSGI_SCRIPT luffyapi.wsgi;  #wsgi.py所在的目录名+.wsgi
           uwsgi_param UWSGI_CHDIR /home/project/luffyapi/; # 项目路径
        }
        # 新增的配置静态文件
        location /static {
            alias /home/project/luffyapi/luffyapi/static;
        }
    }
    server {
        listen 80;
        server_name  127.0.0.1; # 改为自己的域名,没域名修改为127.0.0.1:80
        charset utf-8;
        location / {
            root /home/html; # html访问路径
            index index.html; # html文件名称
            try_files $uri $uri/ /index.html; # 解决单页面应用刷新404问题
        }
    }
}

>: esc
>: :wq

重启服务
>: pkill -f uwsgi -9
>: uwsgi -x /home/project/luffyapi/luffyapi.xml
>: nginx -s reload

重点 重点 重点

# 1、真实环境和虚拟环境都要安装uwsgi,将真实环境下的uwsgi建立软连接

# 2、redis服务一定要后台启动:redis-server &

# 3、uwsgi启动django项目一定要进入虚拟环境下,因为环境都是安装在虚拟环境中

# 4、服务器的日志都会被记录在于uwsgi配置文件 luffyapi.xml 同类目下的 uwsgi.log 中

添加测试数据

>: mysql -uluffy -pLuffy123?
>: use luffy

INSERT INTO luffy_teacher(id, orders, is_show, is_delete, created_time, updated_time, name, role, title, signature, image, brief) VALUES (1, 1, 1, 0, '2019-07-14 13:44:19.661327', '2019-07-14 13:46:54.246271', 'Alex', 1, '老男孩Python教学总监', '金角大王', 'teacher/alex_icon.png', '老男孩教育CTO & CO-FOUNDER 国内知名PYTHON语言推广者 51CTO学院2016\2017年度最受学员喜爱10大讲师之一 多款开源软件作者 曾任职公安部、飞信、中金公司、NOKIA中国研究院、华尔街英语、ADVENT、汽车之家等公司');

INSERT INTO luffy_teacher(id, orders, is_show, is_delete, created_time, updated_time, name, role, title, signature, image, brief) VALUES (2, 2, 1, 0, '2019-07-14 13:45:25.092902', '2019-07-14 13:45:25.092936', 'Mjj', 0, '前美团前端项目组架构师', NULL, 'teacher/mjj_icon.png', '是马JJ老师, 一个集美貌与才华于一身的男人,搞过几年IOS,又转了前端开发几年,曾就职于美团网任高级前端开发,后来因为不同意王兴(美团老板)的战略布局而出家做老师去了,有丰富的教学经验,开起车来也毫不含糊。一直专注在前端的前沿技术领域。同时,爱好抽烟、喝酒、烫头(锡纸烫)。 我的最爱是前端,因为前端妹子多。');

INSERT INTO luffy_teacher(id, orders, is_show, is_delete, created_time, updated_time, name, role, title, signature, image, brief) VALUES (3, 3, 1, 0, '2019-07-14 13:46:21.997846', '2019-07-14 13:46:21.997880', 'Lyy', 0, '老男孩Linux学科带头人', NULL, 'teacher/lyy_icon.png', 'Linux运维技术专家,老男孩Linux金牌讲师,讲课风趣幽默、深入浅出、声音洪亮到爆炸');

INSERT INTO luffy_course_category(id, orders, is_show, is_delete, created_time, updated_time, name) VALUES (1, 1, 1, 0, '2019-07-14 13:40:58.690413', '2019-07-14 13:40:58.690477', 'Python');

INSERT INTO luffy_course_category(id, orders, is_show, is_delete, created_time, updated_time, name) VALUES (2, 2, 1, 0, '2019-07-14 13:41:08.249735', '2019-07-14 13:41:08.249817', 'Linux');

INSERT INTO luffy_course(id, orders, is_show, is_delete, created_time, updated_time, name, course_img, course_type, brief, level, pub_date, period, attachment_path, status, students, sections, pub_sections, price, course_category_id, teacher_id) VALUES (1, 1, 1, 0, '2019-07-14 13:54:33.095201', '2019-07-14 13:54:33.095238', 'Python开发21天入门', 'courses/alex_python.png', 0, 'Python从入门到入土&&&Python从入门到入土&&&Python从入门到入土&&&Python从入门到入土&&&Python从入门到入土&&&Python从入门到入土&&&Python从入门到入土&&&Python从入门到入土&&&Python从入门到入土&&&Python从入门到入土&&&Python从入门到入土&&&Python从入门到入土', 0, '2019-07-14', 21, '', 0, 231, 120, 120, 0.00, 1, 1);

INSERT INTO luffy_course(id, orders, is_show, is_delete, created_time, updated_time, name, course_img, course_type, brief, level, pub_date, period, attachment_path, status, students, sections, pub_sections, price, course_category_id, teacher_id) VALUES (2, 2, 1, 0, '2019-07-14 13:56:05.051103', '2019-07-14 13:56:05.051142', 'Python项目实战', 'courses/mjj_python.png', 0, '', 1, '2019-07-14', 30, '', 0, 340, 120, 120, 99.00, 1, 2);

INSERT INTO luffy_course(id, orders, is_show, is_delete, created_time, updated_time, name, course_img, course_type, brief, level, pub_date, period, attachment_path, status, students, sections, pub_sections, price, course_category_id, teacher_id) VALUES (3, 3, 1, 0, '2019-07-14 13:57:21.190053', '2019-07-14 13:57:21.190095', 'Linux系统基础5周入门精讲', 'courses/lyy_linux.png', 0, '', 0, '2019-07-14', 25, '', 0, 219, 100, 100, 39.00, 2, 3);

INSERT INTO luffy_course_chapter(id, orders, is_show, is_delete, created_time, updated_time, chapter, name, summary, pub_date, course_id) VALUES (1, 1, 1, 0, '2019-07-14 13:58:34.867005', '2019-07-14 14:00:58.276541', 1, '计算机原理', '', '2019-07-14', 1);

INSERT INTO luffy_course_chapter(id, orders, is_show, is_delete, created_time, updated_time, chapter, name, summary, pub_date, course_id) VALUES (2, 2, 1, 0, '2019-07-14 13:58:48.051543', '2019-07-14 14:01:22.024206', 2, '环境搭建', '', '2019-07-14', 1);

INSERT INTO luffy_course_chapter(id, orders, is_show, is_delete, created_time, updated_time, chapter, name, summary, pub_date, course_id) VALUES (3, 3, 1, 0, '2019-07-14 13:59:09.878183', '2019-07-14 14:01:40.048608', 1, '项目创建', '', '2019-07-14', 2);

INSERT INTO luffy_course_chapter(id, orders, is_show, is_delete, created_time, updated_time, chapter, name, summary, pub_date, course_id) VALUES (4, 4, 1, 0, '2019-07-14 13:59:37.448626', '2019-07-14 14:01:58.709652', 1, 'Linux环境创建', '', '2019-07-14', 3);

INSERT INTO luffy_course_Section(id, is_show, is_delete, created_time, updated_time, name, orders, section_type, section_link, duration, pub_date, free_trail, chapter_id) VALUES (1, 1, 0, '2019-07-14 14:02:33.779098', '2019-07-14 14:02:33.779135', '计算机原理上', 1, 2, NULL, NULL, '2019-07-14 14:02:33.779193', 1, 1);

INSERT INTO luffy_course_Section(id, is_show, is_delete, created_time, updated_time, name, orders, section_type, section_link, duration, pub_date, free_trail, chapter_id) VALUES (2, 1, 0, '2019-07-14 14:02:56.657134', '2019-07-14 14:02:56.657173', '计算机原理下', 2, 2, NULL, NULL, '2019-07-14 14:02:56.657227', 1, 1);

INSERT INTO luffy_course_Section(id, is_show, is_delete, created_time, updated_time, name, orders, section_type, section_link, duration, pub_date, free_trail, chapter_id) VALUES (3, 1, 0, '2019-07-14 14:03:20.493324', '2019-07-14 14:03:52.329394', '环境搭建上', 1, 2, NULL, NULL, '2019-07-14 14:03:20.493420', 0, 2);

INSERT INTO luffy_course_Section(id, is_show, is_delete, created_time, updated_time, name, orders, section_type, section_link, duration, pub_date, free_trail, chapter_id) VALUES (4, 1, 0, '2019-07-14 14:03:36.472742', '2019-07-14 14:03:36.472779', '环境搭建下', 2, 2, NULL, NULL, '2019-07-14 14:03:36.472831', 0, 2);

INSERT INTO luffy_course_Section(id, is_show, is_delete, created_time, updated_time, name, orders, section_type, section_link, duration, pub_date, free_trail, chapter_id) VALUES (5, 1, 0, '2019-07-14 14:04:19.338153', '2019-07-14 14:04:19.338192', 'web项目的创建', 1, 2, NULL, NULL, '2019-07-14 14:04:19.338252', 1, 3);

INSERT INTO luffy_course_Section(id, is_show, is_delete, created_time, updated_time, name, orders, section_type, section_link, duration, pub_date, free_trail, chapter_id) VALUES (6, 1, 0, '2019-07-14 14:04:52.895855', '2019-07-14 14:04:52.895890', 'Linux的环境搭建', 1, 2, NULL, NULL, '2019-07-14 14:04:52.895942', 1, 4);

课堂笔记

复习

"""
redis
	基本介绍:nosql数据库、内存数据库
	优势:读写效率高、操作方便、支持五种数据类型、数据持久化、数据丢失可以还原、高并发
	缺点:不支持事务
	操作五种数据类型:
		set key value | setex key time value
		rpush key args | lpush key args
		hset key field value
		sadd key args
		zadd key score member
	Python使用:pip install redis
	Django使用:pip install django-redis => 配置缓存
	
celery
	基本介绍:异步任务框架(独立的socket)
	组成:Broker(任务中间件:内存数据库、内存队列)、Worker(任务执行者)、Backend(任务结果仓库)
	创建celery应用:app = Celery(broker, backend, includ)
	服务命令:
		worker:celery worker -A celery文件所在包 -l info -P eventlet
		beat:celery beat -A celery文件所在包 -l info
	celery应用场景:
		耗时任务
		延迟任务
		周期任务
"""

课程内容

"""
1、免费课、实战课、轻课业务线独立,所以设置三个数据库表,相同字段用BaseModel处理
2、课程分类表、老师表只需要一个,三种课程公用
3、章节表、课时表、评论表、问题表要与具体分类的课程配套(陪三套表)

4、尽量不连表
	主页推荐课程,可以就访问课程表,课程表增加 推荐字段
	主页模块创建 课程推荐表,点击跳转的链接为 课程详情接口
	推荐关系表 => 接口缓存
	
   一下不是实时变化的数字结果(一般都是计算而来),可以直接用一个字段存储
   	总课时,热度(学习学生数)
   	
5、免费课一条业务线五张表:分类、课程、老师、章节、课时

6、序列化:表字段、插拔字段、子序列化

7、过滤组件:排序、搜索、分组筛选、区间筛选、分页
"""

A作业(必做)

"""
1、整理今天所学知识点

2、复习并掌握过滤组件:排序、搜索、分组筛选、区间筛选、分页

3、完成课程主页的 免费课程接口 与 前台数据渲染

4、完成课程详情页 课程详情接口 与 前台数据渲染
"""

B作业(选做)

"""
1、完成 全局课程搜索页面 的前台布局
2、完成 前后台搜索课程 业务
"""

七、

上线

E:\上海python脱产13期\路飞学成项目day60-90\luffy\day89\课件\上线\上线.md (自己本地文件夹)

支付

E:\上海python脱产13期\路飞学成项目day60-90\luffy\day89\课件\支付 (自己本地文件夹)

搜索

Header搜索组件







课堂笔记

日考

"""
1.vue指令和成员:
	v-text、html、if、for、show、model、on、bind
	data、method、computed、watch、props、钩子、filters、components
2.vue组件:
	template(一个根标签) + script(export default) + style(scope)
3.前后台交互:
	同源策略(跨域)
	ajax请求
"""

复习

"""
1、drf排序过滤器
class ListView:
	filter_backends = [OrderingFilter]
	ordering_fields = ['price', 'students']
	# 接口:?ordering=-price,students

2、drf搜索:SearchFilter  search_fields  search=*

3、自定义过滤器
class MyFilter:
	def filter_queryset(self, request, queryset, view):
		# request:从前台请求获取过滤的条件 query_params
		# queryset:要处理的数据
		# view:从视图中反射过滤相关的配置
		return 处理后的queryset,没有过滤就返回原样queryset
	
4、分页器
PageNumberPagination:基础分页器 page_size    page=1
LimitOffsetPagination:偏移分页器 default_limit    offset=0&limit=3
CursorPagination:游标分压器 一定是基于某种排序规则下的分页

5、django-filter

from django_filters.rest_framework.filterset import FilterSet
from django_filters import filters
from . import models
class CourseFilterSet(FilterSet):
    max_price = filters.NumberFilter(field_name='price', lookup_expr='lte')
    min_price = filters.NumberFilter(field_name='price', lookup_expr='gte')
    class Meta:
        model = models.Course
        fields = ['course_category', 'max_price', 'min_price']
        
DjangoFilterBackend   filter_class|filter_fields=['type']   
接口:?type=1
接口:?course_category=0&min_price=30&max_price=60
"""

课程内容

"""
1、搜索页面的实现与课程搜索数据展示
2、支付宝流程与二次封装支付宝框架
3、订单模块创建与表设计
4、支付接口的实现,订单表与订单详情表入库操作
5、前台完成支付请求
"""

A作业(必做)

"""
1、整理今天所学知识点

2、完成搜索页面渲染搜索接口

3、二次封装支付宝框架,并完成支付接口的创建

4、完成前台的支付功能
"""

B作业(选做)

"""
1、预习上线课件,完成阿里云服务器购买
2、预习往期上线视频
"""

八、

上线

E:\上海python脱产13期\路飞学成项目day60-90\luffy\day90\课件\上线 (自己本地文件夹)

支付

E:\上海python脱产13期\路飞学成项目day60-90\luffy\day90\课件\支付 (自己本地文件夹)

课堂笔记

复习

"""
1、搜索页面

2、支付宝支付
	支付流程:前台下单 => 后台生成订单,返回支付链接(包含了回调接口) => 前台访问支付链接,跳转到支付宝平台,与支付宝后台交互,完成支付 => 支付宝支付成功页面同步回调前台接口(跳转回我们自己的前台页面)(支付成功页面可以将回调参数同步传给我们自己的后台,可以完成订单的修改) + 支付宝支付成功8次异步回调后台接口,将支付的信息传输给我们的后台,后台可以做订单状态的修改,对支付宝异步回调响应 success 7个字符

3、异步回调流程
	支付宝支付成功在25小时内,分8次异步回调后台接口,将支付的信息传输给我们的后台,后台可以做订单状态的修改,对支付宝异步回调响应 success 7个字符

4、订单模块:
	订单表:订单号、支付用户、订单总额
	订单详情表:订单号外键、商品外键、商品价
"""

课程总结

"""
Vue
	基础:指令、实例成员、组件及传参
	开发:vue-router、vuex(localStorage|sessionStorage)、axios、vue-cookies
	
drf
	基础模块:请求、响应、渲染、解析、异常
	核心模块:序列化、三大认证、视图家族
	群查模块:搜索、排序、分页、分类、区间
	
luffy
	前后台项目重构
	跨越问题:django-cors-headers
	认证六表
	git:status、add、commit、reset、pull、push、merge、branch、remote、checkout
	短信接口
	redis:字符串、列表、哈希、集合、有序集合、django缓存配置
	celery:三个存成部分broker、worker、backend | 耗时任务、延迟任务、周期任务
	Alipay
	视频
"""

vue





// main.js

import '@/assets/css/global.css'
require('@/assets/css/global.css')

import settings from '@/assets/js/settings.js'
Vue.prototype.$settings = settings

import 'bootstrap'

import ElementUI from 'element-ui';
Vue.use(ElementUI);

// jquery环境需要在 vue.config.js 中配置

drf

"""
请求:request._request、request.query_params、request.data、request.query_params.dict()、request.data.dict()、request.META.get('HTTP_AUTHORIZATION')、request.user、request.auth

响应:data、status(http_status)、exception
	data: {
		status,
		msg,
		results,
	}
	
渲染:响应的数据支持浏览器和json格式数据渲染(全局或局部配置)
解析:请求的数据包数据支持解析的类型:urlencoded、form-data、json(全局或局部配置)
异常:自定义exception_handler,系统处理了客户端异常4xx,服务器异常需要手动处理5xx,记录异常日志


序列化:
	class myModel(models.Model):
		name = models.CharFields(max_length=64)
		@property
		def my_name(self):
			return self.name
		
	class MyModelSerializer(ModelSerializer):
		// 序列化还有子序列化
		re_pwd = serializers.CharFields(max_length=64)
		class Meta:
			model = myModel
			fields = ('name', 'my_name', 're_pwd')
			extra_kwargs={}
			list_serializer_class = ListSerialize
		def validate_name(self, value):
			if ...:
				raise serializers.ValidationError('...')
			return value
		def validate(self, attrs):
			request = self.context.get('request')
			
			obj
			self.obj = obj
			
			if ...:
				raise serializers.ValidationError({'...': '...'})
			return attrs
		
	class myAPIView(APIView):
		def get(self, request, *args, **kwargs):
			obj
			ser = MyModelSerializer(obj)
			
			objs
			ser = MyModelSerializer(objs, many=Ture)
	
		def post(self, request, *args, **kwargs):
			ser = MyModelSerializer(data=request.data, context={'request': request})
			ser.is_valid(raise_exception=True)
			ser.save()
			ser.obj
			
		def patch(self, request, *args, **kwargs):
			obj
			ser = MyModelSerializer(instance=obj,data=request.data, partial=True)
			ser.is_valid(raise_exception=True)
			ser.save()
	
三大认证:
	认证:就采用drf-jwt的认证类,局部或全局配置 - 游客、合法用户、非法用户
	权限:就采用drf提供的权限类,局部或全局配置 - 有权限、无权限
	频率:scope与配置文件完成配置3/min、get_cache_key提供缓存key
	
视图家族:
	APIView(禁用csrf、各种功能模块、全局局部配置)、GenericAPIView(model相关的三个属性三个方法)
	mixin:五个工具类,六个工具方法
	工具视图:ListAPIView,...
	视图集:ViewSets - as_view({'get': 'my_get'})
	
	
	
	
群查接口:
	SearchFilter
	OrderingFilter
	paginations
	django-filter插件
"""

课程内容

"""
1、支付模块的同步回调接口
2、支付模块的异步回调接口
3、阿里云服务器购买与服务器环境搭建
4、Nginx实现前后台项目上线
"""

A作业(必做)

"""
1、整理今天所学知识点

2、完成支付模块的回调接口

3、购买服务器,并完成前后台项目的上线

4、总结整理luffy课程的所有知识点
"""

B作业(选做)

"""
1、认证复习路飞项目涉及的所有知识点,将luffy项目完成
2、预习微信小程序视频
"""

你可能感兴趣的:(路飞学城之 luffy (2 ))