1 项目数据库之隐藏密码
# 我们直接把mysql的用户名和密码 写死在了代码中----》后期可能会存在风险----》代码如果泄露----》mysql的用户密码泄露----》可以远程登录----》脱裤(拖库)----》所有数据会被黑客获取到----》卖钱
# 华住---》在代码中把数据库用户名和密码写死了----》源代码泄露了---》导致数据泄露
# 上海随身办数据泄露----》新员工写博客---》把密钥放到了网上
# 我们不把敏感信息写死在代码中
-从环境变量中获取
-PATH:任意路径下敲可执行文件能找到
-其它key value 是该机器的全局配置,可以直接拿到
-使用python代码拿到
##### python代码获取环境变量的值 #####
# 配置完环境变量,重启一下pycharm
# 如果环境变量没配置,就用默认的
# 如果配置了,就用配置的(项目上线时候,运维配置环境变量---》运维配置的环境变量的值----》开发根本不知道)
import os
res=os.environ.get('PWD','Luffy123?')
print(res)
res=os.environ.get('USER','luffy')
print(res)
###### 具体操作#####
user = os.environ.get('USER', 'luffy')
pwd = os.environ.get('PWD', 'Luffy123?')
print('-----',user)
print(pwd)
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'luffy', # 数据库名字
'USER': user, # luffy用户
'PASSWORD': pwd,
'HOST': 'localhost',
'PORT': 3306
}
}
补充:环境变量设置
# 1 为什么一定要设置默认值
# 开发项目的时候没有配环境变量,设置默认值连自己数据库;项目上线时配置了环境变量,只有运维知道用户名和密码
user = os.environ.get('USER', 'luffy')
pwd = os.environ.get('PWD', 'Luffy123?')
# 2 这种环境变量,一般不写死在系统,而是临时设置,系统重启就失效。
win:图形化界面的设置
mac:
-.bash_profile:只在当前会话生效,当前窗口中生效,关掉窗口,再打开,就失效了
-source .bash_profile,重新在当前会话中生效
-.zshrc:当前用户永久生效
linxu: 文件可能名字不一样,配置方式跟mac完全一样
# 临时设置:运维上线时候,手动设置,当前会话生效。部署项目的时候用shell脚本去做,然后shell脚本设置完了之后立马把项目启动起来,所以它算在一个会话里
win:
set xx=lqz # 设置环境变量
echo %xx%
linux ,mac:
export xx=lqz
echo $xx
项目部署:打开一个命令窗口
设置一堆环境变量
python manage.py runserver '''不是一行一行敲,以shell脚本形式去设置'''
2 封装logger
# 项目运行,会产生很多日志
# 日志作用:记录程序运行过程中 错误,警告,程序员的输出,观察项目运行情况
# 每个项目都需要记录日志
# django中加入记录日志的功能
1 把如下代码,copy到配置文件中
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': 'WARNING',
'filters': ['require_debug_true'],
'class': 'logging.StreamHandler',
'formatter': 'simple'
},
'file': {
# 实际开发建议使用ERROR
'level': 'ERROR',
'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 获取logger对象:utils/common_logger.py
# 日志对象获取,以后想用日志的地方,直接导入,使用 logger.info error....
import logging
logger=logging.getLogger('django')
3 以后想用日志的地方,直接导入使用即可
# DEBUG < INFO < WARNING < ERROR < CRITICAL
logger.debug('debug级别')
logger.info('info级别')
logger.warning('warning级别')
logger.error('error级别')
logger.critical('CRITICAL级别')
4 以后想用print的位置,都用logger.info,以后项目上线,调高日志输出级别,虽然代码中写了日志输出,实际上并不会输出
3 封装全局异常
# utils/common_exceptions.py
from rest_framework.views import exception_handler
from rest_framework.response import Response
from utils.common_logger import logger
### 加入日志记录,只要走到这,说明程序出error了,程序的error,咱们都要记录日志,方便后期排查
### 日志记录尽量详细:ip;如果用户登录了,记录用户;请求地址是;执行那个视图类出的错
def common_exception_handler(exc, context):
request = context.get('request')
view = context.get('view')
ip = request.META.get('REMOTE_ADDR')
user_id = request.user.pk
path = request.get_full_path()
view_str = str(view)
res = exception_handler(exc, context)
logger.error('用户地址为:%s,用户id号为:%s,请求地址为:%s,执行的视图函数为:%s' % (ip, user_id, path, view_str))
if res:
# drf的异常,一种是从res.data这个字典的detail中取,一种是直接取data
if isinstance(res.data, dict):
data = {'code': 201, 'msg': res.data.get('detail', '系统错误,请联系系统管理员')}
else:
data = {'code': 202, 'msg': res.data}
else:
# django的异常
data = {'code': 203, 'msg': str(exc)}
return Response(data)
### 配置文件配置
REST_FRAMEWORK = {
'EXCEPTION_HANDLER': 'utils.common_exceptions.common_exception_handler',
}
4 封装Response
# 咱们之前使用drf提供的Response类,用它的时候,需要传很多参数,基于它做封装,方便我们的使用
data=None,
status=None,
headers=None,
# 封装后达成的效果是 APIResponse
return APIResponse()
----->前端收到的是 {code:100,msg:成功}
return APIResponse(token=12q4dfasdf,username=lqz)
----->前端收到的是 {code:100,msg:成功,token:12q4dfasdf,username:lqz}
return APIResponse(data=[{name:红楼梦,price:33},{name:西游记,price:33}])
----->前端收到的是 {code:100,msg:成功,data:[{name:红楼梦,price:33},{name:西游记,price:33}]}
return APIResponse(code=101,msg='失败')
----->前端收到的是 {code:101,msg:失败}
return APIResponse(headers={'xx':'xx'})
----->前端收到的是 {code:100,msg:成功},但是相应中有xx:xx
return APIResponse(name=lqz,status=201)
----->前端收到的是 {code:100,msg:成功,name:lqz},但是响应状态码是201
# utils/common_response.py
from rest_framework.response import Response
class APIResponse(Response):
def __init__(self, code=100, msg='成功', status=None, headers=None, **kwargs):
data = {'code': code, 'msg': msg}
# kwargs 有可能是 {token:asdfad,name:lqz}
if kwargs:
data.update(kwargs)
# 调用父类(Response)的__init__完成初始化
super().__init__(data=data, status=status, headers=headers)
5 开启media访问
# 头像,课程图片,放在项目的某个目录下 (media),后期需要能够访问
# 需要开启media的访问
from django.views.static import serve
from django.conf import settings
urlpatterns = [
path('media/<path:path>', serve,{'document_root':settings.MEDIA_ROOT}),
]
# dev.py
MEDIA_ROOT = os.path.join(BASE_DIR, 'media') # BASE_DIR是小luffy
6 前端项目创建,调整
# 创建前端项目 vue2
vue create luffy_city
创建成功,用pycharm打开
7 前端配置
# 安装第三方
-axios
-elementui
-vue-cookies
# 安装
cnpm install -S axios
cnpm install -S vue-cookies
cnpm i [email protected] -S
# main.js中配置
// elementui配置
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);
// axios配置
import axios from "axios";
Vue.prototype.$axios=axios
// vue-cookies配置
import cookies from 'vue-cookies'
Vue.prototype.$cookies=cookies
# 写一个全局配置settings.js 文件
# assets--》js--》settings.js
export default {
BASE_URL: 'http://127.0.0.1:8000/api/v1/'
}
# main.js中
import settings from '@/assets/js/settings'
Vue.prototype.$settings=settings
# 以后在任意组件中
this.$settings.BASE_URL
# 全局样式
html的标签a ul li ,都会有默认样式,正常的前端,都会去掉所有标签的默认样式, 自己写样式
# 1 assets--》css--》global.css
/* 声明全局样式和项目的初始化样式 */
body, h1, h2, h3, h4, h5, h6, 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; /* 合并边框 */
}
# 2 main.js 配置,样式全局生效
// 使用全局样式,取出所有标签默认样式
import '@/assets/css/global.css'
标签:02,code,项目,路飞,msg,import,日志,data,logger
From: https://www.cnblogs.com/10086upup/p/17484167.html