路飞项目 - 项目前后端搭建
1 封装后台日志
1.日志的作用:
对特定的io操作进行记录,记录错误和记录操作
【日志可以用来做项目管理,记录用户行为分析,大数据分析】
开发阶段可以将print换成logger.info
这样项目上线后只需要调整日志级别,低级别的日志不在打印了,日志输出不用删掉了
2.日志显示:
① 日志可以打印到控制台
② 日志可以写到日志文件中
③ 日志可以存到数据库中
④ 所有项目统一管理【 sentry:django写的服务,收集日志可以展示】
3.操作步骤
django中集成日志步骤,django使用的是python内置的日志模块
① 第一步:在配置文件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': 'ERROR', '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新建common_logger.py,封装成日志对象
common_logger.py中选择日志对象
import logging logger = logging.getLogger('django')
③ 第三步:在任意想用日志的地方,导入封装好的日志对象使用即可
# 导入封装好的日志对象 from utils.common_logger import logger def test_logging(request): """测试日志""" logger.debug('记录【debug】级别的日志') logger.info('记录【info】级别的日志') logger.warning('记录【warning】级别的日志') logger.error('记录【error】级别的日志') logger.critical('记录【CRITICAL】级别的日志') return HttpResponse('ok')
- debug级别的的日志并不打印在控制台中
- debug()不返回任何内容。 它生成的日志记录将发送到日志模块,并通过您配置的任何处理程序进行处理。 如果您确实想检查通过的记录,则可能需要实现自己的处理程序并将其添加到记录器中。
- 可以通过配置日志对象的记录日志的等级来控制日志输出的等级
'level': 'DEBUG',
2 封装全局异常处理
1.为什么项目中要统一对异常处理进行封装?
前端接收异常的格式要统一,所以我们对于项目中的抛出的异常应该进行统一的处理
但是因为我们是基于drf的基础上编写项目,在drf中使用了三大认证的封装。
所以我们在drf的基础上继续进行封装即可
2.处理步骤
① 在utils.py中新建py文件 - common_exceptions.py
- 1 封装处理drf的异常与非drf的异常
- 2 添加日志记录
# 封装项目的全局异常处理 # 1.导入drf的异常处理函数 from rest_framework.views import exception_handler as drf_exception_handler # 2.导入drf封装的Response对象 from rest_framework.response import Response # 3.导入日志对象 from utils.common_logger import logger def luffy_exception_handler(exc, context): # 对drf的异常捕获以及非drf的异常捕获后,需要把抛出的异常加入到日志文件中 # 0、记录日志:哪个ip地址、用户id是多少、访问哪个路径、执行哪个视图函数、出了什么错 request = context.get('request') view = context.get('view') # 获取ip地址 ip = request.META.get('REMOTE_ADDR') # 获取user_id,通过获取用户对象来获取用户的id user_id = request.user.pk # 获取用户访问的地址 path = request.get_full_path() # 1. 通过drf的异常处理函数,判断是否是drf的异常 drf_request = drf_exception_handler(exc, context) # 2. 判断是否是drf的异常,如果是drf_request有值则是drf抛出了异常 if drf_request: # 添加记录用户日志信息 logger.warning('drf出现异常,异常是【%s】' % str(exc)) res = Response({'code': 888, 'msg': drf_request.data.get('detail', '请联系系统管理员')}) else: # 添加日志 logger.warning('用户【%s】:ip地址为【%s】,访问地址【%s】时,执行了函数【%s】,出现了异常【%s】' % (user_id, ip, path, view, str(exc))) res = Response({'code': 999, 'msg': '请联系系统管理员'}) return res
② 配置文件中配置
配置使用自己封装的异常处理
# 全局异常处理 REST_FRAMEWORK = { 'EXCEPTION_HANDLER':'utils.common_exceptions.luffy_exception_handler' }
③ 写代码后报错会统一处理返回给前端,并且会记录日志

3 封装Response
1.为什么要封装Response
drf已经封装了Response对象,但是公司规定前端收到的格式都是固定的,并且携带一定的数据
例如:
# 携带数据 {code:100,msg:提示,data:{}/[]} # 携带token或者用户 {code:100,msg:提示,token:xxx,user:xxx}
2.使用步骤:
① 在utils下新建common_response.py
② 封装MyResponse
自己编写响应类继承Response,来定制返回格式
from rest_framework.response import Response class MyResponse(Response): # 1 派生 __init__ 方法,给code 与 msg设定默认值, # status=None, headers=None默认可以不传 # 其他的参数用**kwargs统一接收 def __init__(self, code=100, msg='成功', status=None, headers=None, **kwargs): # 2 设置返回格式 data data = {'code': code, 'msg': msg} # 3 判断kwargs是否传值,如果传了则说明处理四个默认的之外有新的参数 if kwargs: # 4 使用字典的update方法,如果有新的键值对则新增,如果没有原有的键值对有更改则更新 data.update(kwargs) # 5 派生继承原有的__init__方法,这样就在drf的Response类基础上 对返回能传递的数据进行了修改 super().__init__(data=data, status=status, headers=headers)
③ 导入使用
视图函数的方法,返回时Response对象时,使用自己封装的
4 luffy数据库创建
1.项目数据库用户为什么不用root
之前项目操作数据库都是root用户,root权限过于高,如果开发人员都是root权限,那么每个开发人员都能对任意的数据库进行操作,数据的安全性较低
因此,应该专门创建一个数据库用户,并且只对当前项目的数据库有操作权限
2.创建luffy数据库操作步骤
① 以管理员身份,连接数据库
mysql -uroot -p
② 创建数据库luffy
create databases luffy default charset=utf8;
③ 创建luffy用户,配置任意ip都可以连入数据库的账户
# 设置权限账号密码:授权账号命令: grant 权限(create, update) on 库.表 to '账号'@'host' identified by '密码' grant all privileges on luffy.* to 'luffy'@'%' identified by 'luffy123';
④ 由于数据库版本的问题,可能本地还连接不上,就给本地用户单独配置
grant all privileges on luffy.* to 'luffy'@'localhost' identified by 'luffy123';
⑤ 刷新权限
flush privileges;
3.在项目中配置数据库
(1)配置文件中配置数据库连接
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'luffy', 'HOST': '127.0.0.1', 'PORT': 3306, 'USER': 'luffy', 'PASSWORD': 'luffy123' } }
(2)在项目下的主模块的__init__.py
配置
import pymysql pymysql.install_as_MySQLdb()
pip3 install mysqlclient -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com/simple/
- 关于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 -人品不好,装不了,centos部署项目,后面会讲centos上如何装
5 软件开发模式
1.瀑布模式
需求分析---》设计--》创建数据库 所有都创建---》开发(3个月)---》交给测试--》测试通过---》上线
2.敏捷开发
需求分析---》设计---》只设计一个板块---》开发(2周)---》交给测试---》运维上线(测试环境)
-设计---》只设计一个板块---》开发(2周)---》交给测试---》运维上线(测试环境)
6 User模块用户表
1.分析
- 用户表使用Auth表扩写
使用auth表扩写,项目一定不要先迁移
2.用户表使用auth表扩写
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
7 开启media访问
1 在配置文件中配置
MEDIA_URL = '/media/' MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
2 配置路由
# 以后使用djagno的配置文件都用这个 from django.conf import settings path('media/<path:path>', serve, {'document_root': settings.MEDIA_ROOT}) # 访问 http://127.0.0.1:8000/media/icon/default.png
以后使用配置文件settings 都使用django内置的
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY