开发环境配置
1. 这里案例项目名叫luffy,为luffy项目创建一个虚拟环境
>: mkvirtualenv luffy
2. 根据项目需求按装基础环境依赖(在cmd中执行)
>: pip install django==2.0.7
>: pip install djangorestframework
>: pip install pymysql
注意兼容问题:
如果想用Django 1.9 的版本,drf就用3.5.4版本
- 创建项目虚拟环境:
- 安装Django
- 安装djangorestframework
- 安装pymysql
创建Django项目
1.一般会为项目创建一个同名文件夹
>:cd Desktop # 切到桌面,这里将项目放到桌面
>:mkdir luffy # 在桌面创建存放项目的文件夹
2.在项目文件夹下创建django项目,这里项目名叫luffyapi
>: django-admin startproject luffyapi
3.用pycharm打开项目,并选择提前备好的虚拟环境
重构项目目录
├── luffyapi
├── logs/ # 项目运行时/开发时日志目录 - 文件夹
├── manage.py # 脚本文件
├── luffyapi/ # 项目主应用,开发时的代码保存 - 包
├── apps/ # 开发者的代码保存目录,以模块[子应用]为目录保存 - 包
├── libs/ # 第三方类库的保存目录[第三方组件、模块] - 包
├── settings/ # 配置目录 - 包
├── dev.py # 项目开发时的本地配置
└── prod.py # 项目上线时的运行配置
├── urls.py # 总路由
└── utils/ # 多个模块[子应用]的公共函数类库[自己开发的组件]
└── scripts/ # 保存项目运营时的测试脚本文件 - 文件夹
settings.py文件的修改
1.将setting.py文件中的内容拷贝到dev.py中,并将setting.py文件删除
2.修改 wsgi.py 与 manage.py 两个文件:
将启动配置文件由之前的settings.py改成现在的dev.py
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'luffyapi.settings.dev')
修改dev.py文件内容
- 国际化配置 django时间与时区问题
LANGUAGE_CODE = 'zh-hans'
TIME_ZONE = 'Asia/Shanghai'
USE_TZ = False
- 环境变量配置
环境变量操作:BASE_DIR与apps文件夹都要添加到环境变量
BASE_DIR: 是小luffy的绝对路径
import sys
sys.path.insert(0, BASE_DIR)
APPS_DIR = os.path.join(BASE_DIR, 'apps') # 拿到apps的绝对路径
sys.path.insert(1, APPS_DIR)
补充: 在写项目直接导入utils文件夹也不''错误提示'' 注意: 只有添加了环境变量的文件夹设置
修改启动配置
uwsgi.py
manage.py
测试默认配置文件是否是dev.py文件:
方法1:在任何一个__init__.py文件中测试默认配置文件是否是dev.py文件
from django.conf import settings
print(settings)
方法2:在测试文件夹 scripts中创建test_dg.py测试文件:
import os, django
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "luffyapi.settings.dev")
django.setup()
from django.conf import settings
print(settings) # <Settings "luffyapi.settings.dev"> 成功配置
日志配置
注意: 这里日志的配置是根据当前项目(重构目录后)配置的,里面的日志路径是根据项目来定的
- setting/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': '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, # 是否让日志信息继续冒泡给其他的日志处理系统
},
}
}
封装功能
封装logger
- utils/logging.py
import logging
logger = logging.getLogger('django')
二次封装异常处理exception
- utils/exception.py
from rest_framework.views import exception_handler as drf_exception_handler
from rest_framework.views import Response
from rest_framework import status
from utils.logging import logger
def exception_handler(exc, context):
response = drf_exception_handler(exc, context)
if response is None:
logger.error('%s - %s - %s' % (context['view'], context['request'].method, exc))
return Response({
'detail': '服务器错误'
}, status=status.HTTP_500_INTERNAL_SERVER_ERROR, exception=True)
return response
- settings/dev.py
REST_FRAMEWORK = {
# 异常配置
'EXCEPTION_HANDLER': 'utils.exception.exception_handler',
}
补充: 开发中可需要将print打印的内容输出到日志中
- mylogger.py
# encoding: utf-8
def make_print_to_file(path='./'):
'''
path, it is a path for save your log about fuction print
example:
use make_print_to_file() and the all the information of funtion print , will be write in to a log file
:return:
'''
import io # python2 需要加上IO模块,python3不需要
import os
# import config_file as cfg_file
import sys
import datetime
class Logger(object):
def __init__(self, filename="Default.log", path="./"):
self.terminal = sys.stdout
self.log = io.open(os.path.join(path, filename), "a", encoding='utf8', )
def write(self, message):
self.terminal.write(message)
self.log.write(unicode(message))
def flush(self):
pass
fileName = datetime.datetime.now().strftime('day' + '%Y_%m_%d')
sys.stdout = Logger(fileName + '.log', path=path)
#############################################################
# 这里输出之后的所有的输出的print 内容即将写入日志
#############################################################
print(fileName.center(60, '*'))
if __name__ == '__main__':
make_print_to_file(path='D:\seafile-server\logs')
#############################################################
# 这里输出之后的所有的输出的print 内容即将写入日志
#############################################################
print("1234124")
print("1234124")
二次封装响应Response
- utils/response.py
from rest_framework.response import Response
class APIResponse(Response):
def __init__(self, data_status=0, data_msg='ok', results=None, http_status=None, headers=None, exception=False, **kwargs):
data = {
'status': data_status,
'msg': data_msg,
}
if results is not None:
data['results'] = results
data.update(kwargs)
super().__init__(data=data, status=http_status, headers=headers, exception=exception)
创建app
进入apps文件夹内,在此文件夹内用相对路径找到manage.py文件创建app
创建user表
dev.py
# 自定义User表
AUTH_USER_MODEL = 'user.User
user/models.py
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
字段
class Meta:
verbose_name = '用户表'
verbose_name_plural = verbose_name
def __str__(self):
return self.username