Files
2018-lpon-site/lpon_site/lpon_site/settings.py

242 lines
9.5 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
Django settings for lpon_site project.
Generated by 'django-admin startproject' using Django 6.0.5.
For more information on this file, see
https://docs.djangoproject.com/en/6.0/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/6.0/ref/settings/
"""
from pathlib import Path
import environ
import os
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
# Читаем переменные окружения
env = environ.Env()
environ.Env.read_env(os.path.join(BASE_DIR.parent, '.env'))
def _normalize_admin_url(value: str) -> str:
"""Приводит URL админки к виду `segment/` без ведущего слэша."""
normalized = value.strip().lstrip('/')
if not normalized:
return 'admin/'
if not normalized.endswith('/'):
normalized += '/'
return normalized
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/6.0/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = env('DJANGO_SECRET_KEY', default='3xym$l+!)erah-k23lf0=t=c_4$e0nr*zls&l%pbz@k6v6qn89')
ADMIN_URL = _normalize_admin_url(env('DJANGO_ADMIN_URL', default='admin/'))
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = env.bool('DJANGO_DEBUG', default=False)
ALLOWED_HOSTS = env.list(
'DJANGO_ALLOWED_HOSTS',
default=['127.0.0.1', 'localhost', 'testserver', 'lpon.ru'],
)
CSRF_TRUSTED_ORIGINS = env.list('DJANGO_CSRF_TRUSTED_ORIGINS', default=['127.0.0.1', 'localhost', 'testserver'])
#########################################
# Настройки сообщений об ошибках когда все упало и т.п.
ADMINS = tuple(
tuple(item.split(':', 1))
for item in env.list('DJANGO_ADMINS', default=['S.Erjemin:erjemin@gmail.com'])
)
# Application definition
INSTALLED_APPS = [
# Django core
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
# Django-filer и его зависимости
# Порядок важен! polymorphic должен быть ДО filer, easy_thumbnails тоже ДО filer
'polymorphic',
'easy_thumbnails',
# 'filer',
# Кастомная надстройка над filer для переопределения verbose_name (и других настроек)
'frontend.apps.CustomFilerConfig',
# Наше приложение
'frontend.apps.FrontendConfig',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'lpon_site.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'lpon_site.wsgi.application'
# Database
# https://docs.djangoproject.com/en/6.0/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR.parent.joinpath('database', env('DJANGO_SQLITE_NAME', default='lpon-db.sqlite3')),
'CONN_MAX_AGE': 600, # время жизни соединения с базой
'OPTIONS': {
'timeout': 25,
'init_command': "PRAGMA journal_mode=WAL; PRAGMA auto_vacuum=2;",
},
}
}
# Password validation
# https://docs.djangoproject.com/en/6.0/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/6.0/topics/i18n/
LANGUAGE_CODE = 'ru-RU' #
# TIME_ZONE = 'Etc/GMT+3' #
TIME_ZONE = 'Europe/Moscow' #
USE_I18N = True
USE_TZ = True
FIRST_DAY_OF_WEEK = 1 # неделя начинается с понедельника
DEFAULT_CHARSET = 'utf-8'
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/6.0/howto/static-files/
STATIC_URL = '/static/'
MEDIA_URL = '/media/'
# Локальные каталоги проекта: медиа и статика лежат рядом в `public`.
PUBLIC_DIR = BASE_DIR.parent.joinpath('public') # Папка `public` находится в корне пректа
MEDIA_ROOT = PUBLIC_DIR.joinpath('media')
STATICFILES_DIRS = [PUBLIC_DIR.joinpath('static')]
STATIC_ROOT = PUBLIC_DIR.joinpath('staticfiles')
# ============================================================================
# Django-Filer Configuration - WebP Conversion Storage
# ============================================================================
# Настройка хранилища filer для автоматического преобразования изображений в WebP
# ВАЖНО: эта конфигурация должна быть в settings.py (не в class attribute),
# т.к. Django-filer загружает её ДО инициализации app configs
# ВАЖНО: location должна быть равна MEDIA_ROOT, иначе Django не сможет
# сгенерировать правильные URL для файлов (URL генерируется как MEDIA_URL + relative_path)
#
# Структура папок:
# public/media/
# ├── flr/ <- основные загруженные файлы (картинки)
# ├── flrm/ <- миниатюры (thumbnails)
# ├── filer_public/ <- старая структура (больше не используется)
# └── filer_public_thumbnails/ <- старая структура (больше не используется)
FILER_STORAGES = {
'public': {
'main': {
# Используем стандартное хранилище Django. Логика конвертации в apps.py
'ENGINE': 'django.core.files.storage.FileSystemStorage',
'OPTIONS': {
'location': str(MEDIA_ROOT),
},
# UPLOAD_TO функция добавляет 'flr/' префикс для более компактных путей в шаблонах
'UPLOAD_TO': 'frontend.apps.generate_upload_path_flr',
'UPLOAD_TO_PREFIX': '',
},
'thumbnails': {
'ENGINE': 'django.core.files.storage.FileSystemStorage',
'OPTIONS': {
'location': str(MEDIA_ROOT),
},
# Миниатюры идят в папку flrm через UPLOAD_TO функцию
'UPLOAD_TO': 'frontend.apps.generate_upload_path_flrm',
'THUMBNAIL_OPTIONS': {
'base_dir': 'flrm',
},
},
},
}
# ============================================================================
# Easy-Thumbnails Configuration - WebP Generation
# ============================================================================
# Настройка генерирования миниатюр в формате WebP вместо JPEG/PNG
THUMBNAIL_PRESERVE_FORMAT = False # Не сохранять оригинальный формат для миниатюр
THUMBNAIL_FORMAT = 'WEBP' # Конвертировать все миниатюры в WebP
THUMBNAIL_QUALITY = 80 # Качество WebP (достаточно 75-85 для миниатюр)
# Кастомная настройка для встроенного конвертора загружаемых файлов в WebP (см. apps.py)
THUMBNAIL_WEBP_QUALITY = 80 # Качество для WebP
FILER_ENABLE_PERMISSIONS = DEBUG
FILER_WHITELIST_FOR_PATH_ACCESS = (
'.jpg', '.jpeg', '.png', '.gif', '.svg', '.webp',
'.doc', '.docx', '.pdf', '.txt', '.xls', '.xlsx', '.csv',
)
FILER_MAX_UPLOAD_SIZE = 100 * 1024 * 1024
MIME_TYPE_WHITELIST = (
'image/jpeg', 'image/png', 'image/gif', 'image/svg+xml', 'image/webp',
'application/pdf', 'application/msword',
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'text/plain', 'application/vnd.ms-excel',
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'text/csv',
)
THUMBNAIL_ENGINE = 'easy_thumbnails.engines.pil_engine.PilEngine'
THUMBNAIL_DEBUG = DEBUG
FILE_VALIDATORS = {}
# Размеры миниатюр для разных использований
THUMBNAIL_ALIASES = {
'': {
# Для админ-интерфейса
'admin_thumbnail': {'size': (64, 64), 'crop': True},
# Для фронтенда
'small': {'size': (256, 256), 'crop': True},
'medium': {'size': (512, 512), 'crop': True},
'large': {'size': (1024, 1024), 'crop': 'smart'},
},
}