Работа с данными основной системы
Обновлено: 07 Декабрь 2025
Версия: 2.2
Модули могут взаимодействовать с данными основной системы двумя способами:
- Через API - для чтения данных с защитой от изменений в моделях
- Напрямую через модели - для сложных операций, записи данных и использования методов моделей
Рекомендация: Используйте API для чтения данных, если хотите защитить модуль от изменений в моделях. Используйте прямые импорты для сложных запросов, методов моделей и операций записи.
Когда использовать API
Используйте API в следующих случаях:
- Чтение данных - для получения информации о сущностях системы (сотрудники, задачи, проекты и т.д.)
- Защита от изменений - когда хотите защитить модуль от изменений во внутренней структуре моделей
- Стандартизированный интерфейс - когда нужен единый способ работы с данными
Преимущества API:
- Абстракция от внутренней структуры моделей
- Защита от изменений в моделях (API может оставаться совместимым)
- Стандартизированный интерфейс
- Безопасность через систему прав доступа Django
Ограничения API:
- Только чтение данных (read-only)
- Ограниченный набор полей (только те, что в сериализаторе)
- Нет доступа к методам моделей
- Нет возможности создавать/изменять/удалять объекты
Когда напрямую обращаться к моделям
Используйте прямые импорты моделей в следующих случаях:
- Создание/изменение/удаление объектов - API предоставляет только чтение
- Сложные запросы - когда нужны сложные фильтры, аннотации, агрегации
- Использование методов моделей - когда нужно вызвать методы объектов (например,
get_absolute_url(),save()с дополнительной логикой) - Связанные объекты - когда нужен доступ к связанным объектам через ForeignKey/ManyToMany
- Транзакции - когда нужны атомарные операции с несколькими объектами
- Производительность - когда нужны оптимизированные запросы с
select_related(),prefetch_related()
Преимущества прямого доступа:
- Полный доступ ко всем полям и методам моделей
- Возможность создания, изменения и удаления объектов
- Сложные запросы с использованием Django ORM
- Использование методов моделей и менеджеров
- Транзакции и атомарные операции
Важно:
- При прямом доступе к моделям вы работаете с внутренней структурой системы
- Изменения в моделях основной системы могут повлиять на ваш модуль
- Всегда проверяйте права доступа перед операциями записи
Примеры использования
Пример 1: Получение списка сотрудников через API
import requests
from django.conf import settings
def get_employees_via_api(request):
"""Получение сотрудников через API"""
response = requests.get(
f'{settings.BASE_URL}/modules/api/core/employees/',
cookies=request.COOKIES # Используем сессию пользователя
)
if response.status_code == 200:
employees = response.json()
return employees
return []
Пример 2: Получение списка сотрудников напрямую через модели
from personal.models import Employee
def get_employees_direct():
"""Получение сотрудников напрямую через модели"""
# Простой запрос
employees = Employee.objects.filter(status='working')
# Сложный запрос с оптимизацией
employees = Employee.objects.select_related('manager', 'org').filter(
status='working',
org__name__icontains='Отдел'
).order_by('last_name', 'first_name')
return employees
Пример 3: Создание задачи (только через модели)
from tasks.models import Task
from personal.models import Employee
from django.utils import timezone
from datetime import timedelta
def create_task_for_employee(employee_id, title, description):
"""Создание задачи - только через модели, так как API read-only"""
employee = Employee.objects.get(id=employee_id)
task = Task.objects.create(
title=title,
description=description,
executor=employee,
author=employee, # или текущий пользователь
duedate=timezone.now() + timedelta(days=7),
completed=False
)
return task
Пример 4: Сложный запрос с агрегацией (только через модели)
from tasks.models import Task
from django.db.models import Count, Q, Avg
from django.utils import timezone
from datetime import timedelta
def get_task_statistics(employee_id):
"""Получение статистики по задачам - сложный запрос через модели"""
now = timezone.now()
week_ago = now - timedelta(days=7)
stats = Task.objects.filter(executor_id=employee_id).aggregate(
total=Count('id'),
completed=Count('id', filter=Q(completed=True)),
overdue=Count('id', filter=Q(completed=False, duedate__lt=now)),
due_soon=Count('id', filter=Q(
completed=False,
duedate__gte=now,
duedate__lte=now + timedelta(days=3)
)),
avg_progress=Avg('progress')
)
return stats
Пример 5: Использование методов модели (только через модели)
from tasks.models import Task
from notifications.services import send_notify
def notify_about_task(task_id):
"""Отправка уведомления о задаче - используем методы модели"""
task = Task.objects.get(id=task_id)
# Используем метод get_absolute_url() модели
task_url = task.get_absolute_url()
# Используем связанные объекты
executor = task.executor
if executor and executor.user:
send_notify(
obj=task,
recipients=[executor.user],
template_name='module_code_TaskNotification',
extra_context={
'task_url': task_url,
'executor_name': executor.display_name
}
)
Пример 6: Транзакция с несколькими объектами (только через модели)
from tasks.models import Task
from django.db import transaction
from personal.models import Employee
@transaction.atomic
def create_tasks_for_team(team_member_ids, title_template):
"""Создание задач для команды - атомарная операция"""
tasks = []
for member_id in team_member_ids:
employee = Employee.objects.get(id=member_id)
task = Task.objects.create(
title=f"{title_template} - {employee.display_name}",
executor=employee,
# ... другие поля
)
tasks.append(task)
# Если произойдет ошибка, все изменения откатятся
return tasks
Пример 7: Работа с ForeignKey и ManyToMany (только через модели)
from tasks.models import Task
from projects.models import Project
def get_project_tasks(project_id):
"""Получение задач проекта с оптимизацией"""
# Используем select_related для ForeignKey
tasks = Task.objects.select_related(
'executor',
'author',
'project'
).filter(project_id=project_id)
# Для ManyToMany используем prefetch_related
# (если бы у Task было поле ManyToMany)
return tasks
Рекомендации по выбору подхода
Используйте API, если:
- ✅ Нужно только чтение данных
- ✅ Хотите защитить модуль от изменений в моделях
- ✅ Нужна стандартизированная интеграция
- ✅ Достаточно полей, предоставляемых API
Используйте прямые импорты моделей, если:
- ✅ Нужно создавать/изменять/удалять объекты
- ✅ Нужны сложные запросы с агрегациями
- ✅ Нужно использовать методы моделей
- ✅ Нужны оптимизированные запросы (select_related, prefetch_related)
- ✅ Нужны транзакции
- ✅ Нужен доступ ко всем полям модели
Импорт моделей основной системы
При прямом доступе к моделям используйте полные пути импорта:
# Сотрудники
from personal.models import Employee, Organigram
# Пользователи
from users.models import CustomUser, CustomGroup
# Задачи
from tasks.models import Task, TaskSource
# Проекты
from projects.models import Project, ProjectRole, ProjectType
# Заявки
from servicedesk.requests import Request
# Договоры
from finance.contracts import Contract
# Уведомления
from system.notifications import Notification
from notifications.services import send_notify
# Клиенты
from clients.models import Clients
Важно:
- Всегда проверяйте наличие прав доступа перед операциями записи
- Используйте
get_object_or_404()для безопасного получения объектов - Используйте транзакции для атомарных операций
- Оптимизируйте запросы с помощью
select_related()иprefetch_related()