Fixes: OrderViewSet fixes

This commit is contained in:
Egor Pavlovich Gorbunov 2025-06-07 18:31:27 +03:00
parent f5a87dac08
commit 6c2d452684
3 changed files with 64 additions and 5 deletions

View file

@ -21,6 +21,8 @@ from core.serializers import (
BuyUnregisteredOrderSerializer,
CategoryDetailSerializer,
CategorySimpleSerializer,
FeedbackDetailSerializer,
FeedbackSimpleSerializer,
OrderDetailSerializer,
OrderSimpleSerializer,
ProductDetailSerializer,
@ -521,3 +523,30 @@ ADDRESS_SCHEMA = {
},
),
}
FEEDBACK_SCHEMA = {
"list": extend_schema(
summary=_("list all feedbacks (simple view)"),
responses={status.HTTP_200_OK: FeedbackSimpleSerializer(many=True), **BASE_ERRORS},
),
"retrieve": extend_schema(
summary=_("retrieve a single feedback (detailed view)"),
responses={status.HTTP_200_OK: FeedbackDetailSerializer, **BASE_ERRORS},
),
"create": extend_schema(
summary=_("create a feedback"),
responses={status.HTTP_201_CREATED: FeedbackDetailSerializer, **BASE_ERRORS},
),
"destroy": extend_schema(
summary=_("delete a feedback"),
responses={status.HTTP_204_NO_CONTENT: {}, **BASE_ERRORS},
),
"update": extend_schema(
summary=_("rewrite an existing feedback saving non-editables"),
responses={status.HTTP_200_OK: FeedbackDetailSerializer, **BASE_ERRORS},
),
"partial_update": extend_schema(
summary=_("rewrite some fields of an existing feedback saving non-editables"),
responses={status.HTTP_200_OK: FeedbackDetailSerializer, **BASE_ERRORS},
),
}

View file

@ -51,7 +51,8 @@ class EvibesPermission(permissions.BasePermission):
}
def has_permission(self, request, view):
action = getattr(view, "action", None)
action = str(getattr(view, "action", None))
model = view.queryset.model
app_label = model._meta.app_label
model_name = model._meta.model_name
@ -59,6 +60,9 @@ class EvibesPermission(permissions.BasePermission):
if action == "create" and view.additional.get("create") == "ALLOW":
return True
if action == 'retrieve' and view.additional.get("retrieve") == "ALLOW":
return True
if action in self.USER_SCOPED_ACTIONS:
return True
@ -87,7 +91,14 @@ class EvibesPermission(permissions.BasePermission):
model = view.queryset.model
app_label = model._meta.app_label
model_name = model._meta.model_name
action = getattr(view, "action", None)
action = str(getattr(view, "action", None))
if action == 'retrieve' and request.method in permissions.SAFE_METHODS and hasattr(obj,
'user') and obj.user is None:
lookup_val = view.kwargs.get(view.lookup_field)
if str(obj.human_readable_id) == lookup_val or str(obj.uuid) == lookup_val:
return True
perm_prefix = self.ACTION_PERM_MAP.get(action)
return bool(perm_prefix and request.user.has_perm(f"{app_label}.{perm_prefix}_{model_name}"))

View file

@ -1,5 +1,6 @@
from uuid import UUID
from django.db.models import Q
from django.http import Http404
from django.utils.decorators import method_decorator
from django.utils.translation import gettext_lazy as _
@ -10,6 +11,7 @@ from drf_spectacular.utils import extend_schema_view
from rest_framework import status
from rest_framework.decorators import action
from rest_framework.exceptions import PermissionDenied
from rest_framework.generics import get_object_or_404
from rest_framework.renderers import MultiPartRenderer
from rest_framework.response import Response
from rest_framework.viewsets import ModelViewSet
@ -22,6 +24,7 @@ from core.docs.drf.viewsets import (
ATTRIBUTE_SCHEMA,
ATTRIBUTE_VALUE_SCHEMA,
CATEGORY_SCHEMA,
FEEDBACK_SCHEMA,
ORDER_SCHEMA,
PRODUCT_SCHEMA,
WISHLIST_SCHEMA,
@ -218,6 +221,7 @@ class VendorViewSet(EvibesViewSet):
}
@extend_schema_view(**FEEDBACK_SCHEMA)
class FeedbackViewSet(EvibesViewSet):
queryset = Feedback.objects.all()
filter_backends = [DjangoFilterBackend]
@ -230,6 +234,7 @@ class FeedbackViewSet(EvibesViewSet):
@extend_schema_view(**ORDER_SCHEMA)
class OrderViewSet(EvibesViewSet):
lookup_field = 'lookup_value'
queryset = Order.objects.prefetch_related("order_products").all()
filter_backends = [DjangoFilterBackend]
filterset_class = OrderFilter
@ -240,6 +245,12 @@ class OrderViewSet(EvibesViewSet):
"add_order_product": AddOrderProductSerializer,
"remove_order_product": RemoveOrderProductSerializer,
}
additional = {
"retrieve": "ALLOW"
}
def get_serializer_class(self):
return self.action_serializer_classes.get(self.action, super().get_serializer_class())
def get_queryset(self):
qs = super().get_queryset()
@ -248,15 +259,23 @@ class OrderViewSet(EvibesViewSet):
if user.has_perm("core.view_order"):
return qs
return qs.filter(user=user)
return qs.filter(Q(user=user) | Q(user__isnull=True))
def get_object(self):
lookup_val = self.kwargs.get(self.lookup_field)
queryset = self.filter_queryset(self.get_queryset())
obj = get_object_or_404(
queryset,
Q(uuid=lookup_val) | Q(human_readable_id=lookup_val)
)
self.check_object_permissions(self.request, obj)
return obj
@action(detail=False, methods=["get"], url_path="current")
def current(self, request):
if not request.user.is_authenticated:
raise PermissionDenied(permission_denied_message)
order = Order.objects.get(user=request.user, status="PENDING")
if not request.user == order.user:
raise PermissionDenied(permission_denied_message)
return Response(
status=status.HTTP_200_OK,
data=OrderDetailSerializer(order).data,