" name="sm-site-verification"/>
侧边栏壁纸
博主头像
PySuper 博主等级

千里之行,始于足下

  • 累计撰写 231 篇文章
  • 累计创建 15 个标签
  • 累计收到 2 条评论

目 录CONTENT

文章目录
Web

Djangi--基础配置

PySuper
2024-09-14 / 0 评论 / 0 点赞 / 16 阅读 / 0 字
温馨提示:
所有牛逼的人都有一段苦逼的岁月。 但是你只要像SB一样去坚持,终将牛逼!!! ✊✊✊
  • 使用env配置文件,添加多环境配置

  • 配置MySQL数据库连接池

  • 使用第三方中间件、自定义中间件

  • 自定义logging配置(日志文件)

  • rest_framework配置(自定义的配置很多)

  • 添加非对称加密

  • 图片验证码配置

  • JWT相关配置

settings.py

import datetime
from datetime import timedelta
from pathlib import Path

import environ

# noinspection PyUnresolvedReferences
from utils.log.logger import *

# START
# ------------------------------------------------------------------------------
ROOT_DIR = Path(__file__).resolve(strict=True).parent.parent.parent

env = environ.Env()

READ_DOT_ENV_FILE = env.bool("DJANGO_READ_DOT_ENV_FILE", default=True)
if READ_DOT_ENV_FILE:
    env.read_env(str(ROOT_DIR / ".env/.env.local"))

# GENERAL
# ------------------------------------------------------------------------------
DEBUG = env.bool("DJANGO_DEBUG", False)
TIME_ZONE = "Asia/Shanghai"
LANGUAGE_CODE = "en-us"
SITE_ID = 1
USE_I18N = True
USE_L10N = True
USE_TZ = True
LOCALE_PATHS = [str(ROOT_DIR / "locale")]

# DATABASES
# ------------------------------------------------------------------------------
DATABASES = {
    "default": {
        **env.db("DATABASE_URL", default="mysql://your_database_url"),
        "ENGINE": "django.db.backends.mysql",
        "CONN_MAX_AGE": 60 * 60 * 6,
        "ATOMIC_REQUESTS": True,
        "OPTIONS": {
            "init_command": 'SET sql_mode="STRICT_TRANS_TABLES"',
            "charset": "utf8mb4",
            "use_unicode": True,
            "sql_mode": "traditional",
        },
        "POOL": {
            "name": "default",
            "max_size": 20,  # 连接池最大连接数
            "min_size": 1,  # 连接池最小连接数
            "max_overflow": 10,  # 连接池溢出容量
            "timeout": 30,  # 获取连接超时时间
            "recycle": 3600,  # 连接回收时间(秒)
            "echo": False,  # 是否打印SQL语句
            "pre_ping": True,  # 每次获取连接前ping一下,确保连接可用
        },
    }
}
# 自定义数据库路由器
DATABASE_ROUTERS = ["utils.router.db.DatabaseAppsRouter"]
# 自定义应用与数据库映射
DATABASE_APPS_MAPPING = {
    # example:
    # 'app_name':'database_name',
    "indicator": "postkeeper",
}

DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"

# URLS
# ------------------------------------------------------------------------------
ROOT_URLCONF = "config.urls"
WSGI_APPLICATION = "config.wsgi.application"

# APPS
# ------------------------------------------------------------------------------
INSTALLED_APPS = [
    # Django自带的应用
    # TODO:这里的 apps 按需添加,不用的可以删除,缩减Django的体积
    "django.contrib.auth",  # 用户认证系统
    "django.contrib.contenttypes",  # 内容类型框架
    # "django.contrib.sessions",  # 会话框架
    # "django.contrib.sites",  # 网站框架
    "django.contrib.messages",  # 消息框架
    # "django.contrib.staticfiles",  # 静态文件管理
    # "django.contrib.humanize",  # 方便的模板标签
    "django.contrib.admin",  # 管理后台
    # "django.forms",  # 表单处理
    # "django.contrib.humanize",  # 提供人性化的格式化工具
    # "django.contrib.sitemaps",  # 网站地图框架
    # "django.contrib.flatpages",  # 静态页面管理
    # 第三方应用
    # "simpleui",  # 简单的用户界面
    "allauth",  # 用于用户认证和注册的库
    "allauth.account",  # 处理用户账户的功能
    "allauth.socialaccount",  # 支持社交账户登录
    # "django_celery_beat",  # 用于定时任务调度
    "rest_framework",  # Django REST框架
    "rest_framework.authtoken",  # 提供基于Token的认证
    "rest_framework_simplejwt.token_blacklist",  # JWT黑名单支持
    "corsheaders",  # 处理跨域请求的库
    "drf_spectacular",  # 用于生成API文档
    "django_filters",  # 用于 Django 的过滤器
    # "django_rest_passwordreset",  # 用于重置密码的 REST API
    # "django_celery_results",  # 用于存储 Celery 任务结果
    # "django_extensions",  # 提供额外的管理命令和工具
    # "debug_toolbar",  # 用于调试的工具栏
    # "dauthz.apps.DauthzConfig",  # 权限管理应用
    # 本地应用
    "users",
]

