blog/docs/code/django/setting.md

22 KiB
Raw Permalink Blame History

title date tags categories author
Django的项目设置Setting 2020-10-30 17:05:10
Django
Django
Anges黎梦

基础

DJANGO_SETTING_MODULE环境变量让settings模块被包含到python可以找到的目录下开发情况下不需要我们通常会在当前文件夹运行python可以搜索到。如果需要运行在其他服务器上就必须指定DJANGO_SETTINGS_MODULE变量。

默认设定

一个django的settings文件不需要我们手动去设置所有项目因为系统已经默认设置好了。我们只需要修改我们使用的设

定就好了。默认的设置在django/conf/global_settings.py文件中。django在编译时先载入global_settings.py中的配置然后加载指定的settings文件重写改变的设定。

好了,步入正文。

前面的随笔中我们经常会改setting配置也经常将一些配置混淆今天主要是将一些常见的配置做一个汇总。

项目配置

通过os模块获取当前项目在系统的具体路径

import os

# 项目路径
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

##密钥配置

随机值,在项目创建的时候生成,主要用于重要数据的加密处理,提高系统的安全性, 主要用于用户密码CSRF机制和会话Session等数据加密。

SECRET_KEY = 'g(eqo*xohqzl9-&&k)-+@5^&_xd+9s9muhe7iy#6$-gv_s_e#f'

调试模式和域名访问权限

调试模式为布尔值,在开发调试过程中,自动检测代码是否发生更改,根据检测结果执行是否刷新重启系统。

域名访问权限,设置可访问的域名,默认值为空。

当开启调试模式时可访问域名为空则项目只允许以loaclhost或者127.0.0.1在浏览器访问。

在生产环境配置时需要关闭调试模式并且此时的ALLOWED_HOSTS为必填项。

ALLOWED_HOSTS = ['*'] 表示允许所有域名访问。

# SECURITY WARNING: don't run with debug turned on in production!
# 生产环境配置
DEBUG = False
ALLOWED_HOSTS = ['*']  

# 测试环境配置
DEBUG = True
ALLOWED_HOSTS = []

app路径

app列表django项目里包含了哪些内容。

INSTALLED_APPS = [
    'django.contrib.admin',   # 内置的后台管理系统
    'django.contrib.auth',   # 内置的用户认证系统
    'django.contrib.contenttypes',   # 记录项目中所有model元数据Django自带的ORM框架
    'django.contrib.sessions',    # 会话功能
    'django.contrib.messages',   # 消息提示功能
    'django.contrib.staticfiles',   # 查找静态资源路径
    'study.apps.StudyConfig',    # 自定义App
]

中间件

中间件MIDDLEWARE是处理Django的request和response对象的钩子。

他的主要作用是处理用户请求信息。

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',   # 内置的安全机制,保护用户和网站的通信安全
    'django.contrib.sessions.middleware.SessionMiddleware',  # 会话session功能
    'django.middleware.common.CommonMiddleware',   # 处理请求信息,规范化请求内容。
    'django.middleware.csrf.CsrfViewMiddleware',        # 开启CSRF防护功能
    'django.contrib.auth.middleware.AuthenticationMiddleware',   # 开启内置的用户认证系统
    'django.contrib.messages.middleware.MessageMiddleware',   # 开启内置的信息提示功能
    'django.middleware.clickjacking.XFrameOptionsMiddleware',   # 防止恶意程序点击劫持。

    'django.middleware.locale.LocalMiddleware',   # 支持中文语言
]

模板路径

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',   # 定义模板引擎,用户识别模板里面的变量和指令
        'DIRS': [os.path.join(BASE_DIR, 'templates')]    # 设置模板所在的路径,可配置多个路径
        # 数据类型列表list[os.path.join(BASE_DIR, 'templates'),os.path.join(BASE_DIR, 'study/templates')]
        ,
        'APP_DIRS': True,   # 是否在app中查找模板文件
        # 用于填充在RequestContext中上下文的调用函数一般情况不用修改
        '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',
            ],
        },
    },
]

数据库配置

如果使用django的默认sqlite3数据库则不需要改。

django一共提供了4种数据引擎每一种引擎对应一种数据库。

django.db.backends.sqlite3
django.db.backends.postgresql
django.db.backends.mysql
django.db.backends.oracle
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}

