winofy-backend/apps/locations/views.py
Ali Asadi fa9a69fff3 Add search to city/neighborhood endpoints; document filters for swagger
Neighborhood filtering was UUID-only; add name-based search on both
GET /api/v1/cities/ and GET /api/v1/neighborhoods/ (the latter also
matching by city name), and document all params for drf-spectacular.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-22 11:25:45 +03:30

72 lines
2.5 KiB
Python

from django.db.models import Q
from drf_spectacular.utils import OpenApiParameter, extend_schema, extend_schema_view
from rest_framework import mixins, viewsets
from rest_framework.permissions import AllowAny, IsAuthenticated
from apps.gooyal_oauth2.rest_framework import IsAuthenticatedOrTokenMatchesOASRequirements
from .models import Address, City, Neighborhood
from .serializers import AddressSerializer, CitySerializer, NeighborhoodSerializer
@extend_schema_view(
list=extend_schema(
parameters=[
OpenApiParameter('search', str, description='Search by city name.'),
],
),
)
class CityViewSet(mixins.ListModelMixin, mixins.RetrieveModelMixin, viewsets.GenericViewSet):
schema_tags = ['Locations']
permission_classes = [AllowAny]
serializer_class = CitySerializer
queryset = City.objects.filter(is_active=True)
def get_queryset(self):
queryset = super().get_queryset()
search = self.request.query_params.get('search')
if search:
queryset = queryset.filter(name__icontains=search)
return queryset
@extend_schema_view(
list=extend_schema(
parameters=[
OpenApiParameter('city', str, description='Filter by city UUID.'),
OpenApiParameter('search', str, description='Search by neighborhood or city name.'),
],
),
)
class NeighborhoodViewSet(mixins.ListModelMixin, mixins.RetrieveModelMixin, viewsets.GenericViewSet):
schema_tags = ['Locations']
permission_classes = [AllowAny]
serializer_class = NeighborhoodSerializer
queryset = Neighborhood.objects.filter(is_active=True).select_related('city')
def get_queryset(self):
queryset = super().get_queryset()
city_uuid = self.request.query_params.get('city')
if city_uuid:
queryset = queryset.filter(city__uuid=city_uuid)
search = self.request.query_params.get('search')
if search:
queryset = queryset.filter(Q(name__icontains=search) | Q(city__name__icontains=search))
return queryset
class AddressViewSet(viewsets.ModelViewSet):
schema_tags = ['Addresses']
serializer_class = AddressSerializer
permission_classes = [IsAuthenticatedOrTokenMatchesOASRequirements]
required_alternate_scopes = {
"POST": [[]],
}
def get_queryset(self):
if getattr(self, 'swagger_fake_view', False):
return Address.objects.none()
return Address.objects.filter(user=self.request.user).select_related('city', 'neighborhood')