# MIGRATIONS
# ------------------------------------------------------------------------------
MIGRATION_MODULES = {"sites": "django.contrib.sites.migrations"}

# AUTHENTICATION
# ------------------------------------------------------------------------------
AUTHENTICATION_BACKENDS = [
    "django.contrib.auth.backends.ModelBackend",
    "allauth.account.auth_backends.AuthenticationBackend",
]
AUTH_USER_MODEL = "users.User"
LOGIN_REDIRECT_URL = "users:redirect"
LOGIN_URL = "account_login"

# PASSWORDS
# ------------------------------------------------------------------------------
PASSWORD_HASHERS = [
    "django.contrib.auth.hashers.Argon2PasswordHasher",
    "django.contrib.auth.hashers.PBKDF2PasswordHasher",
    "django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher",
    "django.contrib.auth.hashers.BCryptSHA256PasswordHasher",
]
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"},
]

# MIDDLEWARE
# ------------------------------------------------------------------------------
MIDDLEWARE = [
    # "allauth.account.middleware.AccountMiddleware",
    "corsheaders.middleware.CorsMiddleware",
    "utils.middleware.JWTAuthenticationMiddleware",  #  自定义JWT认证中间件
    "utils.middleware.DisableCSRFCheck",  #  禁用 CSRF 验证
    "django.middleware.security.SecurityMiddleware",
    "django.middleware.gzip.GZipMiddleware",  # gzip 压缩"
    "django.contrib.sessions.middleware.SessionMiddleware",
    "django.middleware.locale.LocaleMiddleware",
    "django.middleware.common.CommonMiddleware",
    "django.middleware.csrf.CsrfViewMiddleware",  # CSRF 保护
    "django.contrib.auth.middleware.AuthenticationMiddleware",
    "django.contrib.messages.middleware.MessageMiddleware",
    "django.middleware.common.BrokenLinkEmailsMiddleware",
    "django.middleware.clickjacking.XFrameOptionsMiddleware",
    # "dauthz.middlewares.request_middleware.RequestMiddleware",  # django-authorization插件
]

# DAUTHZ
# DAUTHZ = {
#     "DEFAULT": {
#         "MODEL": {
#             "CONFIG_TYPE": "file",
#             "CONFIG_FILE_PATH": Path(__file__).parent.joinpath("dauthz-model.conf"),
#             "CONFIG_TEXT": "",
#         },
#         "ADAPTER": {"NAME": "casbin_adapter.adapter.Adapter"},
#         "LOG": {"ENABLED": False},
#     },
# }

# STATIC
# ------------------------------------------------------------------------------
STATIC_ROOT = str(ROOT_DIR / "staticfiles")
STATIC_URL = "/static/"
STATICFILES_DIRS = [str(ROOT_DIR / "static")]
STATICFILES_FINDERS = [
    "django.contrib.staticfiles.finders.FileSystemFinder",
    "django.contrib.staticfiles.finders.AppDirectoriesFinder",
]

# MEDIA
# ------------------------------------------------------------------------------
MEDIA_ROOT = str(ROOT_DIR / "media")
MEDIA_URL = "/media/"

# TEMPLATES
# ------------------------------------------------------------------------------
TEMPLATES = [
    {
        "BACKEND": "django.template.backends.django.DjangoTemplates",
        "DIRS": [str(ROOT_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.template.context_processors.i18n",
                "django.template.context_processors.media",
                "django.template.context_processors.static",
                "django.template.context_processors.tz",
                "django.contrib.messages.context_processors.messages",
                "utils.settings.allauth_settings",
            ],
        },
    }
]

FORM_RENDERER = "django.forms.renderers.TemplatesSetting"
CRISPY_TEMPLATE_PACK = "bootstrap5"
CRISPY_ALLOWED_TEMPLATE_PACKS = "bootstrap5"