如果使用mysql数据库需要将上述数据库注掉修改如下

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'blog',   # 数据库名称
        'USER': 'root',   #你的数据库用户名
        'PASSWORD':'' ,   #你的数据库密码
        'HOST':'',        #你的数据库主机留空默认为localhost
        'PORT':'3306'     #你的数据库端口
    }
}

并且需要在应用的__init__.py文件添加

import pymysql
pymysql.install_as_MySQLdb()

语言配置

django的目录下django/conf/locale可以找到很多的语言包选择你想要配置的语言包添加进去配置。

zh_Hans代表中文简体

zh_Hant代表中文繁体

LANGUAGE_CODE = 'en-us'    #  默认英文
LANGUAGE_CODE = 'zh-Hans'    # 修改为中文

时间配置

TIME_ZONE = 'UTC'
TIME_ZONE = 'Asia/Shanghai'

时区设置

因为Mysql存储的时间不能灵活设置时区不像datetime对象有一项参数专门指定时区所以为了统一全球的时间必须使用国际标准时间UTC否则就会乱套。所有时间在存如数据库前必须转换成UTC时间。比如北京时间8点存入mysql变成0点UTC

一般不跨时区的应用可以不使用时区即在settings.py设置

USE_TZ = True

USE_TZ = False

静态文件目录

这个路径只用于django提供的静态资源加载服务。

若部署之后,则这里的配置需要更改。

STATIC_URL = '/static/' #调用时目录
STATICFILES_DIRS=[
 os.path.join(BASE_DIR,"static"), #具体路径
]
# 静态资源文件
STATICFILES_DIRS = (os.path.join(BASE_DIR, "statics"),)   # 现添加的配置,这里是元组,注意逗号
#  我们一般只用 STATIC_URL但STATIC_URL会按着你的STATICFILES_DIRS去找

自定义用户表

如果数据库中的UserInfo(用户表)继承django内置AbstractUser

1model需导入

from django.contrib.auth.models import AbstractUser

2配置文件

AUTH_USER_MODEL = "应用名.UserInfo"

session存储的相关配置

1数据库配置默认

Django默认支持Session并且默认是将Session数据存储在数据库中django_session 表中。
配置 settings.py
 SESSION_ENGINE = 'django.contrib.sessions.backends.db' # 引擎(默认)
 SESSION_COOKIE_NAME  "sessionid"   # Session的cookie保存在浏览器上时的keysessionid随机字符串默认
 SESSION_COOKIE_PATH  "/"    # Session的cookie保存的路径默认
 SESSION_COOKIE_DOMAIN = None    # Session的cookie保存的域名默认
 SESSION_COOKIE_SECURE = False    # 是否Https传输cookie默认
 SESSION_COOKIE_HTTPONLY = True    # 是否Session的cookie只支持http传输默认
 SESSION_COOKIE_AGE = 1209600    # Session的cookie失效日期2周默认
 SESSION_EXPIRE_AT_BROWSER_CLOSE = False   # 是否关闭浏览器使得Session过期默认
 SESSION_SAVE_EVERY_REQUEST = False   # 是否每次请求都保存Session默认修改之后才保存默认

2缓存配置

配置 settings.py
 SESSION_ENGINE = 'django.contrib.sessions.backends.cache' # 引擎
 SESSION_CACHE_ALIAS = 'default'    # 使用的缓存别名默认内存缓存也可以是memcache此处别名依赖缓存的设置
 SESSION_COOKIE_NAME  "sessionid"   # Session的cookie保存在浏览器上时的keysessionid随机字符串
 SESSION_COOKIE_PATH  "/"    # Session的cookie保存的路径
 SESSION_COOKIE_DOMAIN = None    # Session的cookie保存的域名
 SESSION_COOKIE_SECURE = False    # 是否Https传输cookie
 SESSION_COOKIE_HTTPONLY = True    # 是否Session的cookie只支持http传输
 SESSION_COOKIE_AGE = 1209600    # Session的cookie失效日期2周
 SESSION_EXPIRE_AT_BROWSER_CLOSE = False   # 是否关闭浏览器使得Session过期
 SESSION_SAVE_EVERY_REQUEST = False   # 是否每次请求都保存Session默认修改之后才保存

3默认配置

