路飞项目 - 项目前后端搭建

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()不返回任何内容。 它生成的日志记录将发送到日志模块,并通过您配置的任何处理程序进行处理。 如果您确实想检查通过的记录,则可能需要实现自己的处理程序并将其添加到记录器中。

image-20230227170327410

  • 可以通过配置日志对象的记录日志的等级来控制日志输出的等级
'level': 'DEBUG',

image-20230227171615195

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'
}

③ 写代码后报错会统一处理返回给前端,并且会记录日志

image-20230227193911876

image-20230227193924405

3 封装Response

1.为什么要封装Response

drf已经封装了Response对象,但是公司规定前端收到的格式都是固定的,并且携带一定的数据

例如:

# 携带数据
{code:100,msg:提示,data:{}/[]}
# 携带token或者用户
{code:100,msg:提示,token:xxx,user:xxx}

2.使用步骤:

① 在utils下新建common_response.py

image-20230227194932708

② 封装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 软件开发模式

img

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内置的

posted @ 2023-02-27 21:47  Duosg  阅读(26)  评论(0编辑  收藏  举报