# FIXTURES
# ------------------------------------------------------------------------------
FIXTURE_DIRS = (str(ROOT_DIR / "fixtures"),)

# SECURITY
# ------------------------------------------------------------------------------
SESSION_COOKIE_HTTPONLY = True
CSRF_COOKIE_HTTPONLY = True
SECURE_BROWSER_XSS_FILTER = True
X_FRAME_OPTIONS = "DENY"

# EMAIL
# ------------------------------------------------------------------------------
EMAIL_BACKEND = env(
    "DJANGO_EMAIL_BACKEND",
    default="django.core.mail.backends.smtp.EmailBackend",
)
EMAIL_TIMEOUT = 5

# ADMIN
# ------------------------------------------------------------------------------
ADMIN_URL = "admin/"
ADMINS = [
    ("""PySuper""", "small.spider.p@gmail.com"),
]
MANAGERS = ADMINS

# LOGGING
# ------------------------------------------------------------------------------
LOGS_DIR = os.path.join(ROOT_DIR, "logs")
if not os.path.isdir(LOGS_DIR):
    os.mkdir(LOGS_DIR)

LOGGING = {
    "version": 1,
    "disable_existing_loggers": False,
    # 日志格式配置
    "formatters": {
        # 详细格式,包含线程、任务ID等信息
        "verbose": {
            "format": "[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d][%(levelname)s][%(message)s]"
        },
        # 标准格式,包含基本的时间、文件等信息
        "standard": {
            "format": "[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d] %(message)s",
        },
        # 简单格式,只包含日志级别和消息
        "simple": {
            "format": "[%(levelname)s] %(message)s",
        },
        # 采集格式,只包含消息内容
        "collect": {
            "format": "%(message)s",
        },
        # 安全日志格式
        "security": {
            "format": "[%(asctime)s][%(levelname)s][%(ip)s][%(user)s][%(message)s]",
        },
        # 性能日志格式
        "performance": {
            "format": "[%(asctime)s][%(levelname)s][%(duration).2fms][%(message)s]",
        },
        # 新增业务日志格式
        "business": {"format": "[%(asctime)s][%(levelname)s][%(business_type)s][%(user)s][%(message)s]"},
        # 新增审计日志格式
        "audit": {"format": "[%(asctime)s][%(levelname)s][%(user)s][%(action)s][%(resource)s][%(result)s]"},
        # 新增接口调用日志格式
        "api_call": {
            "format": "[%(asctime)s][%(levelname)s][%(method)s][%(url)s][%(status_code)s][%(response_time).2fms]"
        },
    },
    # 日志处理器配置
    "handlers": {
        # 原有处理器保持不变...
        "console": {
            "level": "DEBUG",
            "class": "logging.StreamHandler",
            "formatter": "simple",
        },
        "file_handler": {
            "level": "INFO",
            "class": "logging.handlers.TimedRotatingFileHandler",  # 修改为标准的TimedRotatingFileHandler
            "filename": os.path.join(LOGS_DIR, "info.log"),
            "when": "midnight",
            "interval": 1,
            "backupCount": 20,
            "formatter": "standard",
            "encoding": "utf-8",
        },
        "sql_handler": {
            "level": "DEBUG",
            "class": "logging.handlers.TimedRotatingFileHandler",
            "filename": os.path.join(LOGS_DIR, "sql.log"),
            "when": "midnight",
            "interval": 1,
            "backupCount": 20,
            "formatter": "standard",
            "encoding": "utf-8",
        },
        "error_handler": {
            "level": "ERROR",
            "class": "logging.handlers.TimedRotatingFileHandler",
            "filename": os.path.join(LOGS_DIR, "err.log"),
            "when": "midnight",
            "interval": 1,
            "backupCount": 20,
            "formatter": "standard",
            "encoding": "utf-8",
        },
        "collect_handler": {
            "level": "DEBUG",
            "class": "logging.handlers.TimedRotatingFileHandler",
            "filename": os.path.join(LOGS_DIR, "collect.log"),
            "when": "midnight",
            "interval": 1,
            "backupCount": 20,
            "formatter": "collect",
            "encoding": "utf-8",
        },
        "api_handler": {
            "level": "DEBUG",
            "class": "logging.handlers.TimedRotatingFileHandler",
            "filename": os.path.join(LOGS_DIR, "api.log"),
            "when": "midnight",
            "interval": 1,
            "backupCount": 20,
            "formatter": "verbose",
            "encoding": "utf-8",
        },
        "security_handler": {
            "level": "DEBUG",
            "class": "logging.handlers.TimedRotatingFileHandler",
            "filename": os.path.join(LOGS_DIR, "security.log"),
            "when": "midnight",
            "interval": 1,
            "backupCount": 30,
            "formatter": "security",
            "encoding": "utf-8",
        },
        "performance_handler": {
            "level": "DEBUG",
            "class": "logging.handlers.TimedRotatingFileHandler",
            "filename": os.path.join(LOGS_DIR, "performance.log"),
            "when": "midnight",
            "interval": 1,
            "backupCount": 30,
            "formatter": "performance",
            "encoding": "utf-8",
        },
        # 新增业务日志处理器
        "business_handler": {
            "level": "DEBUG",
            "class": "logging.handlers.TimedRotatingFileHandler",
            "filename": os.path.join(LOGS_DIR, "business.log"),
            "when": "midnight",
            "interval": 1,
            "backupCount": 30,
            "formatter": "business",
            "encoding": "utf-8",
        },
        # 新增审计日志处理器
        "audit_handler": {
            "level": "DEBUG",
            "class": "logging.handlers.TimedRotatingFileHandler",
            "filename": os.path.join(LOGS_DIR, "audit.log"),
            "when": "midnight",
            "interval": 1,
            "backupCount": 90,
            "formatter": "audit",
            "encoding": "utf-8",
        },
        # 新增接口调用日志处理器
        "api_call_handler": {
            "level": "DEBUG",
            "class": "logging.handlers.TimedRotatingFileHandler",
            "filename": os.path.join(LOGS_DIR, "api_call.log"),
            "when": "midnight",
            "interval": 1,
            "backupCount": 30,
            "formatter": "api_call",
            "encoding": "utf-8",
        },
    },
    # 日志记录器配置
    "loggers": {
        # 保持原有记录器配置...
        "": {
            "handlers": ["console", "file_handler", "error_handler"],  # 添加console处理器
            "level": "DEBUG",
            "propagate": True,
        },
        "django.db.backends": {
            "handlers": ["console", "sql_handler"],
            "propagate": False,
            "level": "DEBUG",
        },
        "collect": {
            "handlers": ["console", "collect_handler"],
            "level": "INFO",
            "propagate": False,  # 设置为False避免重复记录
        },
        "api": {
            "handlers": ["console", "api_handler"],  # 添加console处理器
            "level": "INFO",
            "propagate": False,
        },
        "security": {
            "handlers": ["console", "security_handler"],
            "level": "INFO",
            "propagate": False,
        },
        "performance": {
            "handlers": ["console", "performance_handler"],
            "level": "INFO",
            "propagate": False,
        },
        "user_operation": {
            "handlers": ["console", "file_handler"],
            "level": "INFO",
            "propagate": False,
        },
        "system_monitor": {
            "handlers": ["console", "file_handler"],
            "level": "INFO",
            "propagate": False,
        },
        # 新增业务日志记录器
        "business": {
            "handlers": ["console", "business_handler"],
            "level": "INFO",
            "propagate": False,
        },
        # 新增审计日志记录器
        "audit": {
            "handlers": ["console", "audit_handler"],
            "level": "INFO",
            "propagate": False,
        },
        # 新增接口调用日志记录器
        "api_call": {
            "handlers": ["console", "api_call_handler"],
            "level": "INFO",
            "propagate": False,
        },
    },
}