配置 settings.py
 SESSION_ENGINE = 'django.contrib.sessions.backends.file' # 引擎
 SESSION_FILE_PATH = None     # 缓存文件路径如果为None则使用tempfile模块获取一个临时地址tempfile.gettempdir() 
 SESSION_COOKIE_NAME  "sessionid"    # Session的cookie保存在浏览器上时的keysessionid随机字符串
 SESSION_COOKIE_PATH  "/"     # Session的cookie保存的路径
 SESSION_COOKIE_DOMAIN = None    # Session的cookie保存的域名
 SESSION_COOKIE_SECURE = False    # 是否Https传输cookie
 SESSION_COOKIE_HTTPONLY = True    # 是否Session的cookie只支持http传输
 SESSION_COOKIE_AGE = 1209600    # Session的cookie失效日期2周
 SESSION_EXPIRE_AT_BROWSER_CLOSE = False   # 是否关闭浏览器使得Session过期
 SESSION_SAVE_EVERY_REQUEST = False    # 是否每次请求都保存Session默认修改之后才保存

注意:

  • 也可以自定义配置 但是自定义的配置都要写到配置文件最后 代码中使用时可以导入配置
from django.conf import settings
settings.配置名
  • 上面所有配置都是针对特定问题需要修改的 系统默认配置不做说明

  • 上面配置只是前面django系列随笔所遇到的常用配置 后续所遇配置都会逐步在此随笔中持续添加跟新

日志配置详解

Logger

记录器是记录系统的入口点。每个记录器都是一个命名存储桶,可以将消息写入进行处理。

记录器配置为具有日志级别。此日志级别描述了记录器将处理的消息的严重性。Python定义了以下日志级别

  • DEBUG:用于调试目的的低级系统信息
  • INFO:一般系统信息
  • WARNING:描述已发生的小问题的信息。
  • ERROR:描述已发生的主要问题的信息。
  • CRITICAL:描述已发生的严重问题的信息。

一旦记录器确定需要处理消息,它就会传递给处理程序

处理程序

处理程序是确定记录器中每条消息发生情况的引擎。它描述了特定的日志记录行为,例如将消息写入屏幕,文件或网络套接字。

与记录器一样,处理程序也具有日志级别。如果日志记录的日志级别未达到或超过处理程序的级别,则处理程序将忽略该消息。

记录器可以有多个处理程序,每个处理程序可以具有不同的日志级别。以这种方式,可以根据消息的重要性提供不同形式的通知。

过滤器

  • 过滤器用于提供对从记录器到处理程序的日志记录传递的额外控制。
  • 默认情况下,将处理满足日志级别要求的任何日志消息。但是,通过安装筛选器,您可以在日志记录过程中添加其他条件
    • 例如,您可以安装仅允许ERROR发出来自特定源的消息的过滤器。
  • 过滤器还可用于在发出之前修改日志记录。
    • 例如,如果满足一组特定条件,您可以编写一个过滤器,将ERROR日志记录降级 为WARNING记录。
  • 过滤器可以安装在记录器或处理器上; 可以在链中使用多个过滤器来执行多个过滤操作。

格式化程序

最终日志记录需要呈现为文本。格式化程序描述该文本的确切格式。格式化程序通常由包含LogRecord属性的Python格式化字符串组成 ; 但是,您也可以编写自定义格式化程序来实现特定的格式化行为。

使用日志记录

配置记录器,处理程序,过滤器和格式化程序后,需要将日志记录调用放入代码中。使用日志框架非常简单。这是一个例子:

# import the logging library
import logging

# Get an instance of a logger
logger = logging.getLogger(__name__)

def my_view(request, arg1, arg):
    ...
    if bad_mojo:
        # Log an error message
        logger.error('Something went wrong!')

配置日志记录

常用配置日志配置例子2个以供大家参考。

import time

