Features: 1) Introduced extend_schema for multiple viewsets to improve OpenAPI documentation; 2) Added detailed schema definitions for blog and payments viewsets using drf-spectacular; 3) Transitioned download_digital_asset functionality to class-based DownloadDigitalAssetView for better modularity.
Fixes: 1) Standardized error responses in `DownloadDigitalAssetView`. Extra: Improved maintainability by refactoring serializers and schema definitions into modular components; updated API URLs to use new class-based view.
This commit is contained in:
parent
c9fd4b4f98
commit
c0fcde4bb4
8 changed files with 323 additions and 65 deletions
17
blog/docs/drf/viewsets.py
Normal file
17
blog/docs/drf/viewsets.py
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
from django.utils.translation import gettext_lazy as _
|
||||
from drf_spectacular.utils import extend_schema
|
||||
from rest_framework import status
|
||||
|
||||
from core.docs.drf import BASE_ERRORS
|
||||
from blog.serializers import PostSerializer
|
||||
|
||||
POST_SCHEMA = {
|
||||
"list": extend_schema(
|
||||
summary=_("list all posts (read-only)"),
|
||||
responses={status.HTTP_200_OK: PostSerializer(many=True), **BASE_ERRORS},
|
||||
),
|
||||
"retrieve": extend_schema(
|
||||
summary=_("retrieve a single post (read-only)"),
|
||||
responses={status.HTTP_200_OK: PostSerializer(), **BASE_ERRORS},
|
||||
),
|
||||
}
|
||||
|
|
@ -1,28 +1,30 @@
|
|||
from django.utils.translation import gettext_lazy as _
|
||||
from django_filters.rest_framework import DjangoFilterBackend
|
||||
from drf_spectacular.utils import extend_schema_view
|
||||
from rest_framework.viewsets import ReadOnlyModelViewSet
|
||||
|
||||
from blog.filters import PostFilter
|
||||
from blog.models import Post
|
||||
from blog.serializers import PostSerializer
|
||||
from blog.docs.drf.viewsets import POST_SCHEMA
|
||||
from core.permissions import EvibesPermission
|
||||
|
||||
|
||||
@extend_schema_view(**POST_SCHEMA)
|
||||
class PostViewSet(ReadOnlyModelViewSet): # type: ignore [type-arg]
|
||||
"""
|
||||
Encapsulates operations for managing and retrieving Post entities in a read-only model view set.
|
||||
|
||||
This class is tailored to handle Post objects that are active and allows filtration based on defined
|
||||
filters. It integrates with Django's backend filtering system and ensures operations align with the
|
||||
defined permissions. The view set also includes an additional "retrieve" permission configuration.
|
||||
|
||||
Attributes:
|
||||
serializer_class: Specifies the serializer to be used for Post objects.
|
||||
permission_classes: Defines the permissions required to interact with this view set.
|
||||
queryset: Determines the initial queryset, filtered to include only active Post objects.
|
||||
filter_backends: Lists the backends to be used for filtering querysets.
|
||||
filterset_class: Defines the set of filters used for filtering Post objects.
|
||||
additional: Contains additional configuration, such as specific action permissions.
|
||||
"""
|
||||
__doc__ = _( # type: ignore [assignment]
|
||||
"Encapsulates operations for managing and retrieving Post entities in a read-only model view set.\n\n"
|
||||
"This class is tailored to handle Post objects that are active and allows filtration based on defined "
|
||||
"filters. It integrates with Django's backend filtering system and ensures operations align with the "
|
||||
"defined permissions. The view set also includes an additional 'retrieve' permission configuration.\n\n"
|
||||
"Attributes:\n"
|
||||
" serializer_class: Specifies the serializer to be used for Post objects.\n"
|
||||
" permission_classes: Defines the permissions required to interact with this view set.\n"
|
||||
" queryset: Determines the initial queryset, filtered to include only active Post objects.\n"
|
||||
" filter_backends: Lists the backends to be used for filtering querysets.\n"
|
||||
" filterset_class: Defines the set of filters used for filtering Post objects.\n"
|
||||
" additional: Contains additional configuration, such as specific action permissions."
|
||||
)
|
||||
|
||||
serializer_class = PostSerializer
|
||||
permission_classes = (EvibesPermission,)
|
||||
|
|
|
|||
|
|
@ -5,11 +5,11 @@ from core.sitemaps import BrandSitemap, CategorySitemap, ProductSitemap, StaticP
|
|||
from core.views import (
|
||||
CacheOperatorView,
|
||||
ContactUsView,
|
||||
DownloadDigitalAssetView,
|
||||
GlobalSearchView,
|
||||
RequestCursedURLView,
|
||||
SupportedLanguagesView,
|
||||
WebsiteParametersView,
|
||||
download_digital_asset_view,
|
||||
sitemap_detail,
|
||||
sitemap_index,
|
||||
)
|
||||
|
|
@ -78,7 +78,7 @@ urlpatterns = [
|
|||
{"sitemaps": sitemaps},
|
||||
name="sitemap-detail",
|
||||
),
|
||||
path("download/<str:order_product_uuid>/", download_digital_asset_view, name="download_digital_asset"),
|
||||
path("download/<str:order_product_uuid>/", DownloadDigitalAssetView.as_view(), name="download_digital_asset"),
|
||||
path("search/", GlobalSearchView.as_view(), name="global_search"),
|
||||
path("app/cache/", CacheOperatorView.as_view(), name="cache_operator"),
|
||||
path("app/languages/", SupportedLanguagesView.as_view(), name="supported_languages"),
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@ from core.serializers import (
|
|||
AttributeSimpleSerializer,
|
||||
AttributeValueDetailSerializer,
|
||||
AttributeValueSimpleSerializer,
|
||||
BrandDetailSerializer,
|
||||
BrandSimpleSerializer,
|
||||
BulkAddOrderProductsSerializer,
|
||||
BulkAddWishlistProductSerializer,
|
||||
BulkRemoveOrderProductsSerializer,
|
||||
|
|
@ -29,9 +31,21 @@ from core.serializers import (
|
|||
OrderProductSimpleSerializer,
|
||||
OrderSimpleSerializer,
|
||||
ProductDetailSerializer,
|
||||
ProductImageDetailSerializer,
|
||||
ProductImageSimpleSerializer,
|
||||
ProductSimpleSerializer,
|
||||
ProductTagDetailSerializer,
|
||||
ProductTagSimpleSerializer,
|
||||
PromoCodeDetailSerializer,
|
||||
PromoCodeSimpleSerializer,
|
||||
PromotionDetailSerializer,
|
||||
PromotionSimpleSerializer,
|
||||
RemoveOrderProductSerializer,
|
||||
RemoveWishlistProductSerializer,
|
||||
StockDetailSerializer,
|
||||
StockSimpleSerializer,
|
||||
VendorDetailSerializer,
|
||||
VendorSimpleSerializer,
|
||||
WishlistDetailSerializer,
|
||||
WishlistSimpleSerializer,
|
||||
)
|
||||
|
|
@ -652,3 +666,196 @@ ORDER_PRODUCT_SCHEMA = {
|
|||
},
|
||||
),
|
||||
}
|
||||
|
||||
BRAND_SCHEMA = {
|
||||
"list": extend_schema(
|
||||
summary=_("list all brands (simple view)"),
|
||||
responses={status.HTTP_200_OK: BrandSimpleSerializer(many=True), **BASE_ERRORS},
|
||||
),
|
||||
"retrieve": extend_schema(
|
||||
summary=_("retrieve a single brand (detailed view)"),
|
||||
responses={status.HTTP_200_OK: BrandDetailSerializer(), **BASE_ERRORS},
|
||||
),
|
||||
"create": extend_schema(
|
||||
summary=_("create a brand"),
|
||||
responses={status.HTTP_201_CREATED: BrandDetailSerializer(), **BASE_ERRORS},
|
||||
),
|
||||
"destroy": extend_schema(
|
||||
summary=_("delete a brand"),
|
||||
responses={status.HTTP_204_NO_CONTENT: {}, **BASE_ERRORS},
|
||||
),
|
||||
"update": extend_schema(
|
||||
summary=_("rewrite an existing brand saving non-editables"),
|
||||
responses={status.HTTP_200_OK: BrandDetailSerializer(), **BASE_ERRORS},
|
||||
),
|
||||
"partial_update": extend_schema(
|
||||
summary=_("rewrite some fields of an existing brand saving non-editables"),
|
||||
responses={status.HTTP_200_OK: BrandDetailSerializer(), **BASE_ERRORS},
|
||||
),
|
||||
"seo_meta": extend_schema(
|
||||
summary=_("SEO Meta snapshot for brand"),
|
||||
responses={status.HTTP_200_OK: SeoSnapshotSerializer(), **BASE_ERRORS},
|
||||
),
|
||||
}
|
||||
|
||||
VENDOR_SCHEMA = {
|
||||
"list": extend_schema(
|
||||
summary=_("list all vendors (simple view)"),
|
||||
responses={status.HTTP_200_OK: VendorSimpleSerializer(many=True), **BASE_ERRORS},
|
||||
),
|
||||
"retrieve": extend_schema(
|
||||
summary=_("retrieve a single vendor (detailed view)"),
|
||||
responses={status.HTTP_200_OK: VendorDetailSerializer(), **BASE_ERRORS},
|
||||
),
|
||||
"create": extend_schema(
|
||||
summary=_("create a vendor"),
|
||||
responses={status.HTTP_201_CREATED: VendorDetailSerializer(), **BASE_ERRORS},
|
||||
),
|
||||
"destroy": extend_schema(
|
||||
summary=_("delete a vendor"),
|
||||
responses={status.HTTP_204_NO_CONTENT: {}, **BASE_ERRORS},
|
||||
),
|
||||
"update": extend_schema(
|
||||
summary=_("rewrite an existing vendor saving non-editables"),
|
||||
responses={status.HTTP_200_OK: VendorDetailSerializer(), **BASE_ERRORS},
|
||||
),
|
||||
"partial_update": extend_schema(
|
||||
summary=_("rewrite some fields of an existing vendor saving non-editables"),
|
||||
responses={status.HTTP_200_OK: VendorDetailSerializer(), **BASE_ERRORS},
|
||||
),
|
||||
}
|
||||
|
||||
PRODUCT_IMAGE_SCHEMA = {
|
||||
"list": extend_schema(
|
||||
summary=_("list all product images (simple view)"),
|
||||
responses={status.HTTP_200_OK: ProductImageSimpleSerializer(many=True), **BASE_ERRORS},
|
||||
),
|
||||
"retrieve": extend_schema(
|
||||
summary=_("retrieve a single product image (detailed view)"),
|
||||
responses={status.HTTP_200_OK: ProductImageDetailSerializer(), **BASE_ERRORS},
|
||||
),
|
||||
"create": extend_schema(
|
||||
summary=_("create a product image"),
|
||||
responses={status.HTTP_201_CREATED: ProductImageDetailSerializer(), **BASE_ERRORS},
|
||||
),
|
||||
"destroy": extend_schema(
|
||||
summary=_("delete a product image"),
|
||||
responses={status.HTTP_204_NO_CONTENT: {}, **BASE_ERRORS},
|
||||
),
|
||||
"update": extend_schema(
|
||||
summary=_("rewrite an existing product image saving non-editables"),
|
||||
responses={status.HTTP_200_OK: ProductImageDetailSerializer(), **BASE_ERRORS},
|
||||
),
|
||||
"partial_update": extend_schema(
|
||||
summary=_("rewrite some fields of an existing product image saving non-editables"),
|
||||
responses={status.HTTP_200_OK: ProductImageDetailSerializer(), **BASE_ERRORS},
|
||||
),
|
||||
}
|
||||
|
||||
PROMOCODE_SCHEMA = {
|
||||
"list": extend_schema(
|
||||
summary=_("list all promo codes (simple view)"),
|
||||
responses={status.HTTP_200_OK: PromoCodeSimpleSerializer(many=True), **BASE_ERRORS},
|
||||
),
|
||||
"retrieve": extend_schema(
|
||||
summary=_("retrieve a single promo code (detailed view)"),
|
||||
responses={status.HTTP_200_OK: PromoCodeDetailSerializer(), **BASE_ERRORS},
|
||||
),
|
||||
"create": extend_schema(
|
||||
summary=_("create a promo code"),
|
||||
responses={status.HTTP_201_CREATED: PromoCodeDetailSerializer(), **BASE_ERRORS},
|
||||
),
|
||||
"destroy": extend_schema(
|
||||
summary=_("delete a promo code"),
|
||||
responses={status.HTTP_204_NO_CONTENT: {}, **BASE_ERRORS},
|
||||
),
|
||||
"update": extend_schema(
|
||||
summary=_("rewrite an existing promo code saving non-editables"),
|
||||
responses={status.HTTP_200_OK: PromoCodeDetailSerializer(), **BASE_ERRORS},
|
||||
),
|
||||
"partial_update": extend_schema(
|
||||
summary=_("rewrite some fields of an existing promo code saving non-editables"),
|
||||
responses={status.HTTP_200_OK: PromoCodeDetailSerializer(), **BASE_ERRORS},
|
||||
),
|
||||
}
|
||||
|
||||
PROMOTION_SCHEMA = {
|
||||
"list": extend_schema(
|
||||
summary=_("list all promotions (simple view)"),
|
||||
responses={status.HTTP_200_OK: PromotionSimpleSerializer(many=True), **BASE_ERRORS},
|
||||
),
|
||||
"retrieve": extend_schema(
|
||||
summary=_("retrieve a single promotion (detailed view)"),
|
||||
responses={status.HTTP_200_OK: PromotionDetailSerializer(), **BASE_ERRORS},
|
||||
),
|
||||
"create": extend_schema(
|
||||
summary=_("create a promotion"),
|
||||
responses={status.HTTP_201_CREATED: PromotionDetailSerializer(), **BASE_ERRORS},
|
||||
),
|
||||
"destroy": extend_schema(
|
||||
summary=_("delete a promotion"),
|
||||
responses={status.HTTP_204_NO_CONTENT: {}, **BASE_ERRORS},
|
||||
),
|
||||
"update": extend_schema(
|
||||
summary=_("rewrite an existing promotion saving non-editables"),
|
||||
responses={status.HTTP_200_OK: PromotionDetailSerializer(), **BASE_ERRORS},
|
||||
),
|
||||
"partial_update": extend_schema(
|
||||
summary=_("rewrite some fields of an existing promotion saving non-editables"),
|
||||
responses={status.HTTP_200_OK: PromotionDetailSerializer(), **BASE_ERRORS},
|
||||
),
|
||||
}
|
||||
|
||||
STOCK_SCHEMA = {
|
||||
"list": extend_schema(
|
||||
summary=_("list all stocks (simple view)"),
|
||||
responses={status.HTTP_200_OK: StockSimpleSerializer(many=True), **BASE_ERRORS},
|
||||
),
|
||||
"retrieve": extend_schema(
|
||||
summary=_("retrieve a single stock (detailed view)"),
|
||||
responses={status.HTTP_200_OK: StockDetailSerializer(), **BASE_ERRORS},
|
||||
),
|
||||
"create": extend_schema(
|
||||
summary=_("create a stock record"),
|
||||
responses={status.HTTP_201_CREATED: StockDetailSerializer(), **BASE_ERRORS},
|
||||
),
|
||||
"destroy": extend_schema(
|
||||
summary=_("delete a stock record"),
|
||||
responses={status.HTTP_204_NO_CONTENT: {}, **BASE_ERRORS},
|
||||
),
|
||||
"update": extend_schema(
|
||||
summary=_("rewrite an existing stock record saving non-editables"),
|
||||
responses={status.HTTP_200_OK: StockDetailSerializer(), **BASE_ERRORS},
|
||||
),
|
||||
"partial_update": extend_schema(
|
||||
summary=_("rewrite some fields of an existing stock record saving non-editables"),
|
||||
responses={status.HTTP_200_OK: StockDetailSerializer(), **BASE_ERRORS},
|
||||
),
|
||||
}
|
||||
|
||||
PRODUCT_TAG_SCHEMA = {
|
||||
"list": extend_schema(
|
||||
summary=_("list all product tags (simple view)"),
|
||||
responses={status.HTTP_200_OK: ProductTagSimpleSerializer(many=True), **BASE_ERRORS},
|
||||
),
|
||||
"retrieve": extend_schema(
|
||||
summary=_("retrieve a single product tag (detailed view)"),
|
||||
responses={status.HTTP_200_OK: ProductTagDetailSerializer(), **BASE_ERRORS},
|
||||
),
|
||||
"create": extend_schema(
|
||||
summary=_("create a product tag"),
|
||||
responses={status.HTTP_201_CREATED: ProductTagDetailSerializer(), **BASE_ERRORS},
|
||||
),
|
||||
"destroy": extend_schema(
|
||||
summary=_("delete a product tag"),
|
||||
responses={status.HTTP_204_NO_CONTENT: {}, **BASE_ERRORS},
|
||||
),
|
||||
"update": extend_schema(
|
||||
summary=_("rewrite an existing product tag saving non-editables"),
|
||||
responses={status.HTTP_200_OK: ProductTagDetailSerializer(), **BASE_ERRORS},
|
||||
),
|
||||
"partial_update": extend_schema(
|
||||
summary=_("rewrite some fields of an existing product tag saving non-editables"),
|
||||
responses={status.HTTP_200_OK: ProductTagDetailSerializer(), **BASE_ERRORS},
|
||||
),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -301,9 +301,16 @@ class BuyAsBusinessView(APIView):
|
|||
)
|
||||
|
||||
|
||||
def download_digital_asset_view(request: HttpRequest, *args, **kwargs) -> FileResponse | JsonResponse:
|
||||
class DownloadDigitalAssetView(APIView):
|
||||
__doc__ = _( # type: ignore [assignment]
|
||||
"Handles the downloading of a digital asset associated with an order.\n"
|
||||
"This function attempts to serve the digital asset file located in the "
|
||||
"storage directory of the project. If the file is not found, an HTTP 404 "
|
||||
"error is raised to indicate the resource is unavailable."
|
||||
)
|
||||
|
||||
def get(self, request: HttpRequest, *args, **kwargs) -> HttpResponse | FileResponse:
|
||||
try:
|
||||
logger.debug(f"download_digital_asset_view: {kwargs}")
|
||||
op_uuid = str(kwargs.get("order_product_uuid"))
|
||||
if not op_uuid:
|
||||
raise BadRequest(_("order_product_uuid is required"))
|
||||
|
|
@ -335,31 +342,22 @@ def download_digital_asset_view(request: HttpRequest, *args, **kwargs) -> FileRe
|
|||
return response
|
||||
|
||||
except BadRequest as e:
|
||||
return JsonResponse(camelize({"error": str(e)}), status=400)
|
||||
return Response(data=camelize({"error": str(e)}), status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
except DigitalAssetDownload.DoesNotExist:
|
||||
return JsonResponse(camelize({"error": "Digital asset not found"}), status=404)
|
||||
return Response(data=camelize({"error": "Digital asset not found"}), status=status.HTTP_404_NOT_FOUND)
|
||||
|
||||
except Exception as e:
|
||||
capture_exception(e)
|
||||
return JsonResponse(
|
||||
camelize(
|
||||
return Response(
|
||||
data=camelize(
|
||||
{
|
||||
"error": "An error occurred while trying to download the digital asset",
|
||||
"traceback": traceback.format_exc() if settings.DEBUG else None,
|
||||
"received": {"order_product_uuid": kwargs.get("order_product_uuid", "")},
|
||||
}
|
||||
),
|
||||
status=500,
|
||||
)
|
||||
|
||||
|
||||
# noinspection PyTypeChecker
|
||||
download_digital_asset_view.__doc__ = _( # type: ignore [assignment]
|
||||
"Handles the downloading of a digital asset associated with an order.\n"
|
||||
"This function attempts to serve the digital asset file located in the "
|
||||
"storage directory of the project. If the file is not found, an HTTP 404 "
|
||||
"error is raised to indicate the resource is unavailable."
|
||||
status=status.HTTP_503_SERVICE_UNAVAILABLE,
|
||||
)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -31,11 +31,18 @@ from core.docs.drf.viewsets import (
|
|||
ATTRIBUTE_GROUP_SCHEMA,
|
||||
ATTRIBUTE_SCHEMA,
|
||||
ATTRIBUTE_VALUE_SCHEMA,
|
||||
BRAND_SCHEMA,
|
||||
CATEGORY_SCHEMA,
|
||||
FEEDBACK_SCHEMA,
|
||||
ORDER_PRODUCT_SCHEMA,
|
||||
ORDER_SCHEMA,
|
||||
PRODUCT_IMAGE_SCHEMA,
|
||||
PRODUCT_SCHEMA,
|
||||
PRODUCT_TAG_SCHEMA,
|
||||
PROMOCODE_SCHEMA,
|
||||
PROMOTION_SCHEMA,
|
||||
STOCK_SCHEMA,
|
||||
VENDOR_SCHEMA,
|
||||
WISHLIST_SCHEMA,
|
||||
)
|
||||
from core.filters import AddressFilter, BrandFilter, CategoryFilter, FeedbackFilter, OrderFilter, ProductFilter
|
||||
|
|
@ -313,6 +320,7 @@ class CategoryViewSet(EvibesViewSet):
|
|||
return Response(SeoSnapshotSerializer(payload).data)
|
||||
|
||||
|
||||
@extend_schema_view(**BRAND_SCHEMA)
|
||||
class BrandViewSet(EvibesViewSet):
|
||||
__doc__ = _(
|
||||
"Represents a viewset for managing Brand instances. "
|
||||
|
|
@ -554,6 +562,7 @@ class ProductViewSet(EvibesViewSet):
|
|||
return Response(SeoSnapshotSerializer(payload).data)
|
||||
|
||||
|
||||
@extend_schema_view(**VENDOR_SCHEMA)
|
||||
class VendorViewSet(EvibesViewSet):
|
||||
__doc__ = _(
|
||||
"Represents a viewset for managing Vendor objects. "
|
||||
|
|
@ -853,6 +862,7 @@ class OrderProductViewSet(EvibesViewSet):
|
|||
return Response(status=status.HTTP_404_NOT_FOUND)
|
||||
|
||||
|
||||
@extend_schema_view(**PRODUCT_IMAGE_SCHEMA)
|
||||
class ProductImageViewSet(EvibesViewSet):
|
||||
__doc__ = _("Manages operations related to Product images in the application. ")
|
||||
|
||||
|
|
@ -865,6 +875,7 @@ class ProductImageViewSet(EvibesViewSet):
|
|||
}
|
||||
|
||||
|
||||
@extend_schema_view(**PROMOCODE_SCHEMA)
|
||||
class PromoCodeViewSet(EvibesViewSet):
|
||||
__doc__ = _("Manages the retrieval and handling of PromoCode instances through various API actions.")
|
||||
|
||||
|
|
@ -886,6 +897,7 @@ class PromoCodeViewSet(EvibesViewSet):
|
|||
return qs.filter(user=user)
|
||||
|
||||
|
||||
@extend_schema_view(**PROMOTION_SCHEMA)
|
||||
class PromotionViewSet(EvibesViewSet):
|
||||
__doc__ = _("Represents a view set for managing promotions. ")
|
||||
|
||||
|
|
@ -898,6 +910,7 @@ class PromotionViewSet(EvibesViewSet):
|
|||
}
|
||||
|
||||
|
||||
@extend_schema_view(**STOCK_SCHEMA)
|
||||
class StockViewSet(EvibesViewSet):
|
||||
__doc__ = _("Handles operations related to Stock data in the system.")
|
||||
|
||||
|
|
@ -1100,6 +1113,7 @@ class AddressViewSet(EvibesViewSet):
|
|||
)
|
||||
|
||||
|
||||
@extend_schema_view(**PRODUCT_TAG_SCHEMA)
|
||||
class ProductTagViewSet(EvibesViewSet):
|
||||
__doc__ = _(
|
||||
"Handles operations related to Product Tags within the application. "
|
||||
|
|
|
|||
17
payments/docs/drf/viewsets.py
Normal file
17
payments/docs/drf/viewsets.py
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
from django.utils.translation import gettext_lazy as _
|
||||
from drf_spectacular.utils import extend_schema
|
||||
from rest_framework import status
|
||||
|
||||
from core.docs.drf import BASE_ERRORS
|
||||
from payments.serializers import TransactionSerializer
|
||||
|
||||
TRANSACTION_SCHEMA = {
|
||||
"list": extend_schema(
|
||||
summary=_("list all transactions (read-only)"),
|
||||
responses={status.HTTP_200_OK: TransactionSerializer(many=True), **BASE_ERRORS},
|
||||
),
|
||||
"retrieve": extend_schema(
|
||||
summary=_("retrieve a single transaction (read-only)"),
|
||||
responses={status.HTTP_200_OK: TransactionSerializer(), **BASE_ERRORS},
|
||||
),
|
||||
}
|
||||
|
|
@ -1,10 +1,13 @@
|
|||
from django.utils.translation import gettext_lazy as _
|
||||
from drf_spectacular.utils import extend_schema_view
|
||||
from rest_framework.viewsets import ReadOnlyModelViewSet
|
||||
|
||||
from core.permissions import EvibesPermission, IsOwner
|
||||
from payments.serializers import TransactionSerializer
|
||||
from payments.docs.drf.viewsets import TRANSACTION_SCHEMA
|
||||
|
||||
|
||||
@extend_schema_view(**TRANSACTION_SCHEMA)
|
||||
class TransactionViewSet(ReadOnlyModelViewSet): # type: ignore
|
||||
__doc__ = _( # type: ignore [assignment]
|
||||
"ViewSet for handling read-only operations on the Transaction model. "
|
||||
|
|
|
|||
Loading…
Reference in a new issue