from django.shortcuts import render from django.db.models import Q from rest_framework import viewsets, status from rest_framework.decorators import action from rest_framework.response import Response from rest_framework.permissions import AllowAny from django.utils import timezone from .models import SearchSession, Creator from .serializers import ( SearchSessionSerializer, SearchSessionDetailSerializer, CreatorSerializer, CreatorDetailSerializer ) from .pagination import StandardResultsSetPagination class ApiResponse: """API统一响应格式""" @staticmethod def success(data=None, message="操作成功"): return Response({ "code": 200, "message": message, "data": data }) @staticmethod def error(message="操作失败", code=400, data=None): return Response({ "code": code, "message": message, "data": data }, status=status.HTTP_200_OK) # 始终返回200状态码,错误信息在内容中提供 class SearchSessionViewSet(viewsets.ModelViewSet): """搜索会话视图集""" queryset = SearchSession.objects.all() serializer_class = SearchSessionSerializer permission_classes = [AllowAny] pagination_class = StandardResultsSetPagination def get_serializer_class(self): if self.action == 'retrieve': return SearchSessionDetailSerializer return SearchSessionSerializer def list(self, request, *args, **kwargs): queryset = self.filter_queryset(self.get_queryset()) page = self.paginate_queryset(queryset) if page is not None: serializer = self.get_serializer(page, many=True) return self.get_paginated_response(serializer.data) serializer = self.get_serializer(queryset, many=True) return ApiResponse.success(serializer.data, "获取搜索会话列表成功") def retrieve(self, request, *args, **kwargs): instance = self.get_object() serializer = self.get_serializer(instance) return ApiResponse.success(serializer.data, "获取搜索会话详情成功") def create(self, request, *args, **kwargs): serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) self.perform_create(serializer) headers = self.get_success_headers(serializer.data) return ApiResponse.success(serializer.data, "创建搜索会话成功") def update(self, request, *args, **kwargs): partial = kwargs.pop('partial', False) instance = self.get_object() serializer = self.get_serializer(instance, data=request.data, partial=partial) serializer.is_valid(raise_exception=True) self.perform_update(serializer) return ApiResponse.success(serializer.data, "更新搜索会话成功") def destroy(self, request, *args, **kwargs): instance = self.get_object() self.perform_destroy(instance) return ApiResponse.success(None, "删除搜索会话成功") @action(detail=True, methods=['get']) def results(self, request, pk=None): """获取指定会话的搜索结果""" session = self.get_object() creators = session.creators.all() page = self.paginate_queryset(creators) if page is not None: serializer = CreatorSerializer(page, many=True) return self.get_paginated_response(serializer.data) serializer = CreatorSerializer(creators, many=True) return ApiResponse.success(serializer.data, "获取会话创作者列表成功") class CreatorDiscoveryViewSet(viewsets.ReadOnlyModelViewSet): """创作者发现视图集""" queryset = Creator.objects.all() serializer_class = CreatorSerializer permission_classes = [AllowAny] pagination_class = StandardResultsSetPagination def get_serializer_class(self): if self.action == 'retrieve': return CreatorDetailSerializer return CreatorSerializer def list(self, request, *args, **kwargs): queryset = self.filter_queryset(self.get_queryset()) page = self.paginate_queryset(queryset) if page is not None: serializer = self.get_serializer(page, many=True) return self.get_paginated_response(serializer.data) serializer = self.get_serializer(queryset, many=True) return ApiResponse.success(serializer.data, "获取创作者列表成功") def retrieve(self, request, *args, **kwargs): instance = self.get_object() serializer = self.get_serializer(instance) return ApiResponse.success(serializer.data, "获取创作者详情成功") @action(detail=False, methods=['post']) def search(self, request): """搜索创作者""" query = request.data.get('query', '') category = request.data.get('category', None) ecommerce_level = request.data.get('ecommerce_level', None) exposure_level = request.data.get('exposure_level', None) # 创建模拟搜索会话 session = self._create_mock_search_session() # 生成模拟搜索结果 creators = self._generate_mock_creators(session, query, category, ecommerce_level, exposure_level) # 返回会话详情 serializer = SearchSessionDetailSerializer(session) return ApiResponse.success(serializer.data, "搜索创作者成功") def _create_mock_search_session(self): """创建模拟搜索会话""" # 获取当前最大会话编号并加1 max_session_number = SearchSession.objects.all().order_by('-session_number').first() session_number = 1 if max_session_number: session_number = max_session_number.session_number + 1 # 创建新会话 session = SearchSession.objects.create( session_number=session_number, creator_count=100, shoppable_creators=26, avg_followers=162.2, avg_gmv=534.1, avg_video_views=1.9, date_created=timezone.now().date() # 将datetime转换为date类型 ) return session def _generate_mock_creators(self, session, query, category=None, ecommerce_level=None, exposure_level=None): """生成模拟创作者数据""" # 模拟数据 - 这里可以根据实际需求调整 mock_creators = [ { "name": "Mock Creator 1", "category": "Phones & Electronics", "ecommerce_level": "L2", "exposure_level": "KOC-1", "followers": 162.2, "gmv": 534.1, "items_sold": 18.1, "avg_video_views": 1.9, "has_ecommerce": True }, { "name": "Mock Creator 2", "category": "Womenswear & Underwear", "ecommerce_level": "L3", "exposure_level": "KOL-3", "followers": 162.2, "gmv": 534.1, "items_sold": 18.1, "avg_video_views": 1.9, "has_ecommerce": False }, { "name": "Mock Creator 3", "category": "Sports & Outdoor", "ecommerce_level": "L4", "exposure_level": "KOC-2", "followers": 162.2, "gmv": 534.1, "items_sold": 18.1, "avg_video_views": 1.9, "has_ecommerce": True }, { "name": "Mock Creator 4", "category": "Food & Beverage", "ecommerce_level": "L1", "exposure_level": "KOC-2", "followers": 162.2, "gmv": 534.1, "items_sold": 18.1, "avg_video_views": 1.9, "has_ecommerce": True }, { "name": "Mock Creator 5", "category": "Health", "ecommerce_level": "L5", "exposure_level": "KOL-2", "followers": 162.2, "gmv": 534.1, "items_sold": 18.1, "avg_video_views": 1.9, "has_ecommerce": False }, { "name": "Mock Creator 6", "category": "Kitchenware", "ecommerce_level": "New tag", "exposure_level": "New tag", "followers": 162.2, "gmv": 534.1, "items_sold": 18.1, "avg_video_views": 1.9, "has_ecommerce": True }, { "name": "Mock Creator 7", "category": "Furniture", "ecommerce_level": "New tag", "exposure_level": "New tag", "followers": 162.2, "gmv": 534.1, "items_sold": 18.1, "avg_video_views": 1.9, "has_ecommerce": False }, { "name": "Mock Creator 8", "category": "Shoes", "ecommerce_level": "New tag", "exposure_level": "New tag", "followers": 162.2, "gmv": 534.1, "items_sold": 18.1, "avg_video_views": 1.9, "has_ecommerce": True }, ] # 根据查询条件过滤模拟数据 filtered_creators = mock_creators if category: filtered_creators = [c for c in filtered_creators if c['category'] == category] if ecommerce_level: filtered_creators = [c for c in filtered_creators if c['ecommerce_level'] == ecommerce_level] if exposure_level: filtered_creators = [c for c in filtered_creators if c['exposure_level'] == exposure_level] # 创建创作者记录 for creator_data in filtered_creators: Creator.objects.create( session=session, **creator_data ) # 更新会话统计信息 session.creator_count = len(filtered_creators) session.shoppable_creators = len([c for c in filtered_creators if c['has_ecommerce']]) session.save() return filtered_creators