"""
|
Django settings for backend project.
|
|
Generated by 'django-admin startproject' using Django 2.2.17.
|
|
For more information on this file, see
|
https://docs.djangoproject.com/en/2.2/topics/settings/
|
|
For the full list of settings and their values, see
|
https://docs.djangoproject.com/en/2.2/ref/settings/
|
"""
|
import datetime
|
import os
|
import sys
|
|
from loguru import logger
|
|
from conf.env import *
|
|
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
|
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
sys.path.insert(0, BASE_DIR)
|
sys.path.insert(0, os.path.join(BASE_DIR, "apps"))
|
sys.path.insert(0, os.path.join(BASE_DIR, "extra_apps"))
|
|
# Quick-start development settings - unsuitable for production
|
# See https://docs.djangoproject.com/en/2.2/howto/deployment/checklist/
|
|
# SECURITY WARNING: keep the secret key used in production secret!
|
SECRET_KEY = "^v68x$m2x($7!z@8lt548otbgev)@on&tntu3qts^s2z3xx(_a"
|
|
# SECURITY WARNING: don't run with debug turned on in production!
|
DEBUG = locals().get("DEBUG", True)
|
ALLOWED_HOSTS = locals().get("ALLOWED_HOSTS", ["*"])
|
|
DEFAULT_AUTO_FIELD = "django.db.models.AutoField"
|
|
# Application definition
|
|
INSTALLED_APPS = [
|
"simpleui",
|
"django.contrib.admin",
|
"django.contrib.auth",
|
"django.contrib.contenttypes",
|
"django.contrib.sessions",
|
"django.contrib.messages",
|
"django.contrib.staticfiles",
|
"rest_framework",
|
"corsheaders",
|
"drf_yasg",
|
"django_celery_beat",
|
"django_celery_results",
|
"lunaruser",
|
"lunarlink",
|
]
|
|
MIDDLEWARE = [
|
"backend.utils.middleware.PerformanceAndExceptionLoggerMiddleware",
|
"corsheaders.middleware.CorsMiddleware",
|
"django.middleware.gzip.GZipMiddleware",
|
"log_request_id.middleware.RequestIDMiddleware",
|
"django.middleware.security.SecurityMiddleware",
|
"django.contrib.sessions.middleware.SessionMiddleware",
|
"django.middleware.common.CommonMiddleware",
|
"django.contrib.auth.middleware.AuthenticationMiddleware",
|
"django.contrib.messages.middleware.MessageMiddleware",
|
"django.middleware.clickjacking.XFrameOptionsMiddleware",
|
"backend.utils.middleware.VisitTimesMiddleware",
|
]
|
|
ROOT_URLCONF = "backend.urls"
|
|
TEMPLATES = [
|
{
|
"BACKEND": "django.template.backends.django.DjangoTemplates",
|
"DIRS": [os.path.join(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",
|
],
|
},
|
},
|
]
|
|
ASGI_APPLICATION = "backend.asgi.application"
|
WSGI_APPLICATION = "backend.wsgi.application"
|
|
# Database
|
# https://docs.djangoproject.com/en/2.2/ref/settings/#databases
|
|
DATABASES = {
|
"default": {
|
"ENGINE": "django.db.backends.mysql",
|
"NAME": DATABASE_NAME,
|
"USER": DATABASE_USER,
|
"PASSWORD": DATABASE_PASSWORD,
|
"HOST": DATABASE_HOST,
|
"PORT": DATABASE_PORT,
|
"OPTIONS": {
|
"charset": "utf8mb4", # 设置字符集为utf8mb4
|
},
|
}
|
}
|
|
# Password validation
|
# https://docs.djangoproject.com/en/2.2/ref/settings/#auth-password-validators
|
|
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",
|
},
|
]
|
|
# Internationalization
|
# https://docs.djangoproject.com/en/2.2/topics/i18n/
|
|
LANGUAGE_CODE = "zh-Hans"
|
|
TIME_ZONE = "Asia/Shanghai"
|
|
USE_I18N = True
|
|
USE_L10N = True
|
|
USE_TZ = False
|
|
# ================================================= #
|
# *************** REST_FRAMEWORK配置 *************** #
|
# ================================================= #
|
REST_FRAMEWORK = {
|
"DEFAULT_AUTHENTICATION_CLASSES": [
|
"backend.utils.auth.MyJWTAuthentication", # 设置全局的默认身份验证方案
|
],
|
"UNAUTHENTICATED_USER": None,
|
"UNAUTHENTICATED_TOKEN": None,
|
# json form 渲染
|
# 设置全局默认的解析器集
|
"DEFAULT_PARSER_CLASSES": [
|
"rest_framework.parsers.JSONParser", # 解析 JSON 请求内容
|
"rest_framework.parsers.FormParser", # 解析 HTML 表单内容
|
"rest_framework.parsers.MultiPartParser", # 解析多部分HTML表单内容,支持文件上传
|
"rest_framework.parsers.FileUploadParser", # 解析原始文件上传内容
|
],
|
"DEFAULT_PAGINATION_CLASS": "backend.utils.pagination.MyPageNumberPagination", # 默认分页器
|
"DEFAULT_PERMISSION_CLASSES": (
|
"rest_framework.permissions.IsAuthenticated", # 有经过身份认证确定用户身份才能访问
|
),
|
}
|
|
# ================================================= #
|
# ****************** simplejwt配置 ***************** #
|
# ================================================= #
|
JWT_AUTH = {
|
"JWT_EXPIRATION_DELTA": datetime.timedelta(days=1),
|
"JWT_ALLOW_REFRESH": True,
|
}
|
|
AUTH_USER_MODEL = "lunaruser.MyUser"
|
|
# ====================================#
|
# ****************swagger************#
|
# ====================================#
|
SWAGGER_SETTINGS = {
|
"DEFAULT_AUTO_SCHEMA_CLASS": "backend.utils.swagger.CustomSwaggerAutoSchema",
|
"SECURITY_DEFINITIONS": {
|
"Token": {"type": "apiKey", "name": "Authorization", "in": "header"},
|
},
|
# 接口文档中方法列表以首字母升序排列
|
"APIS_SORTER": "alpha",
|
# 如果支持json提交, 则接口文档中包含json输入框
|
"JSON_EDITOR": True,
|
# 方法列表字母排序
|
"OPERATIONS_SORTER": "alpha",
|
"VALIDATOR_URL": None,
|
"USE_SESSION_AUTH": False,
|
}
|
|
# Static files (CSS, JavaScript, Images)
|
# https://docs.djangoproject.com/en/2.2/howto/static-files/
|
|
STATIC_URL = "/django_static/"
|
|
# 指定static文件的路径,缺少这个配置,collectstatic无法加载extent.js
|
STATICFILES_DIRS = [os.path.join(BASE_DIR, "static")]
|
|
# collectstatic 之后的文件存放路径
|
STATIC_ROOT = os.path.join(BASE_DIR, "static_root")
|
|
for level in ["INFO", "WARNING", "ERROR"]:
|
logger.add(
|
f"logs/{level.lower()}.log",
|
format="{time:YYYY-MM-DD HH:mm:ss.SSS}"
|
" [pid:{process} -> thread:{thread.name}]"
|
" {level}"
|
" [{name}:{function}:{line}]"
|
" {message}",
|
level=level,
|
rotation="00:00",
|
retention="14 days",
|
)
|
|
LOGGING = {
|
"version": 1,
|
"disable_existing_loggers": True,
|
"formatters": {
|
"standard": {
|
"format": "%(levelname)-2s [%(asctime)s] [%(request_id)s] %(name)s: %(message)s",
|
"datefmt": "%Y-%m-%d %H:%M:%S",
|
},
|
"color": {
|
"()": "colorlog.ColoredFormatter",
|
"format": "%(green)s%(asctime)s [%(request_id)s] %(name)s %(log_color)s%(levelname)s [pid:%(process)d] "
|
"[%(filename)s->%(funcName)s:%(lineno)s] %(cyan)s%(message)s",
|
"log_colors": {
|
"DEBUG": "black",
|
"INFO": "white",
|
"WARNING": "yellow",
|
"ERROR": "red",
|
"CRITICAL": "bold_red",
|
},
|
}
|
# 日志格式
|
},
|
"filters": {
|
"request_id": {"()": "log_request_id.filters.RequestIDFilter"},
|
"require_debug_true": {
|
"()": "django.utils.log.RequireDebugTrue", # 过滤器,只有当setting的DEBUG = True时生效
|
},
|
},
|
"handlers": {
|
"mail_admins": {
|
"level": "ERROR",
|
"class": "django.utils.log.AdminEmailHandler",
|
"include_html": True,
|
},
|
"default": {
|
"level": "DEBUG",
|
"class": "logging.handlers.RotatingFileHandler",
|
"filename": os.path.join(BASE_DIR, "logs/info.log"),
|
"maxBytes": 1024 * 1024 * 50,
|
"backupCount": 5,
|
"formatter": "color",
|
"filters": ["request_id"],
|
},
|
"console": {
|
"level": "DEBUG",
|
"class": "logging.StreamHandler",
|
"formatter": "color",
|
"filters": ["request_id"],
|
},
|
},
|
"loggers": {
|
"django": {
|
"handlers": ["default", "console"],
|
"level": "INFO",
|
"propagate": True,
|
},
|
"lunarlink": {
|
"handlers": ["default", "console"],
|
"level": "INFO",
|
"propagate": True,
|
},
|
"httprunner": {
|
"handlers": ["default", "console"],
|
"level": "INFO",
|
"propagate": True,
|
},
|
},
|
}
|
|
# celery 配置
|
CELERY_BROKER_URL = MQ_URL # 消息队列地址
|
CELERY_RESULT_BACKEND = "django-db" # celery结果存储到数据库中
|
CELERY_TIMEZONE = TIME_ZONE # celery 时区问题
|
CELERY_BEAT_SCHEDULER = "django_celery_beat.schedulers:DatabaseScheduler" # Backend数据库
|
DJANGO_CELERY_BEAT_TZ_AWARE = False # 时区设置
|
CELERY_ENABLE_UTC = False # 时区设置
|
|
# 设置请求体的最大大小
|
DATA_UPLOAD_MAX_MEMORY_SIZE = 52428800 # 50M
|
|
LOG_REQUEST_ID_HEADER = "HTTP_X_REQUEST_ID"
|
GENERATE_REQUEST_ID_IF_NOT_IN_HEADER = True
|
REQUEST_ID_RESPONSE_HEADER = "RESPONSE_HEADER_NAME"
|
|
CORS_ALLOW_CREDENTIALS = True
|
CORS_ORIGIN_ALLOW_ALL = True
|
CORS_ORIGIN_WHITELIST = []
|
|
CORS_ALLOW_METHODS = (
|
"DELETE",
|
"GET",
|
"OPTIONS",
|
"PATCH",
|
"POST",
|
"PUT",
|
"VIEW",
|
)
|
|
CORS_ALLOW_HEADERS = (
|
"accept",
|
"accept-encoding",
|
"authorization",
|
"content-type",
|
"dnt",
|
"origin",
|
"user-agent",
|
"x-csrftoken",
|
"x-requested-with",
|
"Project",
|
)
|