路飞项目前置准备
软件开发流程
真正的企业里软件从立项到交付整个过程
-立项:确定公司要开发这个软件 公司高层
-软件来源
-产品经理设计出来的----》互联网项目 互联网公司
-用户(医院,政府部门,企业。。) 传统软件公司
-需求分析
# 互联网项目
-需求调研和分析:产品经理设计出来的
# 传统软件
-需求调研和分析:市场人员跟客户对接
-产品经理 ,开发人员跟客户对接,生成需求文档
-原型设计:产品经理
-懂业务
-画出原型图:app,网页款
-分任务开发
-UI设计
-根据原型图设计 切图
-前端团队
-前端拿着切图写代码(pc,小程序,移动端)
-mock数据:搞假数据,先把功能开发出来
-后端团队
-组里开会,需求文档和原型图,设计后台
-架构,数据库设计
-分任务开发:用户,商品板块
-测试(质量控制部)
-普通功能测试
-接口测试
-压力测试,jmeter软件
-自动化测试
-联调测试
-项目上线(运维)
-持续维护项目
作为后端开发,公司里开发的流程
-开新项目,先开会,设计技术选型,数据库设计
-产品,原型图做好了
-老大在项目管理平台(禅道)分配任务给我
-进入到管理平台就能看到任务与相关功能的原型图
-需求,原型图,实现的效果
-开发---有不明白的需求,找产品对接----》自测
-提交到版本仓库(git,svn)
-管理平台点完成
-所有都开发完了,分支合并
-跟前端联调
-发版
-如果是老项目
-老大在项目管理平台(禅道)分配任务给我
-进入到管理平台就能看到任务,相关功能的原型图
-需求,原型图,实现的效果
-开发---有不明白的需求,找产品对接----》自测
-提交到版本仓库(git,svn)
-所有都开发完了,分支合并
-跟前端联调
-发版
路飞项目需求
# 关于路飞项目
-商城类
-知识付费项目
-前后端分离
-主站vue
-后台管理 simpleui
# 需求
-首页功能
-首页轮播图
-推荐课程(没有讲)
-用户功能
-用户名密码登录
-手机号验证码登录
-发送手机验证码
-验证手机号是否注册过
-注册接口
-查看用户信息(没有)
-修改用户信息(没有)
-课程列表功能
-课程列表接口,课程列表展示
-排序,过滤,分页
-课程详情
-课程详情接口
-视频播放功能
-视频托管(第三方,自己平台) 文件托管
-下单功能
-支付宝支付:生成支付链接,付款,回调修改订单状态
-购买成功功能
路飞项目开始
准备工作
1,pip永久换源
打开我的电脑地址栏 输入 %APPDATA% 回车
进入:C:\Users\李啊鸡\AppData\Roaming 目录中
新建pip文件夹并在文件夹中新建pip.ini 配置文件
复制下列内容到pip.ini配置文件中
[global]
index-url = https://mirrors.aliyun.com/pypi/simple
[install]
use-mirrors =true
mirrors =https://mirrors.aliyun.com/pypi/simple
trusted-host =mirrors.aliyun.com
以后直接pip install 就不用切换源了
2.虚拟环境
两个django项目基于不同的django版本同时开发,每个项目都用自己的独立环境,装的模块互不影响。就要使用虚拟环境。
两种解决方案:
Virtualenv
pipenv
Virtualenv 方案创建虚拟环境
需要安装两个模块
pip install virtualenv # 虚拟环境是它
pip install virtualenvwrapper-win # 对虚拟环境的加强,以后只需要简单的命令就可以使用和创建虚拟环境
配置虚拟环境变量
我的电脑右键属性-高级设置-环境变量
在环境变量中新建:WORKON_HOME: D:\Virtualenvs
去D盘目录下创建文件夹,以Virtualenvs命名
以后新建的虚拟环境都会在这个文件下
python3 的安装目录下的Scripts文件夹
有一个名为 virtualenvwrapper.bat 的批处理文件
双击运行
创建虚拟环境
cmd执行
mkvirtualenv -p python38 luffy(luffy是虚拟环境的名字)
创建完成后会放在D:\Virtualenvs目录下,并进入虚拟环境
观察cmd命令行前面 会有显示
eg:
(luffy) C:\Users\李啊鸡>
有则表示在虚拟环境中,以后安装的所有模块,都是给虚拟环境安装的
退出虚拟环境
deactivate
使用虚拟环境
退出虚拟环境后下次进入虚拟环境可以使用
workon # 查看有哪些虚拟环境
workon luffy(环境名) # 进入虚拟环境
删除虚拟环境
rmvirtualenv 虚拟环境名称
pycharm创建虚拟环境

