feat(profile): add activity sorting and payment filters

This commit is contained in:
2026-10-02 13:00:53 +03:30
parent ba829055a5
commit 682ef76396
2 changed files with 47 additions and 10 deletions

View File

@@ -3,7 +3,7 @@ from __future__ import annotations
import logging import logging
import mimetypes import mimetypes
from pathlib import Path from pathlib import Path
from typing import List, Optional from typing import List, Literal, Optional
from django.conf import settings from django.conf import settings
from django.contrib.auth import get_user_model from django.contrib.auth import get_user_model
@@ -624,19 +624,34 @@ def _profile_page_payload(queryset, page: int, page_size: int = 10):
@blog_router.get("/me/activity/liked", response=PaginatedProfilePostsSchema, auth=jwt_auth) @blog_router.get("/me/activity/liked", response=PaginatedProfilePostsSchema, auth=jwt_auth)
def my_liked_posts(request, page: int = Query(1, ge=1)): def my_liked_posts(
queryset = _published_queryset().filter(likes__user=request.auth).order_by("-published_at", "-created_at", "-id") request,
page: int = Query(1, ge=1),
sort_order: Literal["asc", "desc"] = Query("desc"),
):
sort_prefix = "" if sort_order == "asc" else "-"
queryset = _published_queryset().filter(likes__user=request.auth).order_by(f"{sort_prefix}likes__created_at", "-id")
return _profile_page_payload(queryset, page) return _profile_page_payload(queryset, page)
@blog_router.get("/me/activity/saved", response=PaginatedProfilePostsSchema, auth=jwt_auth) @blog_router.get("/me/activity/saved", response=PaginatedProfilePostsSchema, auth=jwt_auth)
def my_saved_posts(request, page: int = Query(1, ge=1)): def my_saved_posts(
queryset = _published_queryset().filter(saves__user=request.auth).order_by("-published_at", "-created_at", "-id") request,
page: int = Query(1, ge=1),
sort_order: Literal["asc", "desc"] = Query("desc"),
):
sort_prefix = "" if sort_order == "asc" else "-"
queryset = _published_queryset().filter(saves__user=request.auth).order_by(f"{sort_prefix}saves__created_at", "-id")
return _profile_page_payload(queryset, page) return _profile_page_payload(queryset, page)
@blog_router.get("/me/activity/comments", response=PaginatedProfileCommentsSchema, auth=jwt_auth) @blog_router.get("/me/activity/comments", response=PaginatedProfileCommentsSchema, auth=jwt_auth)
def my_blog_comments(request, page: int = Query(1, ge=1)): def my_blog_comments(
request,
page: int = Query(1, ge=1),
sort_order: Literal["asc", "desc"] = Query("desc"),
):
sort_prefix = "" if sort_order == "asc" else "-"
queryset = ( queryset = (
Comment.objects.filter( Comment.objects.filter(
author=request.auth, author=request.auth,
@@ -647,7 +662,7 @@ def my_blog_comments(request, page: int = Query(1, ge=1)):
post__is_deleted=False, post__is_deleted=False,
) )
.select_related("author", "post") .select_related("author", "post")
.order_by("-created_at", "-id") .order_by(f"{sort_prefix}created_at", "-id")
) )
return _profile_page_payload(queryset, page) return _profile_page_payload(queryset, page)

View File

@@ -7,8 +7,9 @@ from django.conf import settings
from django.shortcuts import redirect, get_object_or_404 from django.shortcuts import redirect, get_object_or_404
from django.utils import timezone from django.utils import timezone
from django.db.models import Count, Q from django.db.models import Count, Q
from django.db.models.functions import Coalesce
from django.db import transaction from django.db import transaction
from typing import List from typing import List, Literal
from ninja import Query, Router from ninja import Query, Router
from ninja.errors import HttpError from ninja.errors import HttpError
@@ -89,7 +90,13 @@ def _user_payment_payload(request, payment, status_names):
@payments_router.get("/me/paginated", response=PaginatedUserPaymentsSchema, auth=jwt_auth) @payments_router.get("/me/paginated", response=PaginatedUserPaymentsSchema, auth=jwt_auth)
def my_payments_paginated(request, page: int = Query(1, ge=1)): def my_payments_paginated(
request,
page: int = Query(1, ge=1),
status: Literal["all", "initiated", "pending", "paid", "failed", "canceled"] = Query("all"),
sort_by: Literal["time", "amount"] = Query("time"),
sort_order: Literal["asc", "desc"] = Query("desc"),
):
page_size = 10 page_size = 10
status_names = { status_names = {
Payment.OrderStatusChoices.INIT: "initiated", Payment.OrderStatusChoices.INIT: "initiated",
@@ -98,7 +105,22 @@ def my_payments_paginated(request, page: int = Query(1, ge=1)):
Payment.OrderStatusChoices.FAILED: "failed", Payment.OrderStatusChoices.FAILED: "failed",
Payment.OrderStatusChoices.CANCELED: "canceled", Payment.OrderStatusChoices.CANCELED: "canceled",
} }
queryset = Payment.objects.filter(user=request.auth).select_related("event").order_by("-created_at", "-id") queryset = Payment.objects.filter(user=request.auth).select_related("event")
status_values = {
"initiated": Payment.OrderStatusChoices.INIT,
"pending": Payment.OrderStatusChoices.PENDING,
"paid": Payment.OrderStatusChoices.PAID,
"failed": Payment.OrderStatusChoices.FAILED,
"canceled": Payment.OrderStatusChoices.CANCELED,
}
if status != "all":
queryset = queryset.filter(status=status_values[status])
sort_field = "amount" if sort_by == "amount" else "_payment_time"
sort_prefix = "" if sort_order == "asc" else "-"
queryset = queryset.annotate(_payment_time=Coalesce("verified_at", "created_at")).order_by(
f"{sort_prefix}{sort_field}", "-id"
)
count = queryset.count() count = queryset.count()
total_pages = max(1, (count + page_size - 1) // page_size) total_pages = max(1, (count + page_size - 1) // page_size)
start = (page - 1) * page_size start = (page - 1) * page_size