diff --git a/apps/blog/api/views.py b/apps/blog/api/views.py index d63dc48..4d70cb8 100644 --- a/apps/blog/api/views.py +++ b/apps/blog/api/views.py @@ -3,7 +3,7 @@ from __future__ import annotations import logging import mimetypes from pathlib import Path -from typing import List, Optional +from typing import List, Literal, Optional from django.conf import settings 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) -def my_liked_posts(request, page: int = Query(1, ge=1)): - queryset = _published_queryset().filter(likes__user=request.auth).order_by("-published_at", "-created_at", "-id") +def my_liked_posts( + 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) @blog_router.get("/me/activity/saved", response=PaginatedProfilePostsSchema, auth=jwt_auth) -def my_saved_posts(request, page: int = Query(1, ge=1)): - queryset = _published_queryset().filter(saves__user=request.auth).order_by("-published_at", "-created_at", "-id") +def my_saved_posts( + 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) @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 = ( Comment.objects.filter( author=request.auth, @@ -647,7 +662,7 @@ def my_blog_comments(request, page: int = Query(1, ge=1)): post__is_deleted=False, ) .select_related("author", "post") - .order_by("-created_at", "-id") + .order_by(f"{sort_prefix}created_at", "-id") ) return _profile_page_payload(queryset, page) diff --git a/apps/payments/api/views.py b/apps/payments/api/views.py index 9ba26a8..973e784 100644 --- a/apps/payments/api/views.py +++ b/apps/payments/api/views.py @@ -7,8 +7,9 @@ from django.conf import settings from django.shortcuts import redirect, get_object_or_404 from django.utils import timezone from django.db.models import Count, Q +from django.db.models.functions import Coalesce from django.db import transaction -from typing import List +from typing import List, Literal from ninja import Query, Router 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) -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 status_names = { 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.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() total_pages = max(1, (count + page_size - 1) // page_size) start = (page - 1) * page_size