首页 > 数据库 >路飞之后台目录调整、日志封装、异常处理、luffy创建数据库、User表扩建和media开启访问

路飞之后台目录调整、日志封装、异常处理、luffy创建数据库、User表扩建和media开启访问

时间:2023-02-27 22:57:01浏览次数:50  
标签:封装 media django --- 路飞 api User luffy 日志

目录

后台

后端项目调整目录

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

运行项目---python manage.py runserver
#  调整后运行不了--找不到配置文件---要运行,修改manage.py第9行

1.开发阶段
  os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'luffy_api.settings.dev')
    
2.要上线(后期上线改)
    asgi.py
	wsgi.py的第14行
   os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'luffy_api.settings.prod')
    
    
3.创建app时,要进入到apps文件夹下执行
	python38 ../../manage.py startapp home
    
    
4.注册app
	1.首先在app下的apps.py 中修改name,name = 'luffy_api.apps.home'
        
      2.以后想直接写app名字,所以要把apps的路径加入到环境变量,加载配置文件的一开始,在配置文件中把apps和小路飞路径加入到环境变量
        sys.path.insert(0, os.path.join(BASE_DIR, 'apps'))
        # 把BASE_DIR也加入到环境变量,以后直接从小路飞开始导起即可
        sys.path.insert(0, BASE_DIR)
        
        # 把apps和小路飞的路径添加到环境变量的好处:以后从大路飞开始导起,或者小路飞开始导起,或者apps开始导起都可以
        3.注册app
        'luffy_api.apps.home',   # luffy_api在环境变量,直接注册---home
            'home'
        4.# 创建app时,要进入到apps文件夹下执行
             python ../../manage.py startapp home
        
5.导入模块,编辑器爆红,爆红不一定是真的错
   把加入到环境变量的路径--小路飞文件路径--右键-->>source root
        

后台日志封装

项目一般要记录日志,日志可以打印到控制台、日志可以写到日志文件中、日志存到某个库中、所有项目日志统一管理。日志平台:sentry:django写的服务,既可以收集日志、展示日志,又是开源的软件。

以后都使用日志logger.info()记录代码。

日志的作用

  1. 后期可以通过日志排查问题、分析错误
  2. 分析用户行为
  3. 过滤掉低级别的日志报错

django集成日志

djagno就是基于python内置logging模块的日志

  1. 在配置文件dev.py中加入日志配置---大字典

    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对象,以后只需要导入,直接使用对象写日志即可
    logger = logging.getLogger('django')
    
  3. 使用日志----直接导入(注意路径),直接使用logger.info...

    from utils.common_logger import logger
    from django.http import JsonResponse
    
    # 只是为了测试日志的使用
    def logger_test(ruquest):
        logger.info('info级别的日志')
        logger.error('error级别的日志')
        return JsonResponse({'name':'kiki'})
    

全局异常处理封装

drf处理了全局异常,只需要写个函数配置在配置文件中,出了异常这个函数就会执行。

封装全局异常的好处

  1. 给前端制定了统一返回格式
  2. 记录日志:出了异常,程序有问题,查看日志便于后期排查问题。

全局异常封装步骤

  1. utils中新建一个common_exception.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 记录日志 : 哪个ip地址,用户id是多少,访问哪个路径,执行哪个视图函数,出了什么错
        request = context.get('request')
        view = context.get('view')
        ip = request.META.get('REMOTE_ADDR')
        user_id = request.user.pk
        path = request.get_full_path()
        response = drf_exception_handler(exc, context)
        if response:
            logger.warning('drf出了异常,异常是:%s' % str(exc))
            # drf的异常已经处理了--->直接取detail 会有点小小的问题,碰到再解决
            res = Response({'code': 999, 'msg': response.data.get('detail', '服务器异常,请联系系统管理员')})
        else:
            # djagno的异常,咱们要处理
            logger.error(f'用户{user_id}使用{request.method}请求,请求地址{request.get_full_path()},视图函数是{str(view)},出错了的错误是{str(exc)}')
            res = Response({'code': 888, 'msg': '服务器异常,请联系系统管理员'})
    
        return res
    
  2. 配置文件中配置,有异常就会经过书写的异常函数

    REST_FRAMEWORK = {
                'EXCEPTION_HANDLER': 'utils.common_exceptions.exception_handler',
            }
    
  3. 视图函数测试数据,所有的报错都会被记录成日志,并处理成统一格式。

    from rest_framework.views import APIView
    from rest_framework.exceptions import APIException
    from rest_framework.response import Response
    
    # 只是为了测试异常是否正常处理
    class TestException(APIView):
        def get(self,request):
            # drf抛异常
            # raise APIException('drf抛异常')
            # 未知异常
            # l=[12,33,44]
            # print(9)
            # raise Exception('未知异常')
            return Response('ok') # ok是传给第一个参数data
    