已有项目使用虚拟环境,切换虚拟环境的解释器

3,使用pycharm创建虚拟环境路飞项目

注意如果下侧有黄色提示说明该虚拟环境中缺少django模块,需要自己去下载在创建如果直接创建就会下载最新版的django
4,创建路飞前端项目
vue create luffy_city
5.包的导入问题
- pycharm会把项目路径加入到环境变量 ,命令行中不会加入
- from 的路径,需要从环境变量开始
-安装的第三方模块,都在环境变量,内置模块 os,sys, 也在环境变量中,可以直接导入 - 在包内部,推荐使用相对导入
-一旦使用相对导入,该文件,就不能以脚本形式运行了(不能右键运行)
-在同一个目录下的推荐使用相对导入
-不同目录下的推荐使用绝对导入
- from 的路径,需要从环境变量开始
6.后端项目调整目录
# 调整目录后成
"""
├── luffy_api
├── logs/ # 项目运行时/开发时日志目录 - 包
├── manage.py # 脚本文件
├── luffy_api/ # 项目主应用,开发时的代码保存 - 包
├── apps/ # 开发者的代码保存目录,以模块[子应用]为目录保存 - 包
├── libs/ # 第三方类库的保存目录[第三方组件、模块] - 包
├── settings/ # 配置目录 - 包
├── dev.py # 项目开发时的本地配置
└── prod.py # 项目上线时的运行配置
├── urls.py # 总路由
└── utils/ # 多个模块[子应用]的公共函数类库[自己开发的组件]
└── scripts/ # 保存项目运行时的脚本文件,小的测试脚本 - 文件夹,不提交到git上
"""
7,开发阶段
调整完目录后运行项目会报错,报错问题处理
python manage.py runserver # 运行项目
原因是我们把settings文件改成dev了,django运行的时候就会去找settings文件
修改manage.py 的settings.py 目录
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'luffy_api.settings')
修改成
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'luffy_api.settings.dev')

DJANGO_SETTINGS_MODULE=luffyapi.settings.dev
解决问题。
8,上线阶段
修改wsgi.py与asgi.py 文件中的路径
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'luffy_api.settings.prod')
9,创建app
我们可以选择在根路径创建app后拖入apps文件夹内,也可以通过cd切换到apps文件夹路径内进行创建app。
cd luffy_api
cd apps
python ../../manage.py startapp home # 因manage.py 文件在根目录所以需要../..
创建好app后我们在dev文件内注册app 发现报错。原因是apps的路径不在环境变量中
'luffy_api.apps.home', # 可以这样导,但是太长,有简写
'luffy_api.apps.user'
可以直接写成这样,只需要把apps路径加入到环境变量
'home',
'user'
注意:
app目录下的apps.py 文件内也得修改 name改成 name & name 改成home
# 加入环境变量----配置文件中的开始(最上面)dev.py
from pathlib import Path
import sys,os
BASE_DIR = Path(__file__).resolve().parent.parent # dev的父目录settings的父目录小路飞的路径
sys.path.insert(0,os.path.join(BASE_DIR,'apps'))
# 把小路飞也加入到环境变量中
"""方便使用 form home import views
但是不加也可以使用 form luffy_api.apps.home import views"""
sys.path.insert(0,os.path.join(BASE_DIR))
print(sys.path)
但是我们在导入apps下的app时pycharm解释器会给我们爆红,但是其本身是没有问题的。
解决爆红问题

