Site/OneCprogsite/settings.py
2026-04-07 21:55:17 +03:00

291 lines
9.3 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 OneCprogsite project.
Generated by 'django-admin startproject' using Django 4.2.7.
For more information on this file, see
https://docs.djangoproject.com/en/4.2/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/4.2/ref/settings/
"""
import os.path
import sys
from pathlib import Path
from dotenv import load_dotenv
load_dotenv()
SITE_ID = 1
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
sys.path.insert(0, str(BASE_DIR)) # Добавляем корень проекта
sys.path.insert(0, str(BASE_DIR / "OneCprogsite")) # Добавляем папку OneCprogsite
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/4.2/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = os.getenv('DJANGO_SECRET_KEY')
# Для разработки (HTTP)
SESSION_COOKIE_SECURE = False
CSRF_COOKIE_SECURE = False
SECURE_SSL_REDIRECT = False
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = os.getenv('DJANGO_DEBUG', 'True').lower() == 'true'
# Или разрешить конкретные домены (Django 4.0+)
X_FRAME_OPTIONS = 'ALLOW-FROM https://metrika.yandex.ru'
# ОБЯЗАТЕЛЬНО укажите ваши домены
ALLOWED_HOSTS = os.getenv('DJANGO_ALLOWED_HOSTS', 'localhost,127.0.0.1').split(',')
# Важно для работы за прокси
if not DEBUG:
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
SECURE_SSL_REDIRECT = True
# Дополнительная безопасность
SECURE_BROWSER_XSS_FILTER = True
SECURE_CONTENT_TYPE_NOSNIFF = True
SECURE_HSTS_SECONDS = 31536000
SECURE_HSTS_INCLUDE_SUBDOMAINS = True
SECURE_HSTS_PRELOAD = True
# Безопасность cookies для HTTPS
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
SESSION_COOKIE_HTTPONLY = True
CSRF_COOKIE_HTTPONLY = False # Django требует доступ к CSRF cookie через JS
SESSION_COOKIE_SAMESITE = 'Lax'
CSRF_COOKIE_SAMESITE = 'Lax'
# Если используете другие cookies
LANGUAGE_COOKIE_SECURE = True
LANGUAGE_COOKIE_HTTPONLY = True
LANGUAGE_COOKIE_SAMESITE = 'Lax'
CSRF_TRUSTED_ORIGINS = [
'https://nikdizell.ru',
'https://www.nikdizell.ru',
]
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'programmer.apps.ProgrammerConfig',
'django_bootstrap5',
'django_extensions',
'django.contrib.sites',
'django.contrib.sitemaps',
'blog.apps.BlogConfig',
'taggit',
'django_ckeditor_5',
'captcha',
'turnstile',
]
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',
'programmer.middleware.CSPMiddleware',
'programmer.middleware.PageViewMiddleware',
]
ROOT_URLCONF = 'OneCprogsite.urls'
# Кастомный middleware для CSP вынесен в отдельный файл
# class CSPMiddleware:
# def __init__(self, get_response):
# self.get_response = get_response
#
# def __call__(self, request):
# response = self.get_response(request)
# response['Content-Security-Policy'] = "frame-ancestors 'self' https://metrika.yandex.ru https://metrika.yandex.by https://metrica.yandex.com https://metrica.yandex.com.tr https://*.webvisor.com"
# return response
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'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',
'programmer.context_processors.contact_info',
],
},
},
]
WSGI_APPLICATION = 'OneCprogsite.wsgi.application'
# Database
# https://docs.djangoproject.com/en/4.2/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': os.getenv('DB_NAME'),
'USER': os.getenv('DB_USER'),
'PASSWORD': os.getenv('DB_PASSWORD'),
'HOST': os.getenv('DB_HOST'),
'PORT': os.getenv('DB_PORT'),
}
}
# Password validation
# https://docs.djangoproject.com/en/4.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/4.2/topics/i18n/
LANGUAGE_CODE = 'ru'
TIME_ZONE = 'Europe/Moscow'
USE_I18N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/4.2/howto/static-files/
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'programmer', 'static'),
]
# Default primary key field type
# https://docs.djangoproject.com/en/4.2/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
# Настройки email
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
# EMAIL_HOST = 'smtp.yandex.ru' # или smtp.gmail.com, smtp.mail.ru
# EMAIL_PORT = 587
# EMAIL_USE_TLS = True
# EMAIL_HOST_USER = os.getenv('EMAIL_HOST_USER', 'it@yandex.ru')
# EMAIL_HOST_PASSWORD = os.getenv('EMAIL_HOST_PASSWORD', 'tifdctkrcjcqwxyc')
# DEFAULT_FROM_EMAIL = EMAIL_HOST_USER
# SERVER_EMAIL = EMAIL_HOST_USER
EMAIL_HOST = os.getenv('EMAIL_HOST') # или smtp.gmail.com, smtp.mail.ru
EMAIL_PORT = int(os.getenv('EMAIL_PORT', 465))
EMAIL_USE_SSL = True
# if os.getenv('EMAIL_USE_TLS', 'False').lower() == 'False':
# EMAIL_USE_TLS = True
EMAIL_HOST_USER = os.getenv('EMAIL_HOST_USER')
EMAIL_HOST_PASSWORD = os.getenv('EMAIL_HOST_PASSWORD')
DEFAULT_FROM_EMAIL = EMAIL_HOST_USER
SERVER_EMAIL = EMAIL_HOST_USER
# Email для уведомлений (можно указать несколько через запятую)
# ADMIN_EMAILS = os.getenv('ADMIN_EMAILS', 'nikdizell@gmail.com').split(',')
ADMIN_EMAILS = os.getenv('ADMIN_EMAILS').split(',')
# Путь для загрузки файлов редактором
CKEDITOR_5_UPLOAD_FILE_TYPES = ['jpeg', 'jpg', 'png', 'gif', 'bmp', 'webp'] # допустимые типы
CKEDITOR_5_UPLOAD_PATH = "uploads/ckeditor/" # папка внутри MEDIA_ROOT
CKEDITOR_5_CONFIGS = {
'default': {
'toolbar': {
'items': [
'heading', '|',
'bold', 'italic', 'underline', 'strikethrough', 'subscript', 'superscript', '|',
'fontSize', 'fontFamily', 'fontColor', 'highlight', '|',
'alignment', '|',
'bulletedList', 'numberedList', 'todoList', '|',
'outdent', 'indent', '|',
'link', 'blockQuote', 'imageUpload', 'mediaEmbed', 'insertTable', 'codeBlock', '|',
'undo', 'redo', 'removeFormat', 'specialCharacters', 'horizontalLine', '|',
]
},
'image': {
'toolbar': [
'imageTextAlternative', '|',
'imageStyle:alignLeft', 'imageStyle:alignCenter', 'imageStyle:alignRight',
'|', 'resizeImage'
],
'styles': [
'alignLeft', 'alignCenter', 'alignRight'
],
},
'table': {
'contentToolbar': ['tableColumn', 'tableRow', 'mergeTableCells'],
},
'mediaEmbed': {
'previewsInData': True,
},
'codeBlock': {
'languages': [
{'language': 'plaintext', 'label': 'Plain text'},
{'language': '1c-enterprise', 'label': '1С'},
{'language': 'sql', 'label': 'SQL'},
{'language': 'javascript', 'label': 'JavaScript'},
{'language': 'python', 'label': 'Python'},
{'language': 'xml', 'label': 'XML'},
{'language': 'json', 'label': 'JSON'},
]
},
'fontSize': {
'options': [9, 11, 13, 16, 19, 24, 32, 40],
},
'height': 500,
'width': '100%',
}
}
LOGIN_REDIRECT_URL = 'profile'
LOGOUT_REDIRECT_URL = 'home'
LOGIN_URL = 'login'
CAPTCHA_LENGTH = 6
CAPTCHA_FONT_SIZE = 30
CAPTCHA_IMAGE_SIZE = (150, 50)
TURNSTILE_SITEKEY = '0x4AAAAAAC12NGPpc4TutFWA'
TURNSTILE_SECRET = '0x4AAAAAAC12NCpzKHKE09JaXRDv0smrSAU'