cur_path = os.path.dirname(os.path.realpath(__file__))  # log_path是存放日志的路径
log_path = os.path.join(os.path.dirname(cur_path), 'logs')
if not os.path.exists(log_path): os.mkdir(log_path)  # 如果不存在这个logs文件夹就自动创建一个
BASE_LOG_DIR = os.path.join(BASE_DIR, "log")
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'formatters': {
        'standard': {
            'format': '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]'
                      '[%(levelname)s][%(message)s]'
        },
        'simple': {
            'format': '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s'
        },
        'collect': {
            'format': '%(message)s'
        }
    },
    'filters': {
        'require_debug_true': {
            '()': 'django.utils.log.RequireDebugTrue',
        },
    },
    'handlers': {
        'console': {
            'level': 'DEBUG',
            'filters': ['require_debug_true'],  # 只有在Django debug为True时才在屏幕打印日志
            'class': 'logging.StreamHandler',
            'formatter': 'simple'
        },
        'SF': {
            'level': 'INFO',
            'class': 'logging.handlers.RotatingFileHandler',  # 保存到文件,根据文件大小自动切
            'filename': os.path.join(BASE_LOG_DIR, "xxx_info.log"),  # 日志文件
            'maxBytes': 1024 * 1024 * 50,  # 日志大小 50M
            'backupCount': 3,  # 备份数为3  xx.log --> xx.log.1 --> xx.log.2 --> xx.log.3
            'formatter': 'standard',
            'encoding': 'utf-8',
        },
        'TF': {
            'level': 'INFO',
            'class': 'logging.handlers.TimedRotatingFileHandler',  # 保存到文件,根据时间自动切
            'filename': os.path.join(BASE_LOG_DIR, "xxx_info.log"),  # 日志文件
            'backupCount': 3,  # 备份数为3  xx.log --> xx.log.2018-08-23_00-00-00 --> xx.log.2018-08-24_00-00-00 --> ...
            'when': 'D',  # 每天一切, 可选值有S/秒 M/分 H/小时 D/天 W0-W6/周(0=周一) midnight/如果没指定时间就默认在午夜
            'formatter': 'standard',
            'encoding': 'utf-8',
        },
        'error': {
            'level': 'ERROR',
            'class': 'logging.handlers.RotatingFileHandler',  # 保存到文件,自动切
            'filename': os.path.join(BASE_LOG_DIR, "xxx_err.log"),  # 日志文件
            'maxBytes': 1024 * 1024 * 5,  # 日志大小 50M
            'backupCount': 5,
            'formatter': 'standard',
            'encoding': 'utf-8',
        },
        'collect': {
            'level': 'INFO',
            'class': 'logging.handlers.RotatingFileHandler',  # 保存到文件,自动切
            'filename': os.path.join(BASE_LOG_DIR, "xxx_collect.log"),
            'maxBytes': 1024 * 1024 * 50,  # 日志大小 50M
            'backupCount': 5,
            'formatter': 'collect',
            'encoding': "utf-8"
        }
    },
    'loggers': {
        '': {  # 默认的logger应用如下配置
            'handlers': ['SF', 'console', 'error'],  # 上线之后可以把'console'移除
            'level': 'DEBUG',
            'propagate': True,
        },
        'collect': {  # 名为 'collect'的logger还单独处理
            'handlers': ['console', 'collect'],
            'level': 'INFO',
        }
    },
}
LOGGING = {
    'version': 1,
    'disable_existing_loggers': True,
    'formatters': {
        # 日志格式
        'standard': {
            'format': '[%(asctime)s] [%(filename)s:%(lineno)d] [%(module)s:%(funcName)s] '
                      '[%(levelname)s]- %(message)s'},
        'simple': {  # 简单格式
            'format': '%(levelname)s %(message)s'
        },
    },
    # 过滤
    'filters': {
    },
    # 定义具体处理日志的方式
    'handlers': {
        # 默认记录所有日志
        'default': {
            'level': 'INFO',
            'class': 'logging.handlers.RotatingFileHandler',
            'filename': os.path.join(log_path, 'all-{}.log'.format(time.strftime('%Y-%m-%d'))),
            'maxBytes': 1024 * 1024 * 5,  # 文件大小
            'backupCount': 5,  # 备份数
            'formatter': 'standard',  # 输出格式
            'encoding': 'utf-8',  # 设置默认编码,否则打印出来汉字乱码
        },
        # 输出错误日志
        'error': {
            'level': 'ERROR',
            'class': 'logging.handlers.RotatingFileHandler',
            'filename': os.path.join(log_path, 'error-{}.log'.format(time.strftime('%Y-%m-%d'))),
            'maxBytes': 1024 * 1024 * 5,  # 文件大小
            'backupCount': 5,  # 备份数
            'formatter': 'standard',  # 输出格式
            'encoding': 'utf-8',  # 设置默认编码
        },
        # 控制台输出
        'console': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',
            'formatter': 'standard'
        },
        # 输出info日志
        'info': {
            'level': 'INFO',
            'class': 'logging.handlers.RotatingFileHandler',
            'filename': os.path.join(log_path, 'info-{}.log'.format(time.strftime('%Y-%m-%d'))),
            'maxBytes': 1024 * 1024 * 5,
            'backupCount': 5,
            'formatter': 'standard',
            'encoding': 'utf-8',  # 设置默认编码
        },
    },
    # 配置用哪几种 handlers 来处理日志
    'loggers': {
        # 类型 为 django 处理所有类型的日志, 默认调用
        'django': {
            'handlers': ['default', 'console'],
            'level': 'INFO',
            'propagate': False
        },
        # log 调用时需要当作参数传入
        'log': {
            'handlers': ['error', 'info', 'console', 'default'],
            'level': 'INFO',
            'propagate': True
        },
    }
}