封装Response--后台配置之二次封装response

drf提供的Response对象,不方便加入想要的code和msg字段,自己封装的Response类,都可以使用自己封装的返回格式,且公司一般都规定前端收到的返回格式都是固定的,如:

-{code:100,msg:提示,data:{}/[]}
-{code:100,msg:提示,token:asdfasd,user:kiki}

# 对Response进行封装,封装后,code,msg可以不传,不传就用默认的

封装response

  1. 在utils下新建common_response.py

  2. 封装APIResponse

    class APIResponse(Response):
        def __init__(self, code=100, msg='成功', status=None, headers=None, **kwargs):
            data = {'code': code, 'msg': msg}
            if kwargs:  # 有值,说明,传了 除了code msg   status headers 以外的,咱们都要返回给前端,放到这个data中
                data.update(kwargs) # 有的更新,没有的添加进去
            # Response(data=data,status=status,headers=headers)
            super().__init__(data=data, status=status, headers=headers)
    
            # 不要return,你可以这样做  self.data=data  self.status=status
    
  3. 导入使用,视图函数的方法,返回格式都是固定的

luffy数据库创建

root用户权限太高了,一般都是管理人员,如果开发人员是root权限,数据安全性就很差。一般给开发人员专门创建一个用户,只对当前项目的库有操作权限。

如何创建luffy库

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

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

3.查看用户
    select user,host,password from mysql.user; 
    只有root用户,要创建luffy用户

# 5.7往后的版本
    select user,host,authentication_string from mysql.user;

image

如何创建luffy用户

创建路飞用户,授予luffy库所有权限

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

1.配置任意ip都可以连入数据库的账户
   grant all privileges on luffy.* to 'luffy'@'%' identified by 'Luffy123?';
    # 把luffy库下所有表的权限都授予luffy_api这个用户,允许远程链接

2.由于数据库版本的问题,可能本地还连接不上,就给本地用户单独配置
    grant all privileges on luffy.* to 'luffy'@'localhost' identified by 'Luffy123?';
  # 把luffy库下所有表的权限都授予luffy_api这个用户,允许本地链接
3.刷新一下权限
    flush privileges;

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

# luffy_api连接方式:一条通过本地连接,一条通过远程连接
    通过本地连接:mysql -uroot -p密码
    通过远程连接:mysql -h ip地址 -p端口号 -u用户名 -p密码

问题?

image

项目连接库

# 项目操作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
        -人品不好,装不了,centos部署项目,后面会讲centos上如何装
        

# mysqlclient
pip install mysqlclient

###### 配置文件修改,连接mysql,使用路飞用户