# Celery
# ------------------------------------------------------------------------------
if USE_TZ:
    CELERY_TIMEZONE = TIME_ZONE
CELERY_BROKER_URL = env("CELERY_BROKER_URL", default="redis://:redis_yJpScr@119.45.4.159:16379/8")
CELERY_RESULT_BACKEND = CELERY_BROKER_URL
CELERY_ACCEPT_CONTENT = ["json"]
CELERY_TASK_SERIALIZER = "json"
CELERY_RESULT_SERIALIZER = "json"
CELERY_TASK_TIME_LIMIT = 5 * 60
CELERY_TASK_SOFT_TIME_LIMIT = 60
CELERY_BEAT_SCHEDULER = "django_celery_beat.schedulers:DatabaseScheduler"


# CORS
ALLOWED_HOSTS = ["*"]
CORS_ALLOW_ALL_ORIGINS = True

# django-allauth
# ------------------------------------------------------------------------------
ACCOUNT_ALLOW_REGISTRATION = env.bool("DJANGO_ACCOUNT_ALLOW_REGISTRATION", True)
ACCOUNT_AUTHENTICATION_METHOD = "username_email"
ACCOUNT_EMAIL_REQUIRED = True
ACCOUNT_EMAIL_VERIFICATION = "mandatory"
ACCOUNT_ADAPTER = "users.adapters.AccountAdapter"
ACCOUNT_FORMS = {"signup": "users.forms.UserSignupForm"}
SOCIALACCOUNT_ADAPTER = "users.adapters.SocialAccountAdapter"
SOCIALACCOUNT_FORMS = {"signup": "users.forms.UserSocialSignupForm"}

