db_kyc_project/backend/users/views/ranking.py
Даня Вакуленков 4a18a785e9 Add backend code
2024-12-10 23:31:35 +03:00

54 lines
2.3 KiB
Python

from django.db.models import F
from django.db.models.functions import RowNumber
from django.db.models.expressions import Window
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework.status import HTTP_200_OK
from django_cte import With
from users.serializers import TGUserSerializer
from users.models import TGUser
from misc.models import Setting
@api_view(['GET'])
def top(request):
limit = int(request.query_params.get('limit', Setting.objects.get(name='DEFAULT_TOP_LIMIT').value['value']))
qs = (
TGUser.objects.order_by('-points', 'user_id')
.annotate(row_number=Window(expression=RowNumber(), order_by=[-F('points'), F('user_id')]))[:limit]
)
serializer = TGUserSerializer(qs, many=True)
return Response(status=HTTP_200_OK, data=serializer.data)
@api_view(['GET'])
def neighbours(request):
limit = int(request.query_params.get('limit', Setting.objects.get(name='DEFAULT_NEIGHBOUR_LIMIT').value['value']))
cte = With(
TGUser.objects.annotate(row_number=Window(expression=RowNumber(), order_by=[-F('points'), F('user_id')])))
full_qs = cte.join(TGUser, tg_id=cte.col.tg_id).with_cte(cte).annotate(row_number=cte.col.row_number)
self = full_qs.get(pk=request.user.tg_user.pk)
qs = (
full_qs.filter(pk=request.user.tg_user.pk)
.union(full_qs.filter(row_number__lt=self.rank).order_by('points', '-user_id')[:limit])
.union(full_qs.filter(row_number__gt=self.rank).order_by('-points', 'user_id')[:limit])
.order_by('-points', 'user_id')
)
serializer = TGUserSerializer(qs, many=True)
return Response(status=HTTP_200_OK, data=serializer.data)
@api_view(['GET'])
def friends(request):
cte = With(
TGUser.objects.annotate(row_number=Window(expression=RowNumber(), order_by=[-F('points'), F('user_id')])))
full_qs = cte.join(TGUser, tg_id=cte.col.tg_id).with_cte(cte).annotate(row_number=cte.col.row_number)
self = full_qs.get(pk=request.user.tg_user.pk)
qs = (
full_qs.filter(pk=request.user.tg_user.pk)
.union(full_qs.filter(referred_by_id=self.pk).order_by('points', '-user_id'))
.order_by('-points', 'user_id')
)
serializer = TGUserSerializer(qs, many=True)
return Response(status=HTTP_200_OK, data=serializer.data)