添加发送邮件

#管理员邮箱
ADMINS = (
 ('laixintao','*******@163.com'),
)
  
#非空链接却发生404错误发送通知MANAGERS
SEND_BROKEN_LINK_EMAILS = True
MANAGERS = ADMINS
  
#Email设置
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST= 'smtp.163.com'#QQ邮箱SMTP服务器(邮箱需要开通SMTP服务)
EMAIL_PORT= 25 #QQ邮箱SMTP服务端口
EMAIL_HOST_USER = '**********@163.com' #我的邮箱帐号
EMAIL_HOST_PASSWORD = '**************' #授权码
EMAIL_SUBJECT_PREFIX = 'website' #为邮件标题的前缀,默认是'[django]'
EMAIL_USE_TLS = True #开启安全链接
DEFAULT_FROM_EMAIL = SERVER_EMAIL = EMAIL_HOST_USER #设置发件人
  
#logging日志配置
LOGGING = {
 'version': 1,
 'disable_existing_loggers': True,
 'formatters': {#日志格式 
 'standard': {
  'format': '%(asctime)s [%(threadName)s:%(thread)d] [%(name)s:%(lineno)d] [%(module)s:%(funcName)s] [%(levelname)s]- %(message)s'} 
 },
 'filters': {#过滤器
 'require_debug_false': {
  '()': 'django.utils.log.RequireDebugFalse',
  }
 },
 'handlers': {#处理器
 'null': {
  'level': 'DEBUG',
  'class': 'logging.NullHandler',
 },
 'mail_admins': {#发送邮件通知管理员
  'level': 'ERROR',
  'class': 'django.utils.log.AdminEmailHandler',
  'filters': ['require_debug_false'],# 仅当 DEBUG = False 时才发送邮件
  'include_html': True,
 },
 'debug': {#记录到日志文件(需要创建对应的目录,否则会出错)
  'level':'DEBUG',
  'class':'logging.handlers.RotatingFileHandler',
  'filename': os.path.join(BASE_DIR, "log",'debug.log'),#日志输出文件
  'maxBytes':1024*1024*5,#文件大小 
  'backupCount': 5,#备份份数
  'formatter':'standard',#使用哪种formatters日志格式
 },
 'console':{#输出到控制台
  'level': 'DEBUG',
  'class': 'logging.StreamHandler',
  'formatter': 'standard',
 },
 },
 'loggers': {#logging管理器
 'django': {
  'handlers': ['console'],
  'level': 'DEBUG',
  'propagate': False
 },
 'django.request': {
  'handlers': ['debug','mail_admins'],
  'level': 'ERROR',
  'propagate': True,
 },
 # 对于不在 ALLOWED_HOSTS 中的请求不发送报错邮件
 'django.security.DisallowedHost': {
  'handlers': ['null'],
  'propagate': False,
 },
 } 
}

以上的配置文件中,有三个日志处理器。分别是:

  • django.request'django的request发生error会自动记录然后使用debug将信息记录到文件还有mail_admins将信息通过邮件发送给管理员。这里邮件的功能非常棒并不是一个纯文本信息而是一个html文件和我们在浏览器看到的错误页面一模一样要正常使用邮件功能需要像我一样配置一下上面的邮件发件人信息。我是直接去网易申请了一个邮箱。要格外注意三点
    • 一定要去邮件服务商开启SMTP服务
    • 不同的邮件服务商可能有一些特殊的设置,比如网易,会给你一个客户端授权码,这个才是密码,而不是网页的登录密码。
    • 注意服务商有没有对发信频率的限制。
  • django'使用console处理器将信息输出。在开发的时候就可以使用这个处理器什么print 太low了
  • 最后一个处理器见注

8日志模块流程图

img