ЛР 3. Django REST & API
Отчет по лабораторной работе №3: Реализация серверной части на Django REST Framework
1. Цель работы
Разработать отказоустойчивую серверную часть (backend) для системы управления альпинистским клубом. Основные задачи включают: проектирование реляционной базы данных, создание гибкого API средствами Django REST Framework, реализацию системы разграничения прав доступа и автоматическое документирование всех интерфейсов.
2. Архитектура базы данных и моделирование
Проектирование велось с учетом необходимости хранения истории восхождений. Использовано 6 взаимосвязанных моделей. Особое внимание уделено реализации связи Many-to-Many между сущностями Alpinist и Climb.
Вместо стандартной связки использована промежуточная модель Participation (через аргумент through). Это архитектурное решение позволило хранить специфические данные для каждого участника в контексте конкретного похода: статус (успех, травма) и описание инцидентов. Таким образом, база данных поддерживает не только учет групп, но и детальную медицинскую и статистическую хронику.
Схема базы данных:

Листинг ключевых моделей (models.py):
class Mountain(models.Model):
name = models.CharField(max_length=100, verbose_name="Название горы")
height = models.PositiveIntegerField(verbose_name="Высота")
country = models.CharField(max_length=100)
class Climb(models.Model):
route = models.ForeignKey(Route, on_delete=models.CASCADE, related_name="climbs")
group_name = models.CharField(max_length=100)
start_actual = models.DateTimeField(null=True, blank=True)
is_group_success = models.BooleanField(default=False)
participants = models.ManyToManyField(Alpinist, through='Participation')
class Participation(models.Model):
alpinist = models.ForeignKey(Alpinist, on_delete=models.CASCADE)
climb = models.ForeignKey(Climb, on_delete=models.CASCADE, related_name="details")
status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='success')
incident_details = models.TextField(blank=True)
Скриншот: Зарегистрированные модели в административной панели Django

3. Сериализация данных и вложенные структуры
Для эффективной передачи данных по протоколу HTTP реализованы сериализаторы на базе ModelSerializer. Чтобы минимизировать количество запросов от клиента к серверу, применена технология Nested Serializers (вложенные сериализаторы).
Это позволяет при запросе данных о восхождении (Climb) сразу получать детальный список всех участников с их статусами, а также информацию о горе, на которую совершается подъем, через использование полей ReadOnlyField со ссылками на связанные объекты.
Листинг сериализатора (serializers.py):
class ClimbSerializer(serializers.ModelSerializer):
mountain_name = serializers.ReadOnlyField(source='route.mountain.name')
# отдаём список объектов Participation внутри объекта Climb
details = ParticipationSerializer(many=True, read_only=True)
class Meta:
model = Climb
fields = '__all__'
4. Бизнес-логика, агрегация и аналитические отчеты
Реализован набор эндпоинтов для решения задач администратора. Использованы возможности Django ORM для проведения сложных вычислений на стороне базы данных:
* Фильтрация: Поиск участников и групп в заданных временных интервалах (__range).
* Агрегация: Использование метода annotate и функции Count для подсчета количества альпинистов, покоривших каждую конкретную вершину.
* Сложная группировка: Создан эндпоинт MountainReportView, который формирует иерархическую структуру данных: Гора -> Список групп -> Кол-во человек, а также вычисляет итоговое суммарное количество участников по всему отчету.
Листинг формирования сложного отчета (views.py):
class MountainReportView(APIView):
def get(self, request):
start_date = request.query_params.get('start')
end_date = request.query_params.get('end')
climbs = Climb.objects.filter(
route__mountain=mtn,
start_actual__range=[start_date, end_date]
).annotate(members_count=Count('participants'))
Скриншот: Тестирование API и получение данных о горах

5. Безопасность и токенизация
Защита API реализована на базе библиотеки Djoser и стандартного механизма Token Authentication в Django REST Framework.
Механизм токенизации:
1. Выпуск токена: При успешном входе пользователя (POST запрос на /auth/token/login/) сервер генерирует уникальный алфавитно-цифровой ключ (Token), который сохраняется в базе данных и возвращается клиенту.
2. Хранение: Клиентское приложение сохраняет этот токен и прикрепляет его к каждому последующему запросу в HTTP-заголовке Authorization: Token <key>.
3. Валидация: Бэкенд перехватывает заголовок, сопоставляет токен с пользователем в базе и определяет его личность.
4. Права доступа: Использован класс IsAuthenticated, который блокирует доступ к критически важным эндпоинтам (например, просмотр списка гор или создание новых восхождений) для неавторизованных лиц.
Документирование:
Все интерфейсы автоматически описаны с помощью Swagger (drf-spectacular). Это обеспечивает интерактивную среду, где можно протестировать запросы, увидеть требуемые параметры (Query Parameters) и форматы ответов без написания кода.
Скриншот: Перечень всех эндпоинтов системы в Swagger UI

6. Выводы
В результате выполнения работы была создана полноценная серверная архитектура, соответствующая принципам REST. Реализована сложная модель данных с промежуточными сущностями, настроена эффективная агрегация данных средствами ORM и обеспечена высокая безопасность системы за счет использования токенизации. Система готова к интеграции с клиентской частью. Все требования Варианта №15 выполнены.