from rest_framework import status from rest_framework.viewsets import ViewSet from rest_framework.permissions import IsAuthenticated from rest_framework.decorators import action from rest_framework.response import Response from django.shortcuts import get_object_or_404 from django.core.validators import validate_email from django.core.exceptions import ValidationError from django.db import models from api.auth.serializers import UserResponseSerializer from api.models import UserProfile from api.utils.decorators import handle_exceptions from routes.models import Route, City, Country from .serializers import RouteSerializer, CreateRouteSerializer, CitySerializer, CountrySerializer class UserDataView(ViewSet): permission_classes = [IsAuthenticated] def initial(self, request, *args, **kwargs): try: super().initial(request, *args, **kwargs) except Exception as e: print(f"Authentication error: {e}") raise @action(detail=False, methods=['get']) @handle_exceptions def user_data(self, request): user = request.user try: user_data = UserResponseSerializer(user).data return Response(user_data, status=status.HTTP_200_OK) except UserProfile.DoesNotExist: return Response( {"error": "User profile not found"}, status=status.HTTP_404_NOT_FOUND ) class AccountActionsView(ViewSet): permission_classes = [IsAuthenticated] @action(detail=False, methods=['patch']) @handle_exceptions def change_data_main_tab(self, request): """Обновление данных на главной странице аккаунта""" user = request.user user_profile = get_object_or_404(UserProfile, user=user) # обновляем данные пользователя if 'firstName' in request.data: user.first_name = request.data['firstName'] if 'lastName' in request.data: user.last_name = request.data['lastName'] if 'email' in request.data: email = request.data['email'] validate_email(email) # handle_exceptions обработает ValidationError user.email = email user.username = email # обновляем номер телефона if 'phone_number' in request.data: phone = request.data['phone_number'] if phone: if len(phone) < 13: # +375XXXXXXXXX raise ValidationError("Номер телефона слишком короткий") if len(phone) > 18: raise ValidationError("Номер телефона слишком длинный") # проверка на уникальность if UserProfile.objects.filter(phone_number=phone).exclude(user=user).exists(): raise ValidationError("Этот номер телефона уже используется") user_profile.phone_number = phone # сохраняем изменения user.save() user_profile.save() return Response({ "message": "Данные успешно обновлены", "user": UserResponseSerializer(user).data }, status=status.HTTP_200_OK) @action(detail=False, methods=['get']) @handle_exceptions def user_routes(self, request): user = request.user routes = Route.objects.filter(owner=user) return Response(RouteSerializer(routes, many=True).data, status=status.HTTP_200_OK) @action(detail=False, methods=['post']) @handle_exceptions def create_route(self, request): print("[DEBUG] Входящие данные в create_route view:", request.data) try: serializer = CreateRouteSerializer(data=request.data, context={'request': request}) if not serializer.is_valid(): print("[DEBUG] Ошибки валидации:", serializer.errors) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) route = serializer.save() print("[DEBUG] Маршрут успешно создан в view:", route.id) return Response(serializer.data, status=status.HTTP_201_CREATED) except Exception as e: print("[DEBUG] Необработанная ошибка в create_route:", str(e)) raise class CityView(ViewSet): @action(detail=False, methods=['get']) @handle_exceptions def get_cities(self, request): # получаем параметр country_id из query params country_id = request.query_params.get('country_id') # базовый QuerySet cities = City.objects.all() # фильтруем города по стране, если указан country_id if country_id: cities = cities.filter(country_id=country_id) # поиск по названию города search = request.query_params.get('search') if search: cities = cities.filter(name__icontains=search) # ограничиваем количество результатов и сортируем по имени cities = cities.order_by('name')[:100] return Response(CitySerializer(cities, many=True).data, status=status.HTTP_200_OK) class CountryView(ViewSet): @action(detail=False, methods=['get']) @handle_exceptions def get_countries(self, request): # базовый QuerySet countries = Country.objects.all() # поиск по названию страны search = request.query_params.get('search') if search: countries = countries.filter( models.Q(international_name__icontains=search) | models.Q(official_name__icontains=search) ) # сортируем по международному названию countries = countries.order_by('international_name') return Response(CountrySerializer(countries, many=True).data, status=status.HTTP_200_OK)