04-luffy后台-路径配置及其他
luffy后台-路径配置及其他
一、环境变量
1. 开发dev.py中路径的处理
问题:应用的创建,dev.py中注册路径无法生效了
# 先切换到apps目录, 再执行以下命令
cd luffyapi\apps\
# 创建应用: 提示, startapp在哪执行,就把app创建在哪
python3.6 ../../manage.py startapp home
python3.6 ../../manage.py startapp user
dev.py 中配置
# 1. 导入sys
import sys
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# 2. 把当前项目中与项目名同名的小的luffyapi的这个路径加入到环境变量。 目的: 提供INSTALLED_APPS中应用的注册, 在项目启动时会被项目加载。
sys.path.insert(0, BASE_DIR)
# 3. 把apps的路径加入到环境变量。 目的: 提供在应用下导入语法 from views import aaa
sys.path.insert(1, os.path.join(BASE_DIR, 'apps'))
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
# 4. 现在就可以将刚刚的引用注册生效了。
'user',
'home'
]
print(sys.path)
2. 解决不在项目中导入的飘红问题
提示: 在apps中的应用下, 使用from viwes import aaa
这种导入就是会飘红,但是导入没有错误,只是不在项目中的导入, 就会出现这种问题.
二、封装logger
1. 开发人员
真实项目上线后,日志文件打印级别不能过低,因为一次日志记录就是一次文件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': 'DEBUG',
'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, # 是否让日志信息继续冒泡给其他的日志处理系统
},
}
}
2. utils / loggin.py
# 如果加了名字这里就是配置文件中日志对象loggers下的名字要对应
'''
'loggers': {
'django': {
'handlers': ['console', 'file'],
'propagate': True, # 是否让日志信息继续冒泡给其他的日志处理系统
},
}
'''
import logging
logger = logging.getLogger('django')
三、封装项目异常处理
1. utils / exception.py
from rest_framework.views import exception_handler
from rest_framework import status
from utils.logging import log
from .response import CommonResponse
def common_exception_handler(exc, context):
response = exception_handler(exc, context)
# 记录日志: context['view'] 是TextView的对象,想拿出这个对象对应的类名
log.error(f'{context.get("view").__class__.__name__}:{exc}')
if not response:
obj = CommonResponse(code=2000, messages='error', results=str(exc),
status=status.HTTP_500_INTERNAL_SERVER_ERROR)
else:
obj = CommonResponse(code=2000, messages='error', results=response.data,
status=status.HTTP_500_INTERNAL_SERVER_ERROR)
return obj
2. settings.py
REST_FRAMEWORK = {
'EXCEPTION_HANDLER': 'utils.exception.common_exception_handler',
}
四、封装Response模块
from rest_framework.response import Response
class APIResponse(Response):
def __init__(self, code=1000, messages='ok', results=None,
status=None, template_name=None, headers=None,
exception=False, content_type=None,
**kwargs):
data = {
'code': code,
'messages': messages,
}
data.update(kwargs)
if results:
data['results'] = results
super().__init__(data=data, status=status,
template_name=template_name, headers=headers,
exception=exception, content_type=content_type)
五、路由组件配置
from rest_framework.routers import Route, DynamicRoute, SimpleRouter as DRFSimpleRouter
class SimpleRouter(DRFSimpleRouter):
routes = [
# List route. /资源s/
Route(
url=r'^{prefix}{trailing_slash}$',
mapping={
'get': 'list', # 群查
'post': 'create', # 单增、群增
'put': 'multiple_update', # 群整改
'patch': 'multiple_partial_update', # 群局改
'delete': 'multiple_destroy', # 群删
},
name='{basename}-list',
detail=False,
initkwargs={'suffix': 'List'}
),
# Dynamically generated list routes. Generated using
# @action(detail=False) decorator on methods of the viewset.
DynamicRoute(
url=r'^{prefix}/{url_path}{trailing_slash}$',
name='{basename}-{url_name}',
detail=False,
initkwargs={}
),
# Detail route. /资源s/(pk)/
Route(
url=r'^{prefix}/{lookup}{trailing_slash}$',
mapping={
'get': 'retrieve', # 单查
'put': 'update', # 单整改
'patch': 'partial_update', # 单局改
'delete': 'destroy' # 单删
},
name='{basename}-detail',
detail=True,
initkwargs={'suffix': 'Instance'}
),
# Dynamically generated detail routes. Generated using
# @action(detail=True) decorator on methods of the viewset.
DynamicRoute(
url=r'^{prefix}/{lookup}/{url_path}{trailing_slash}$',
name='{basename}-{url_name}',
detail=True,
initkwargs={}
),
]
# 对外提供十大接口的router对象
router = SimpleRouter()
# eg: router.register('users', UserModelViewSet, basename='user')
"""
/users/
'get': 'list', # 群查
'post': 'create', # 单增、群增
'put': 'multiple_update', # 群整改
'patch': 'multiple_partial_update', # 群局改
'delete': 'multiple_destroy', # 群删
/users/(pk)/
'get': 'retrieve', # 单查
'put': 'update', # 单整改
'patch': 'partial_update', # 单局改
'delete': 'destroy' # 单删
"""