mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-24 08:11:08 -05:00
Add secret management guide, client-side performance monitoring, and search accessibility enhancements
- Introduced a comprehensive Secret Management Guide detailing best practices, secret classification, development setup, production management, rotation procedures, and emergency protocols. - Implemented a client-side performance monitoring script to track various metrics including page load performance, paint metrics, layout shifts, and memory usage. - Enhanced search accessibility with keyboard navigation support for search results, ensuring compliance with WCAG standards and improving user experience.
This commit is contained in:
124
backend/config/settings/storage.py
Normal file
124
backend/config/settings/storage.py
Normal file
@@ -0,0 +1,124 @@
|
||||
"""
|
||||
Storage configuration for thrillwiki project.
|
||||
|
||||
This module configures static files, media files, and storage backends
|
||||
including WhiteNoise for static file serving.
|
||||
|
||||
Why python-decouple?
|
||||
- Already used in base.py for consistency
|
||||
- Simpler API than django-environ
|
||||
- Sufficient for our configuration needs
|
||||
- Better separation of config from code
|
||||
"""
|
||||
|
||||
from pathlib import Path
|
||||
from decouple import config
|
||||
|
||||
# =============================================================================
|
||||
# Base Directory
|
||||
# =============================================================================
|
||||
# This will be set by the importing module, but we define a fallback
|
||||
BASE_DIR = Path(__file__).resolve().parent.parent.parent
|
||||
|
||||
# =============================================================================
|
||||
# Static Files Configuration
|
||||
# =============================================================================
|
||||
# https://docs.djangoproject.com/en/5.0/howto/static-files/
|
||||
|
||||
STATIC_URL = config("STATIC_URL", default="static/")
|
||||
STATICFILES_DIRS = [BASE_DIR / "static"]
|
||||
STATIC_ROOT = BASE_DIR / "staticfiles"
|
||||
|
||||
# =============================================================================
|
||||
# WhiteNoise Configuration
|
||||
# =============================================================================
|
||||
# https://whitenoise.readthedocs.io/
|
||||
# WhiteNoise serves static files efficiently without a separate web server
|
||||
|
||||
# Compression quality for Brotli/Gzip (1-100, higher = better but slower)
|
||||
WHITENOISE_COMPRESSION_QUALITY = config(
|
||||
"WHITENOISE_COMPRESSION_QUALITY", default=90, cast=int
|
||||
)
|
||||
|
||||
# Cache max-age for static files (1 year for immutable content)
|
||||
WHITENOISE_MAX_AGE = config(
|
||||
"WHITENOISE_MAX_AGE", default=31536000, cast=int
|
||||
)
|
||||
|
||||
# Don't fail on missing manifest entries (graceful degradation)
|
||||
WHITENOISE_MANIFEST_STRICT = config(
|
||||
"WHITENOISE_MANIFEST_STRICT", default=False, cast=bool
|
||||
)
|
||||
|
||||
# Additional MIME types
|
||||
WHITENOISE_MIMETYPES = {
|
||||
".webp": "image/webp",
|
||||
".woff2": "font/woff2",
|
||||
}
|
||||
|
||||
# Skip compressing already compressed formats
|
||||
WHITENOISE_SKIP_COMPRESS_EXTENSIONS = [
|
||||
"jpg", "jpeg", "png", "gif", "webp", # Images
|
||||
"zip", "gz", "tgz", "bz2", "tbz", "xz", "br", # Archives
|
||||
"swf", "flv", # Flash
|
||||
"woff", "woff2", # Fonts
|
||||
"mp3", "mp4", "ogg", "webm", # Media
|
||||
]
|
||||
|
||||
# =============================================================================
|
||||
# Media Files Configuration
|
||||
# =============================================================================
|
||||
# User-uploaded content
|
||||
|
||||
MEDIA_URL = config("MEDIA_URL", default="/media/")
|
||||
MEDIA_ROOT = BASE_DIR.parent / "shared" / "media"
|
||||
|
||||
# =============================================================================
|
||||
# Storage Backends Configuration
|
||||
# =============================================================================
|
||||
# Django 4.2+ storage configuration
|
||||
|
||||
STORAGES = {
|
||||
# Default storage for user uploads (FileField, ImageField)
|
||||
"default": {
|
||||
"BACKEND": "django.core.files.storage.FileSystemStorage",
|
||||
"OPTIONS": {
|
||||
"location": str(MEDIA_ROOT),
|
||||
},
|
||||
},
|
||||
# Static files storage
|
||||
"staticfiles": {
|
||||
"BACKEND": "django.contrib.staticfiles.storage.StaticFilesStorage",
|
||||
"OPTIONS": {
|
||||
"location": str(STATIC_ROOT),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
# =============================================================================
|
||||
# File Upload Security Settings
|
||||
# =============================================================================
|
||||
# These settings help prevent denial-of-service attacks via file uploads
|
||||
|
||||
# Maximum size (in bytes) of file to upload into memory (2.5MB)
|
||||
# Files larger than this are written to disk
|
||||
FILE_UPLOAD_MAX_MEMORY_SIZE = config(
|
||||
"FILE_UPLOAD_MAX_MEMORY_SIZE", default=2621440, cast=int
|
||||
)
|
||||
|
||||
# Maximum size (in bytes) of request data (10MB)
|
||||
# This limits the total size of POST request body
|
||||
DATA_UPLOAD_MAX_MEMORY_SIZE = config(
|
||||
"DATA_UPLOAD_MAX_MEMORY_SIZE", default=10485760, cast=int
|
||||
)
|
||||
|
||||
# Maximum number of GET/POST parameters (1000)
|
||||
DATA_UPLOAD_MAX_NUMBER_FIELDS = config(
|
||||
"DATA_UPLOAD_MAX_NUMBER_FIELDS", default=1000, cast=int
|
||||
)
|
||||
|
||||
# File upload permissions (0o644 = rw-r--r--)
|
||||
FILE_UPLOAD_PERMISSIONS = 0o644
|
||||
|
||||
# Directory permissions for uploaded files (0o755 = rwxr-xr-x)
|
||||
FILE_UPLOAD_DIRECTORY_PERMISSIONS = 0o755
|
||||
Reference in New Issue
Block a user