| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115 |
- from rest_framework import viewsets
- from rest_framework.permissions import IsAuthenticated, AllowAny
- from rest_framework.decorators import action
- from rest_framework.response import Response
- from django_filters.rest_framework import DjangoFilterBackend
- from django.db.models import Q
- from .models import Profile, Opportunity, IntroductionRequest
- from .serializers import ProfileSerializer, OpportunitySerializer, IntroductionRequestSerializer, LeaderRowSerializer
- from .services.matching import rank_users_for, rank_opportunities_for
- from .services.benefit import build_leaderboard_queryset
- class ProfileViewSet(viewsets.ModelViewSet):
- queryset = Profile.objects.all()
- serializer_class = ProfileSerializer
- permission_classes = [IsAuthenticated]
- filter_backends = [DjangoFilterBackend]
- filterset_fields = {
- 'user__username': ['exact', 'icontains'],
- 'is_verified': ['exact'],
- 'industry': ['exact', 'icontains'],
- 'interests': ['icontains'],
- 'tags__name': ['exact', 'icontains'],
- }
- @action(detail=False, methods=['get'], permission_classes=[IsAuthenticated])
- def match(self, request):
- """Return top user matches for the authenticated user."""
- ranked = rank_users_for(request.user, k=int(request.query_params.get('k', 20)))
- payload = [
- {
- 'score': round(item.score, 4),
- 'profile': ProfileSerializer(item.profile, context={'request': request}).data,
- }
- for item in ranked
- ]
- return Response(payload)
- class OpportunityViewSet(viewsets.ModelViewSet):
- queryset = Opportunity.objects.all()
- serializer_class = OpportunitySerializer
- permission_classes = [IsAuthenticated]
- filter_backends = [DjangoFilterBackend]
- filterset_fields = {
- 'title': ['exact', 'icontains'],
- 'created_at': ['gte', 'lte'],
- }
- @action(detail=False, methods=['get'], permission_classes=[IsAuthenticated])
- def recommend(self, request):
- """Return top opportunity recommendations for the authenticated user."""
- ranked = rank_opportunities_for(request.user, k=int(request.query_params.get('k', 20)))
- payload = [
- {
- 'score': round(item.score, 4),
- 'opportunity': OpportunitySerializer(item.opportunity, context={'request': request}).data,
- }
- for item in ranked
- ]
- return Response(payload)
- class IntroductionRequestViewSet(viewsets.ModelViewSet):
- queryset = IntroductionRequest.objects.all()
- serializer_class = IntroductionRequestSerializer
- permission_classes = [IsAuthenticated]
- filter_backends = [DjangoFilterBackend]
- filterset_fields = {
- 'from_user__username': ['exact', 'icontains'],
- 'to_user__username': ['exact', 'icontains'],
- 'is_accepted': ['exact'],
- 'message': ['icontains'],
- }
- def get_queryset(self):
- return IntroductionRequest.objects.filter(
- Q(from_user=self.request.user) | Q(to_user=self.request.user)
- )
- def perform_create(self, serializer):
- serializer.save(from_user=self.request.user)
- class LeaderboardView(viewsets.ViewSet):
- permission_classes = [AllowAny]
- def list(self, request):
- period = request.query_params.get('period', 'weekly')
- try:
- limit = min(int(request.query_params.get('limit', 100)), 500)
- except Exception:
- limit = 100
- try:
- offset = int(request.query_params.get('offset', 0))
- except Exception:
- offset = 0
- qs = build_leaderboard_queryset(period)
- page = qs[offset:offset+limit]
- data = LeaderRowSerializer(page, many=True).data
- return Response({"period": period, "offset": offset, "limit": limit, "results": data})
- class LeaderboardMeView(viewsets.ViewSet):
- permission_classes = [IsAuthenticated]
- def list(self, request):
- period = request.query_params.get('period', 'weekly')
- qs = build_leaderboard_queryset(period)
- me = qs.filter(id=request.user.id).first()
- if not me:
- return Response({
- "period": period,
- "result": None,
- "detail": "No rank for current user in this period.",
- })
- return Response({"period": period, "result": LeaderRowSerializer(me).data})
|