# DRF
# -------------------------------------------------------------------------------
REST_FRAMEWORK = {
    # 自定义默认分页类
    "DEFAULT_PAGINATION_CLASS": "utils.custom.LargePagination",
    # 默认的每页显示的条数
    "PAGE_SIZE": 10,
    # # 自定义的异常处理器
    "EXCEPTION_HANDLER": "utils.handler.custom_exception_handler",
    # 自定义的权限类
    "DEFAULT_AUTHENTICATION_CLASSES": (
        # JWT身份验证
        "rest_framework_simplejwt.authentication.JWTAuthentication",
        # 基于会话身份验证
        "rest_framework.authentication.TokenAuthentication",
        # 基本身份验证,上线可取消
        "rest_framework.authentication.BasicAuthentication",
        # 会话身份验证,上线可取消
        "rest_framework.authentication.SessionAuthentication",
    ),
    # 默认的渲染器类。渲染器负责将API响应转换为客户端可以理解的格式
    "DEFAULT_RENDERER_CLASSES": (
        # JSON渲染器
        "rest_framework.renderers.JSONRenderer",
        # 浏览API渲染器
        "rest_framework.renderers.BrowsableAPIRenderer",
    ),
    # 默认的解析器类,将客户端发送的请求数据解析为Python对象
    "DEFAULT_PARSER_CLASSES": (
        # JSON解析器
        "rest_framework.parsers.JSONParser",
        # 表单解析器
        "rest_framework.parsers.FormParser",
        # 多部分解析器
        "rest_framework.parsers.MultiPartParser",
    ),
    # 默认的权限类,只有经过身份验证的用户才能访问API端点
    "DEFAULT_PERMISSION_CLASSES": [
        # 自定义的RBAC权限类,用于实现基于角色的访问控制,可以在全局或视图级别使用
        "utils.custom.RbacPermission",
        # 允许所有用户访问,包括未认证用户,通常用于公开API
        "rest_framework.permissions.AllowAny",
        # 只允许已认证用户访问,要求用户必须登录,是最基本的认证要求
        # 全局默认需要登录认证,但是可以在具体的视图中通过permission_classes设置例外
        # 比如登录接口设置permission_classes = [AllowAny]
        # 对于api/docs/这类接口, 我们可以在视图级别单独设置权限, 比如使用AllowAny或IsAdminUser
        # 在全局默认使用IsAuthenticated, 确保API安全性
        # "rest_framework.permissions.IsAuthenticated",
    ],
    # 设置默认的节流(限流)类和速率
    "DEFAULT_THROTTLE_CLASSES": [
        "rest_framework.throttling.AnonRateThrottle",
        "rest_framework.throttling.UserRateThrottle",
    ],
    # 匿名用户每天最多可以请求100次,而认证用户每天最多可以请求1000次。
    "DEFAULT_THROTTLE_RATES": {
        "anon": "100/day",
        "user": "1000/day",
    },
    # 默认的版本控制类,使用了命名空间版本控制,允许你通过URL路径来区分不同版本的API
    "DEFAULT_VERSIONING_CLASS": "rest_framework.versioning.NamespaceVersioning",
    # 默认的过滤器后端,它允许你在查询参数中使用过滤条件,这个可以在类里面设置
    "DEFAULT_FILTER_BACKENDS": (
        "django_filters.rest_framework.DjangoFilterBackend",
        "rest_framework.filters.SearchFilter",
        "rest_framework.filters.OrderingFilter",
    ),
    # 默认的内容协商类。内容协商决定了客户端和服务器之间如何确定响应的格式
    "DEFAULT_CONTENT_NEGOTIATION_CLASS": "rest_framework.negotiation.DefaultContentNegotiation",
    # 默认的架构生成器类
    # DRF自带的自动架构生成器
    # 'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.AutoSchema',
    # 使用drf-spectacular库生成OpenAPI文档
    "DEFAULT_SCHEMA_CLASS": "drf_spectacular.openapi.AutoSchema",
    # 使用自定义的架构生成器
    # "DEFAULT_SCHEMA_CLASS": "config.extend_schema.CustomAutoSchema",
}