# 用户名密码写死在代码中了,保证安全
name = os.environ.get('LUFFY_NAME', 'luffy')
password = os.environ.get('LUFFY_PASSWORD', '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周期:一个板块的周期
    -scrum敏捷项目管理

image

User模块用户表

# 你决定使用auth表扩写,项目一定不要先迁移,先建好用户表再迁移
	已经迁移完了,再想用auth的user表
    -删库,删迁移文件所有app
    -删admin和auth的迁移文件
    
# 用户表使用auth表扩写  pip install Pillow
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
    

开启media访问

# 配置文件加入
from django.views.static import serve
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

# 总路由中设置
# re_path('^media/(?P<path>.*)', serve, {'document_root': settings.MEDIA_ROOT})
path('media/<path:path>', serve, {'document_root': settings.MEDIA_ROOT})
# 访问
http://127.0.0.1:8000/media/icon/default.png
        
        
# 以后使用djagno的配置文件都用这个
from django.conf import settings

django的配置文件

# pathlib   # 3.6 以后,处理文件路径的模块,原来是os,
from pathlib import Path
import os
import sys

# 项目根路径
# 我们就是要让小路飞路径作为项目根路径
BASE_DIR = Path(__file__).resolve().parent.parent  # 项目根路径, 小路飞luffy_api路径 D:\pythonProject03\luffy_api\luffy_api
# print(BASE_DIR)
# 把 apps 路径加入到环境变量
sys.path.insert(0, os.path.join(BASE_DIR, 'apps'))
# 把BASE_DIR也加入到环境变量,以后直接从小路飞开始导起即可
sys.path.insert(0, str(BASE_DIR))
# print(sys.path)
# 以后从大路飞开始导起,或者小路飞开始导起,或者apps开始导起都可以


# 秘钥,涉及到加密的django中,都会用它
SECRET_KEY = 'django-insecure-!g(8l%fw_#t$pz$x4jdf#e3$b4+c%xzqyq@3zki08vj&i)z4k-'

# 项目是以debug模式运行,还是非debug模式运行

# 项目上线,要改成false
# debug=True 代码可以热更新
# 调试模式下,对开发者更友好:可以列出所有路径.报了错,前端能看到
DEBUG = False
# 它搭配debug=False,它的意思是,允许我的项目部署在哪个ip地址上,* 表示允许部署在所有地址上
ALLOWED_HOSTS = ['*']



# django 是多个app组成的,里面配置app,默认带的app,django内置的app
# django 是一个大而全的框架,有很多内置app:
#   admin后台管理,
#   auth权限管理,
#   contenttypes表中存app也表的关系,
#   sessions session表,django的session相关
#   messages:消息框架,flask讲闪现,是一样的东西
#  staticfiles:静态资源的

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',

    # 'luffy_api.apps.home',   # luffy_api在环境变量,直接从这一层开始导起, 太长了,以后就想 注册  home
    # 'luffy_api.apps.user'
    'home',
    'user'
]


# 中间件
MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',  # 安全相关中间件
    'django.contrib.sessions.middleware.SessionMiddleware', # session相关中间件
    'django.middleware.common.CommonMiddleware',            # 带不带 / 问题
    'django.middleware.csrf.CsrfViewMiddleware',            # csrf 认证,生成csrf串
    'django.contrib.auth.middleware.AuthenticationMiddleware', # 用户认证
    'django.contrib.messages.middleware.MessageMiddleware',  #消息框架相关
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]


# 根路由
ROOT_URLCONF = 'luffy_api.urls'

# 模板文件
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [BASE_DIR / 'templates'],  # 坑,模板路径用列表,可以有多个
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]


# 项目运行的配置---》项目上线运行,使用uwsgi 运行  application()
WSGI_APPLICATION = 'luffy_api.wsgi.application'

# 用户名密码写死在代码中了,保证安全
name = os.environ.get('LUFFY_NAME', 'luffy')
password = os.environ.get('LUFFY_PASSWORD', 'Luffy123?')
# 拓展:有的公司,直接有个配置中心---》服务--》只用来存放配置文件


# 数据库配置,mysql 主从搭建完,读写分离
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'luffy',
        'USER': name,
        'PASSWORD': password,
        'HOST': '127.0.0.1',
        'PORT': 3306
    },
}

#忽略掉
AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]


# 国际化
LANGUAGE_CODE = 'zh-hans'
TIME_ZONE = 'Asia/Shanghai'
USE_I18N = True
USE_L10N = True
USE_TZ = False


# 静态资源
STATIC_URL = '/static/'


# 
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

前后端分离的rbac项目演示

# 后台:https://gitee.com/liuqingzheng/rbac_manager
# 前端:https://gitee.com/liuqingzheng/vue_admin

关键前后端分离如何引入别人的页面样式

# 期终架构相关
	-前端---》看人家开源的前端项目,看不懂
    -第一种情况,vue+java====》分析有哪些接口,drf复写出来
	-第二种情况: 你新建前端项目,你看到它哪个页面好看,copy你里面去只要template和style  
    	-js东西自己写


# python运算符之位运算
https://zhuanlan.zhihu.com/p/370167569


# windows安装 mysql 5.7
https://zhuanlan.zhihu.com/p/571585588

python位运算

标签:封装,media,django,---,路飞,api,User,luffy,日志
From: https://www.cnblogs.com/zhanglanhua/p/17162273.html

相关文章