diff --git a/acore/settings/base.py b/acore/settings/base.py index 357ce11..fa8046d 100644 --- a/acore/settings/base.py +++ b/acore/settings/base.py @@ -16,6 +16,11 @@ ALLOWED_HOSTS = env.list('ALLOWED_HOSTS', default=[]) # core.utils.crypto делает fallback на SECRET_KEY (см. предупреждение ниже). FIELD_ENCRYPTION_KEY = env('FIELD_ENCRYPTION_KEY', default=env('SECRET_KEY')) +# E016 — ложноположительный для proxy-моделей над Directory (django-fast-treenode +# динамически добавляет индекс по _path, который proxy «наследует»). На реальных +# таблицах индексы корректны; для proxy это лишь предупреждение проверки. +SILENCED_SYSTEM_CHECKS = ['models.E016'] + # Базовый URL портала — используется для абсолютных ссылок в уведомлениях # (например, Mattermost-бот шлёт ссылку на задачу) PORTAL_BASE_URL = env('PORTAL_BASE_URL', default='http://localhost:8000') diff --git a/core/admin.py b/core/admin.py index 2783d0c..93cae31 100644 --- a/core/admin.py +++ b/core/admin.py @@ -10,7 +10,7 @@ from unfold.decorators import action from treenode.forms import TreeNodeForm from django.forms import TextInput, Textarea from django.db.models import Count -from core.models import DirectoryType, Directory, ConnectorConfig +from core.models import DirectoryType, Directory, ConnectorConfig, AccessSystem from import_export.admin import ImportExportModelAdmin from unfold.contrib.import_export.forms import ExportForm, ImportForm @@ -220,6 +220,25 @@ class DirectoryAdmin(ModelAdmin, ImportExportModelAdmin): children_count_display.short_description = 'Потомков' +@admin.register(AccessSystem) +class AccessSystemAdmin(ModelAdmin): + """Отдельный раздел для списка систем/баз доступа (1С, почта, CRM…), + которые выбираются чекбоксами в заявке на найм.""" + list_display = ['name', 'code', 'is_active', 'updated_at'] + list_filter = ['is_active'] + search_fields = ['name', 'code'] + ordering = ['name'] + fields = ['name', 'code', 'description', 'is_active'] + + def get_queryset(self, request): + return super().get_queryset(request).filter(directory_type__code='access_system') + + def save_model(self, request, obj, form, change): + if not obj.directory_type_id: + obj.directory_type = DirectoryType.objects.get(code='access_system') + super().save_model(request, obj, form, change) + + @admin.register(ConnectorConfig) class ConnectorConfigAdmin(ModelAdmin): list_display = ('connector_type_display', 'is_enabled', 'host', 'port', 'use_ssl', 'updated_at') diff --git a/core/migrations/0006_accesssystem.py b/core/migrations/0006_accesssystem.py new file mode 100644 index 0000000..6f3ce94 --- /dev/null +++ b/core/migrations/0006_accesssystem.py @@ -0,0 +1,26 @@ +# Generated by Django 6.0.3 on 2026-07-24 22:07 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0005_seed_location_types'), + ] + + operations = [ + migrations.CreateModel( + name='AccessSystem', + fields=[ + ], + options={ + 'verbose_name': 'Система доступу', + 'verbose_name_plural': 'Системи доступу', + 'proxy': True, + 'indexes': [], + 'constraints': [], + }, + bases=('core.directory',), + ), + ] diff --git a/core/models/__init__.py b/core/models/__init__.py index dfe5d12..20b3aaa 100644 --- a/core/models/__init__.py +++ b/core/models/__init__.py @@ -1,3 +1,3 @@ from .base import BaseModel -from .directories import DirectoryType, Directory +from .directories import DirectoryType, Directory, AccessSystem from .connector_config import ConnectorConfig diff --git a/core/models/directories.py b/core/models/directories.py index 24436a9..035b9a6 100644 --- a/core/models/directories.py +++ b/core/models/directories.py @@ -285,4 +285,23 @@ class Directory(TreeNodeModel, BaseModel): return DirectoryType.objects.all() elif self.directory_type.hierarchy_type == 'custom': return self.directory_type.allowed_child_types.all() - return [] \ No newline at end of file + return [] + +class AccessSystemManager(models.Manager): + """Только записи справочника «Система доступу» (базы/системы для доступов).""" + def get_queryset(self): + return super().get_queryset().filter(directory_type__code='access_system') + + +class AccessSystem(Directory): + """Proxy над Directory — отдельный раздел админки для управления списком + систем/баз доступа (1С, почта, CRM…), которые выбираются в заявке на найм.""" + objects = AccessSystemManager() + + class Meta: + proxy = True + verbose_name = 'Система доступу' + verbose_name_plural = 'Системи доступу' + # не наследуем treenode-индексы Directory (ссылаются на _path — E016 для proxy) + indexes = [] + constraints = []