Files
tripwithbonus/backend/api/account/client/views.py
2025-05-22 13:52:02 +03:00

156 lines
6.3 KiB
Python

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)