Fixes: ORDER_SCHEMA

This commit is contained in:
Egor Pavlovich Gorbunov 2025-06-08 16:42:18 +03:00
parent e716f88eac
commit 7b60cf3d6d
3 changed files with 110 additions and 9 deletions

View file

@ -149,8 +149,63 @@ ORDER_SCHEMA = {
"list": extend_schema(
summary=_("list all orders (simple view)"),
description=_("for non-staff users, only their own orders are returned."),
parameters=[
OpenApiParameter(
name="search",
type=OpenApiTypes.STR,
description=_(
"Case-insensitive substring search across human_readable_id, "
"order_products.product.name, and order_products.product.partnumber"
),
),
OpenApiParameter(
name="min_buy_time",
type=OpenApiTypes.DATETIME,
description=_("Filter orders with buy_time >= this ISO 8601 datetime"),
),
OpenApiParameter(
name="max_buy_time",
type=OpenApiTypes.DATETIME,
description=_("Filter orders with buy_time <= this ISO 8601 datetime"),
),
OpenApiParameter(
name="uuid",
type=OpenApiTypes.UUID,
description=_("Filter by exact order UUID"),
),
OpenApiParameter(
name="human_readable_id",
type=OpenApiTypes.STR,
description=_("Filter by exact human-readable order ID"),
),
OpenApiParameter(
name="user_email",
type=OpenApiTypes.STR,
description=_("Filter by user's email (case-insensitive exact match)"),
),
OpenApiParameter(
name="user",
type=OpenApiTypes.UUID,
description=_("Filter by user's UUID"),
),
OpenApiParameter(
name="status",
type=OpenApiTypes.STR,
description=_("Filter by order status (case-insensitive substring match)"),
),
OpenApiParameter(
name="order_by",
type=OpenApiTypes.STR,
description=_(
"Order by one of: uuid, human_readable_id, user_email, user, "
"status, created, modified, buy_time, random. "
"Prefix with '-' for descending (e.g. '-buy_time')."
),
),
],
responses={status.HTTP_200_OK: OrderSimpleSerializer(many=True), **BASE_ERRORS},
),
# ... other actions unchanged
"retrieve": extend_schema(
summary=_("retrieve a single order (detailed view)"),
responses={status.HTTP_200_OK: OrderDetailSerializer(), **BASE_ERRORS},

View file

@ -5,7 +5,16 @@ import uuid
from django.db.models import Avg, FloatField, OuterRef, Q, Subquery, Value
from django.db.models.functions import Coalesce
from django.utils.http import urlsafe_base64_decode
from django_filters import BaseInFilter, BooleanFilter, CharFilter, FilterSet, NumberFilter, OrderingFilter, UUIDFilter
from django_filters import (
BaseInFilter,
BooleanFilter,
CharFilter,
DateTimeFilter,
FilterSet,
NumberFilter,
OrderingFilter,
UUIDFilter,
)
from core.models import Brand, Category, Feedback, Order, Product, Wishlist
@ -210,11 +219,27 @@ class ProductFilter(FilterSet):
class OrderFilter(FilterSet):
uuid = UUIDFilter(field_name="uuid", lookup_expr="exact")
user_email = CharFilter(field_name="user__email", lookup_expr="iexact")
user = UUIDFilter(field_name="user__uuid", lookup_expr="exact")
status = CharFilter(field_name="status", lookup_expr="icontains", label="Status")
human_readable_id = CharFilter(field_name="human_readable_id", lookup_expr="exact")
search = CharFilter(
method='filter_search',
label='Search (ID, product name or part number)',
)
min_buy_time = DateTimeFilter(
field_name='buy_time',
lookup_expr='gte',
label='Bought after (inclusive)'
)
max_buy_time = DateTimeFilter(
field_name='buy_time',
lookup_expr='lte',
label='Bought before (inclusive)'
)
uuid = UUIDFilter(field_name='uuid', lookup_expr='exact')
user_email = CharFilter(field_name='user__email', lookup_expr='iexact')
user = UUIDFilter(field_name='user__uuid', lookup_expr='exact')
status = CharFilter(field_name='status', lookup_expr='icontains', label='Status')
human_readable_id = CharFilter(field_name='human_readable_id', lookup_expr='exact')
order_by = OrderingFilter(
fields=(
@ -232,7 +257,28 @@ class OrderFilter(FilterSet):
class Meta:
model = Order
fields = ["uuid", "human_readable_id", "user_email", "user", "status", "order_by"]
fields = [
"uuid",
"human_readable_id",
"user_email",
"user",
"status",
"order_by",
"search",
"min_buy_time",
"max_buy_time",
]
def filter_search(self, queryset, _name, value):
return (
queryset
.filter(
Q(human_readable_id__icontains=value) |
Q(order_products__product__name__icontains=value) |
Q(order_products__product__partnumber__icontains=value)
)
.distinct()
)
class WishlistFilter(FilterSet):
@ -267,7 +313,7 @@ class CategoryFilter(FilterSet):
model = Category
fields = ["uuid", "name", "parent_uuid", "slug"]
def filter_parent_uuid(self, queryset, name, value):
def filter_parent_uuid(self, queryset, _name, value):
"""
If ?parent_uuid= or ?parent_uuid=null, return items with parent=None.
Otherwise treat `value` as a real UUID and filter parent__uuid=value.

View file

@ -70,6 +70,6 @@ class AddressManager(models.Manager):
region=region,
postal_code=postal_code,
country=country,
user=kwargs.pop('user'),
defaults={"api_response": data, "location": location},
**kwargs,
)[0]