diff --git a/backend/api/search/serializers.py b/backend/api/search/serializers.py index f23494f..3deb4e7 100644 --- a/backend/api/search/serializers.py +++ b/backend/api/search/serializers.py @@ -1,5 +1,5 @@ from rest_framework import serializers -from routes.models import Route, Country +from routes.models import Route, Country, City from api.main.serializers import RouteSerializer class SearchRouteSerializer(RouteSerializer): @@ -7,8 +7,10 @@ class SearchRouteSerializer(RouteSerializer): username = serializers.SerializerMethodField() owner_type = serializers.CharField() from_city_name = serializers.SerializerMethodField('get_start_point') + from_city_russian_name = serializers.SerializerMethodField() from_country_name = serializers.SerializerMethodField('get_country_from') to_city_name = serializers.SerializerMethodField('get_end_point') + to_city_russian_name = serializers.SerializerMethodField() to_country_name = serializers.SerializerMethodField('get_country_to') formatted_cargo_type = serializers.SerializerMethodField('get_cargo_type') formatted_transport = serializers.SerializerMethodField('get_moving_type') @@ -23,11 +25,12 @@ class SearchRouteSerializer(RouteSerializer): class Meta: model = Route fields = ( - 'id', 'username', 'owner_type', 'from_city_name', 'from_country_name', - 'to_city_name', 'to_country_name', 'formatted_cargo_type', - 'formatted_transport', 'type_transport', 'userImg', 'comment', - 'formatted_departure', 'formatted_arrival', 'country_from_icon', - 'country_to_icon' + 'id', 'username', 'owner_type', + 'from_city_name', 'from_city_russian_name', 'from_country_name', + 'to_city_name', 'to_city_russian_name', 'to_country_name', + 'formatted_cargo_type', 'formatted_transport', 'type_transport', + 'userImg', 'comment', 'formatted_departure', 'formatted_arrival', + 'country_from_icon', 'country_to_icon' ) def get_username(self, obj): @@ -79,3 +82,17 @@ class SearchRouteSerializer(RouteSerializer): def get_moving_type(self, obj): return self.get_formatted_transport(obj) + + def get_from_city_russian_name(self, obj): + try: + city = City.objects.get(id=obj.from_city_id) + return city.russian_name or city.name + except City.DoesNotExist: + return None + + def get_to_city_russian_name(self, obj): + try: + city = City.objects.get(id=obj.to_city_id) + return city.russian_name or city.name + except City.DoesNotExist: + return None diff --git a/backend/api/search/views.py b/backend/api/search/views.py index c7ff029..2444818 100644 --- a/backend/api/search/views.py +++ b/backend/api/search/views.py @@ -8,35 +8,8 @@ from rest_framework.exceptions import ValidationError from routes.constants.routeChoices import owner_type_choices from django.utils import timezone from django.db.models import Q -import cyrtranslit from urllib.parse import unquote - -def get_city_variations(city_name: str) -> list[str]: - """ - Получает варианты написания города, включая транслитерацию - """ - variations = set() - - # добавляем оригинальное название и его варианты с разным регистром - variations.add(city_name) - variations.add(city_name.lower()) - variations.add(city_name.title()) - - # пробуем добавить транслитерации - try: - # пробуем транслитерировать в обе стороны - lat = cyrtranslit.to_latin(city_name, 'ru') - cyr = cyrtranslit.to_cyrillic(city_name, 'ru') - - # добавляем варианты транслитерации с разным регистром - for variant in [lat, cyr]: - variations.add(variant) - variations.add(variant.lower()) - variations.add(variant.title()) - except: - pass - - return list(variations) +from api.utils.cityVariator import get_city_variations class SearchRouteListView(generics.ListAPIView): serializer_class = SearchRouteSerializer @@ -48,15 +21,12 @@ class SearchRouteListView(generics.ListAPIView): # получаем маршрут из URL и разбиваем его на города route = self.kwargs.get('route', '') - print(f"Raw route from URL: {route}") if route: # декодируем URL дважды, так как он может быть дважды закодирован route = unquote(unquote(route)) - print(f"Decoded route: {route}") try: from_city, to_city = route.split('-', 1) - print(f"Split cities - from: {from_city}, to: {to_city}") except ValueError: from_city = to_city = None else: @@ -82,8 +52,7 @@ class SearchRouteListView(generics.ListAPIView): to_city = unquote(to_city) except Exception as e: print(f"Error decoding to_city: {e}") - - print(f"Query params - from: {from_city}, to: {to_city}") + valid_types = [choice[0] for choice in owner_type_choices] current_time = timezone.now() @@ -99,10 +68,8 @@ class SearchRouteListView(generics.ListAPIView): # фильтруем по городам если они указаны if from_city: - print(f"Searching for from_city: {from_city}") # Получаем варианты написания для поиска from_city_variations = get_city_variations(from_city) - print(f"From city variations: {from_city_variations}") # Используем Q objects для поиска по обоим полям from_city_filter = ( Q(from_city__name__in=from_city_variations) | @@ -111,10 +78,8 @@ class SearchRouteListView(generics.ListAPIView): queryset = queryset.filter(from_city_filter) if to_city: - print(f"Searching for to_city: {to_city}") # получаем варианты написания для поиска to_city_variations = get_city_variations(to_city) - print(f"To city variations: {to_city_variations}") # используем Q objects для поиска по обоим полям to_city_filter = ( Q(to_city__name__in=to_city_variations) | @@ -128,4 +93,5 @@ class SearchRouteListView(generics.ListAPIView): else: # customer queryset = queryset.filter(arrival_DT__gt=current_time) + # print(queryset) return queryset.order_by('-arrival_DT') diff --git a/backend/api/utils/cityVariator.py b/backend/api/utils/cityVariator.py new file mode 100644 index 0000000..ec5927a --- /dev/null +++ b/backend/api/utils/cityVariator.py @@ -0,0 +1,28 @@ +import cyrtranslit + +def get_city_variations(city_name: str) -> list[str]: + """ + Получает варианты написания города, включая транслитерацию + """ + variations = set() + + # добавляем оригинальное название и его варианты с разным регистром + variations.add(city_name) + variations.add(city_name.lower()) + variations.add(city_name.title()) + + # пробуем добавить транслитерации + try: + # пробуем транслитерировать в обе стороны + lat = cyrtranslit.to_latin(city_name, 'ru') + cyr = cyrtranslit.to_cyrillic(city_name, 'ru') + + # добавляем варианты транслитерации с разным регистром + for variant in [lat, cyr]: + variations.add(variant) + variations.add(variant.lower()) + variations.add(variant.title()) + except: + pass + + return list(variations) \ No newline at end of file diff --git a/frontend/app/(urls)/search/[category]/[route]/page.tsx b/frontend/app/(urls)/search/[category]/[route]/page.tsx index dede80c..e677e5f 100644 --- a/frontend/app/(urls)/search/[category]/[route]/page.tsx +++ b/frontend/app/(urls)/search/[category]/[route]/page.tsx @@ -68,9 +68,11 @@ export default async function SearchPage(props: RouteSearchPageProps) { return (