后台日志封装
项目肯定要打印日志,日志可以打印到控制台,也可以写到文件中,或者保存到库里。
所有项目日志都可以统一管理 使用sentry
sentry:django写的服务,收集日志的,可以展示 开源的
我们这里不用这个但是有空需要看一下
操作步骤
1,配置文件中加入配置
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': 'INFO',
'filters': ['require_debug_true'],
'class': 'logging.StreamHandler',
'formatter': 'simple'
},
# 写到日志文件中
'file': {
# 实际开发建议使用ERROR
'level': 'WARNING',
'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, # 是否让日志信息继续冒泡给其他的日志处理系统
},
}
}
2.utils下新建 common_logger.py 得到日志对象
import logging
logger = logging.getLogger('django')
3.导入后再视图方法内使用
logger.info('info级别的日志')
logger.error('error级别的日志')
全局捕捉异常
无论后端是否出错,前端接收的格式要统一
drf的三大认证,视图类的方法中只要出了异常,就会执行一个函数,但是这个函数只能处理drf的异常
我们需要自己写个函数既能处理drf异常,又能处理django异常
使用步骤
记得配路由哦
1.在utils中新建 common_exceptions.py 写个函数
from rest_framework.views import exception_handler as drf_exception_handler
from rest_framework.response import Response
from utils.common_logger import logger
# 只要知道这个函数一定出错了,就要记录日志
def exception_handler(exc, context):
# 1.记录日志 记录详细
# context 里有request和view
request = context.get('request')
view = context.get('view')
ip = request.META.get('REMOTE_ADDR')
user_id = request.user.id
if not user_id:
user_id = '匿名用户'
path = request.get_full_path()
response = drf_exception_handler(exc, context)
if response:
# drf 的异常 已经处理过
logger.warning(f'drf出了异常,问题是:{str(exc)}')
# drf的异常已经被drf三大认证处理了,response.data里的detail里有错误信息,直接取可能会有问题 碰到在解决
res = Response({'code': 999, 'msg': response.data.get('detail', '服务器异常,请联系管理员')})
else:
# django的异常需要我们自己处理详细一点
logger.error(f'用户:{user_id},ip地址为:{ip},访问地址为:{path},执行视图函数为:{str(view)},出错问题是:{str(exc)}')
# django的异常我们自己处理,后续报错我们可以根据时间去日志里查找详细信息
res = Response({'code': 888, 'msg': '服务器异常,请联系系统管理员'})
return res
2.导入使用
视图函数的方法报错返回时的数据格式,都使用咱们自己的
# 测试全局异常处理
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.exceptions import APIException
class TestException(APIView):
def get(self, request):
# # drf报错
# raise APIException('drf出了异常')
# 未知错误
# l = [1,2]
# print(l[3])
# django的错误
raise Exception('django抛异常')
return Response('ok')
封装APIResponse
本身drf就有Response 但是根据公司规定前端收到的格式必须是固定格式
eg:
{'code':100,'msg':'错误提示',data:{}}
{'code':100,'msg':'错误提示','token':dasd213asd123f,data:{}}
封装后code,msg就不需要传了,使用默认的
开始封装
在utils中新建common_response.py复制下列代码放入
记得配路由哦
# 继承drf的Response 在其基础之上继续封装
from rest_framework.response import Response
"""
使用APIResponse()返回数据前端收到{'code':100,'msg':'成功'}
APIResponse(token=token,username='lxj'),----》前端收到{'code':100,'msg':'成功','token':dasda231314,'username':lxj}
"""
class APIResponse(Response):
def __init__(self,code=100,msg='成功',status=None,headers=None,**kwargs):
# 如果不传 data就等于默认的,传了就用新传的
data = {'code':code,'msg':msg}
# 判断kwargs里有传入数据没,有则传入了非code,msg,status,headers,之外的数据都要返回给前端
if kwargs:
# data里有一样的就替换,不一样的往data添加进去
data.update(kwargs)
# "子类调用父类的方法"完成初始化
super().__init__(data=data,status=status,headers=headers)
导入使用
# 测试APIResonse
from rest_framework.views import APIView
from utils.common_response import APIResponse
class TestAPIResponse(APIView):
def get(self,request):
# return APIResponse(token='213da',username='lxj')
"""
{
"code": 100,
"msg": "成功",
"token": "213da",
"username": "lxj"
}
"""
# return APIResponse(code=101,msg='错误')
"""
{
"code": 101,
"msg": "错误"
}
"""
return APIResponse(data=[{'name':'lxj','age':18}])
"""
{
"code": 100,
"msg": "成功",
"data": [
{
"name": "lxj",
"age": 18
}
]
}
"""
luffy数据库创建
在实际情况中root权限太大,在公司里一般不会给到你。
创建一个luffy库,创建luffy用户,luffy用户只对luffy库有操作权限
1.管理员连接数据库
>: mysql -uroot -proot
2.创建数据库
>: create database luffy default charset=utf8;
3.查看用户
>: select user,host,password from mysql.user;
只有root用户,要创建luffy用户
% 代表所有ip远程方式都能连
localhost 代表只能本地连
# 5.7往后的版本
>: select user,host,authentication_string from mysql.user;
创建路飞用户,授予luffy库所有权限
设置权限账号密码
# 授权账号命令:grant 权限(create, update) on 库.表 to '账号'@'host' identified by '密码'
1.配置任意ip都可以连入数据库的账户
"""
grant all privileges 所有权限
on luffy.* = luffy库所有表
to 'luffy'@'%' = @ 访问地址 %允许远程访问
identified by 'Luffy123?'; 密码
"""
>: 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?
连接区别
mysql -uluffy -p 本地连
mysql -uluffy -h 127.0.0.1 -p 远程联
一个是直接连,一个是通过网卡连
项目连接mysql
# 项目操作mysql,需要安装模块
pymysql
mysqlDB
mysqlclient
历史:原来py2上有个操作mysql的模块叫mysqlDB,但到py3,没有支持py3,django默认使用这个模块去连接mysql,默认使用-mysqlDB连接,-mysqlDB不支持py3,运行报错
我们使用pymysql,作为连接mysql的数据库模块,但是需要加代码
imprort pymysql
pymysql.install_as_mysqldb() # 猴子补丁
django 2.2.2以后,还使用pymysql,需要改djagno源代码
统一使用mysqlclient来作为操作mysql的底层库,基于py2的mysqldb,在py3上重写了,但是名字改成了mysqlclient
使用mysqlclient,只需要安装这个模块,不需要再写任何代码,直接用即可
-但是:mysqlclient 这个模块,不好装
-win 一般人品好,人品好,pip install mysqlclient
安装mysqlclient
pip install mysqlclient
配置文件修改,连接mysql,使用路飞用户
import os
# 为了数据的安全一般从环境变量中配置好用户名与密码,然后取出来,后面可以随便写 是前面娶不到就用后面的,为了安全不能填写真实的
环境变量添加:
"""LUFFY_NAME = name
LUFFY_PASSWORD = password"""
name = os.environ.get('LUFFY_NAME', 'luffy')
password = os.environ.get('LUFFY_PASSWORD', 'Luffy123?') # luffy123? 这个是前面取不到环境变量就会用这个,因为我们没添加环境变量所以用的真的
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'luffy',
'USER':name,
'PASSWORD':password,
'HOST':'127.0.0.1',
'PORT':3306,
}
}
软件开发模式
瀑布模式:bbs项目就是按照这种模式
# 流程
需求分析-->设计-->创建数据库 所有都创建-->开发(3个月)-->交给测试-->测试通过-->上线
敏捷开发
需求分析-->设计-->只设计一个板块-->开发(2周)-->交给测试-->运维上线(测试环境)
设计-->设计下一个板块-->开发(2周)-->交给测试-->运维上线(测试环境)

sprint周期就是敏捷开发周期
User模块用户表
用户表使用auth表扩写
from django.db import models
from django.contrib.auth.models import AbstractUser
# Create your models here.
class User(AbstractUser):
# 扩写手机号和头像字段
mobile = models.CharField(max_length=11, unique=True)
# 需要pillow包的支持
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
"""
记得迁移前:在配置文件中替换
AUTH_USER_MODEL = 'user.user'"""
# 大家遇到的问题,明明小luffyapi已经加入到环境变量,程序运行没问题,但是表迁移,就报错,找不到模块
-迁移有问题:配置文件中把小路飞的path环境变量转成字符串添加到sys.path中,就解决了
我没报错哦
开启媒体目录media访问
配置文件添加以下代码
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
路由设置
from django.urls import path,re_path
from django.views.static import serve
from django.conf import settings
# 第一种方法
re_path('^media/(?P<path>.*)', serve, {'document_root': settings.MEDIA_ROOT})
# 第二种方法
path('media/<path:path>', serve, {'document_root': settings.MEDIA_ROOT})


浙公网安备 33010602011771号