Добавил форму для загрузки данных с LyngSat

This commit is contained in:
2025-11-10 23:28:06 +03:00
parent 1b345a3fd9
commit 65e6c9a323
24 changed files with 2730 additions and 308 deletions

View File

@@ -21,19 +21,21 @@ load_dotenv()
BASE_DIR = Path(__file__).resolve().parent.parent
# GDAL/GEOS configuration for Windows
if os.name == 'nt':
if os.name == "nt":
OSGEO4W = r"C:\Program Files\OSGeo4W"
assert os.path.isdir(OSGEO4W), "Directory does not exist: " + OSGEO4W
os.environ['OSGEO4W_ROOT'] = OSGEO4W
os.environ['PROJ_LIB'] = os.path.join(OSGEO4W, r"share\proj")
os.environ['PATH'] = OSGEO4W + r"\bin;" + os.environ['PATH']
os.environ["OSGEO4W_ROOT"] = OSGEO4W
os.environ["PROJ_LIB"] = os.path.join(OSGEO4W, r"share\proj")
os.environ["PATH"] = OSGEO4W + r"\bin;" + os.environ["PATH"]
# ============================================================================
# SECURITY SETTINGS
# ============================================================================
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = os.getenv('SECRET_KEY', 'django-insecure-7etj5f7buo2a57xv=w3^&llusq8rii7b_gd)9$t_1xcnao!^tq')
SECRET_KEY = os.getenv(
"SECRET_KEY", "django-insecure-7etj5f7buo2a57xv=w3^&llusq8rii7b_gd)9$t_1xcnao!^tq"
)
# SECURITY WARNING: don't run with debug turned on in production!
# This should be overridden in environment-specific settings
@@ -49,38 +51,42 @@ ALLOWED_HOSTS = []
INSTALLED_APPS = [
# Django Autocomplete Light (must be before admin)
'dal',
'dal_select2',
"dal",
"dal_select2",
# Admin interface customization
'admin_interface',
'colorfield',
"admin_interface",
"colorfield",
# Django GIS
'django.contrib.gis',
"django.contrib.gis",
# Django core apps
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.humanize',
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"django.contrib.humanize",
# Third-party apps
'leaflet',
'dynamic_raw_id',
'rangefilter',
'django_admin_multiple_choice_list_filter',
'more_admin_filters',
'import_export',
"leaflet",
"dynamic_raw_id",
"rangefilter",
"django_admin_multiple_choice_list_filter",
"more_admin_filters",
"import_export",
# Project apps
'mainapp',
'mapsapp',
"mainapp",
"mapsapp",
"lyngsatapp",
]
# Add Celery results app if available
try:
import django_celery_results
INSTALLED_APPS.append("django_celery_results")
except ImportError:
pass
# Note: Custom user model is implemented via OneToOneField relationship
# If you need a custom user model, uncomment and configure:
# AUTH_USER_MODEL = 'mainapp.CustomUser'
@@ -90,17 +96,17 @@ INSTALLED_APPS = [
# ============================================================================
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.locale.LocaleMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
"django.middleware.security.SecurityMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.locale.LocaleMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
]
ROOT_URLCONF = 'dbapp.urls'
ROOT_URLCONF = "dbapp.urls"
# ============================================================================
# TEMPLATES CONFIGURATION
@@ -108,36 +114,36 @@ ROOT_URLCONF = 'dbapp.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [
BASE_DIR / 'templates',
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [
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',
"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",
],
},
},
]
WSGI_APPLICATION = 'dbapp.wsgi.application'
WSGI_APPLICATION = "dbapp.wsgi.application"
# ============================================================================
# DATABASE CONFIGURATION
# ============================================================================
DATABASES = {
'default': {
'ENGINE': os.getenv('DB_ENGINE', 'django.contrib.gis.db.backends.postgis'),
'NAME': os.getenv('DB_NAME', 'db'),
'USER': os.getenv('DB_USER', 'user'),
'PASSWORD': os.getenv('DB_PASSWORD', 'password'),
'HOST': os.getenv('DB_HOST', 'localhost'),
'PORT': os.getenv('DB_PORT', '5432'),
"default": {
"ENGINE": os.getenv("DB_ENGINE", "django.contrib.gis.db.backends.postgis"),
"NAME": os.getenv("DB_NAME", "db"),
"USER": os.getenv("DB_USER", "user"),
"PASSWORD": os.getenv("DB_PASSWORD", "password"),
"HOST": os.getenv("DB_HOST", "localhost"),
"PORT": os.getenv("DB_PORT", "5432"),
}
}
@@ -148,16 +154,16 @@ DATABASES = {
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator",
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator",
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator",
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator",
},
]
@@ -165,9 +171,9 @@ AUTH_PASSWORD_VALIDATORS = [
# INTERNATIONALIZATION
# ============================================================================
LANGUAGE_CODE = 'ru'
LANGUAGE_CODE = "ru"
TIME_ZONE = 'Europe/Moscow'
TIME_ZONE = "Europe/Moscow"
USE_I18N = True
@@ -177,18 +183,18 @@ USE_TZ = True
# AUTHENTICATION CONFIGURATION
# ============================================================================
LOGIN_URL = 'login'
LOGIN_REDIRECT_URL = 'mainapp:home'
LOGOUT_REDIRECT_URL = 'mainapp:home'
LOGIN_URL = "login"
LOGIN_REDIRECT_URL = "mainapp:home"
LOGOUT_REDIRECT_URL = "mainapp:home"
# ============================================================================
# STATIC FILES CONFIGURATION
# ============================================================================
STATIC_URL = '/static/'
STATIC_URL = "/static/"
STATICFILES_DIRS = [
BASE_DIR.parent / 'static',
BASE_DIR.parent / "static",
]
# STATIC_ROOT will be set in production.py
@@ -198,7 +204,7 @@ STATICFILES_DIRS = [
# ============================================================================
# Default primary key field type
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
# ============================================================================
# THIRD-PARTY APP CONFIGURATION
@@ -210,17 +216,53 @@ SILENCED_SYSTEM_CHECKS = ["security.W019"]
# Leaflet Configuration
LEAFLET_CONFIG = {
'ATTRIBUTION_PREFIX': '',
'TILES': [
"ATTRIBUTION_PREFIX": "",
"TILES": [
(
'Satellite',
'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}',
{'attribution': '© Esri', 'maxZoom': 16}
"Satellite",
"https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}",
{"attribution": "© Esri", "maxZoom": 16},
),
(
'Streets',
'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
{'attribution': '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>'}
)
"Streets",
"http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
{
"attribution": '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>'
},
),
],
}
}
# ============================================================================
# CELERY CONFIGURATION
# ============================================================================
# Celery Configuration Options
CELERY_BROKER_URL = os.getenv("CELERY_BROKER_URL", "redis://localhost:6379/0")
CELERY_RESULT_BACKEND = "django-db"
CELERY_CACHE_BACKEND = "default"
# Celery Task Configuration
CELERY_TASK_TRACK_STARTED = True
CELERY_TASK_TIME_LIMIT = 30 * 60 # 30 minutes
CELERY_TASK_SOFT_TIME_LIMIT = 25 * 60 # 25 minutes
CELERY_TASK_ALWAYS_EAGER = False # Set to True for synchronous execution in development
# Celery Beat Configuration (for periodic tasks)
CELERY_BEAT_SCHEDULER = "django_celery_beat.schedulers:DatabaseScheduler"
# Celery Result Backend Configuration
CELERY_RESULT_EXTENDED = True
CELERY_RESULT_EXPIRES = 3600 # Results expire after 1 hour
# Celery Logging
CELERY_WORKER_HIJACK_ROOT_LOGGER = False
CELERY_WORKER_LOG_FORMAT = "[%(asctime)s: %(levelname)s/%(processName)s] %(message)s"
CELERY_WORKER_TASK_LOG_FORMAT = "[%(asctime)s: %(levelname)s/%(processName)s][%(task_name)s(%(task_id)s)] %(message)s"
# Celery Accept Content
CELERY_ACCEPT_CONTENT = ["json"]
CELERY_TASK_SERIALIZER = "json"
CELERY_RESULT_SERIALIZER = "json"
CELERY_TIMEZONE = TIME_ZONE