SPECTACULAR_SETTINGS = {
    "TITLE": "Backend API",
    "DESCRIPTION": "Documentation of API endpoints of Backend",
    "VERSION": "1.0.0",
    "SERVE_PERMISSIONS": ["rest_framework.permissions.AllowAny"],
    "SERVE_INCLUDE_SCHEMA": False,
    "SERVERS": [
        {
            "url": "http://localhost:8000",
            "description": "Local Development server",
        },
        {
            "url": "https://dev.pysuper.com",
            "description": "Production server",
        },
    ],
}

# PySuper
# ------------------------------------------------------------------------------
# 不再自动重定向到带斜杠的 URL 后缀,返回 404 状态码
APPEND_SLASH = False

# 学校CODE的位数
CODE_LENGTH = 6

# 阿里云短信
ALIYUN_SMS = {
    "ACCESS_KEY_ID": "your_access_key_id",
    "ACCESS_KEY_SECRET": "your_access_key_secret",
    "SIGN_NAME": "your_sms_sign_name",  # 短信签名
    "TEMPLATE_CODE": "your_template_code",  # 短信模板CODE
}

# 初始登录密码
START_PASSWORD = "123456"


# 读取密钥文件
def read_key(file_path):
    """读取密钥文件内容"""
    with open(file_path, "r") as file:
        return file.read()


# RSA 密钥配置,解密用户密码
RSA_PUBLIC_KEY = read_key(str(ROOT_DIR / "config/settings/pub.key"))
RSA_PRIVATE_KEY = read_key(str(ROOT_DIR / "config/settings/pri.key"))
RSA_PASSWORD = "your_password_for_rsa_encrypt"

# 用户缓存默认闲置时间,单位:秒
USER_CACHE_IDLE_TIME = 36000

# LOGIN_CODE 相关
login_code_config = (
    ("ARITHMETIC", "算数"),
    ("CHINESE", "中文"),
    ("CHINESE_GIF", "中文闪图"),
    ("GIF", "闪图"),
    ("SPEC", "普通"),
)
SINGLE_LOGIN = True  # 单点登录
EXPIRATION_DELTA = timedelta(minutes=2)  # 验证码有效期(分钟)
LOGIN_CODE_TYPE = "ARITHMETIC"  # 验证码格式: ARITHMETIC、CHINESE、RANDOM
LOGIN_CODE_LENGTH = 4  # 验证码图片长度
LOGIN_CODE_WIDTH = 120  # 验证码图片宽度
LOGIN_CODE_HEIGHT = 40  # 验证码图片高度
LOGIN_CODE_FONT_NAME = str(ROOT_DIR / "SimSun.ttf")  # 验证码字体路径
LOGIN_CODE_FONT_SIZE = 20  # 验证码字体大小
LOGIN_CODE_KEY = "captcha:"  # 验证码前缀

# JWT 相关
JWT_AUTH = {
    "JWT_EXPIRATION_DELTA": datetime.timedelta(days=100),
    "JWT_AUTH_HEADER_PREFIX": "Bearer ",
}
JWT_HEADER_NAME = "Authorization"  # 请求头头部名称
JWT_AUTH_HEADER_PREFIX = "Bearer "  # Token前缀
BASE64_SECRET_KEY = "base_secret"  # Base64编码的密钥
TOKEN_LIFETIME = 3600000  # JWT 有效期(秒)
ONLINE_KEY = "online-user:"  # 在线用户键前缀
TOKEN_DETECT = 1800000  # Token 过期检测时间(秒)
TOKEN_RENEW_PERIOD = 3600000  # Token 续期时间(秒)
SIMPLE_JWT = {
    # "BLACKLIST_AFTER_ROTATION": True,  # 刷新令牌时将旧令牌放入黑名单
    "ACCESS_TOKEN_LIFETIME": datetime.timedelta(minutes=1500),  # 访问令牌的有效期
    "REFRESH_TOKEN_LIFETIME": datetime.timedelta(days=100),  # 刷新令牌的有效期
}

# 设置文件上传下载读写权限
FILE_UPLOAD_PERMISSIONS = 0o666

# 默认自动字段设置为 BigAutoField
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"

0
  1. 支付宝打赏

    qrcode alipay
  2. 微信打赏

    qrcode weixin

评论区