operations_project/apps/discovery/views.py
2025-05-20 15:57:10 +08:00

277 lines
10 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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