diff --git a/nxtbn/product/api/storefront/serializers.py b/nxtbn/product/api/storefront/serializers.py index 3d32aaa..2190c9a 100644 --- a/nxtbn/product/api/storefront/serializers.py +++ b/nxtbn/product/api/storefront/serializers.py @@ -20,7 +20,7 @@ class Meta: class ProductVariantSerializer(serializers.ModelSerializer): - variant_image = ImageSerializer(many=True, read_only=True) + variant_image = ImageSerializer(read_only=True) price_in_target_currency = serializers.SerializerMethodField() class Meta: model = ProductVariant @@ -34,8 +34,29 @@ def get_price_in_target_currency(self, obj): price = currency_Backend().to_target_currency(currency_code, obj.price) return price -class ProductSerializer(serializers.ModelSerializer): - default_variant = ProductVariantSerializer() +class ProductWithVariantSerializer(serializers.ModelSerializer): + variants = ProductVariantSerializer(many=True) + product_thumbnail = serializers.SerializerMethodField() + + class Meta: + model = Product + fields = ( + 'id', + 'name', + 'summary', + 'description', + 'category', + 'brand', + 'slug', + 'variants', + 'product_thumbnail' + ) + + def get_product_thumbnail(self, obj): + return obj.product_thumbnail(self.context['request']) + + +class ProductWithDefaultVariantSerializer(serializers.ModelSerializer): product_thumbnail = serializers.SerializerMethodField() class Meta: diff --git a/nxtbn/product/api/storefront/urls.py b/nxtbn/product/api/storefront/urls.py index 3c10f37..fc4082f 100644 --- a/nxtbn/product/api/storefront/urls.py +++ b/nxtbn/product/api/storefront/urls.py @@ -1,8 +1,14 @@ from django.urls import path +from rest_framework.routers import DefaultRouter + from nxtbn.product.api.storefront import views as product_views +from django.urls import include + +router = DefaultRouter() +router.register(r'products', product_views.ProductViewSet, basename='product') urlpatterns = [ - path('products/', product_views.ProductListView.as_view(), name='product-list'), + path('', include(router.urls)), path('products//', product_views.ProductDetailView.as_view(), name='product-detail'), path('collections/', product_views.CollectionListView.as_view(), name='collection-list'), path('recursive-categories/', product_views.CategoryListView.as_view(), name='category-list'), diff --git a/nxtbn/product/api/storefront/views.py b/nxtbn/product/api/storefront/views.py index 4f8efc6..8fe980f 100644 --- a/nxtbn/product/api/storefront/views.py +++ b/nxtbn/product/api/storefront/views.py @@ -1,3 +1,5 @@ +from rest_framework import viewsets +from rest_framework.decorators import action from rest_framework import generics, status from rest_framework.response import Response from django.utils.translation import gettext_lazy as _ @@ -10,7 +12,7 @@ from nxtbn.core.paginator import NxtbnPagination -from nxtbn.product.api.storefront.serializers import CategorySerializer, CollectionSerializer, ProductDetailSerializer, ProductSerializer +from nxtbn.product.api.storefront.serializers import CategorySerializer, CollectionSerializer, ProductDetailSerializer, ProductWithDefaultVariantSerializer, ProductWithVariantSerializer from nxtbn.product.models import Category, Collection, Product from nxtbn.product.models import Supplier @@ -31,23 +33,45 @@ class Meta: fields = ('name', 'summary', 'description', 'category', 'supplier', 'brand', 'type', 'related_to', 'collection') - - - -class ProductListView(generics.ListAPIView): +class ProductViewSet(viewsets.ReadOnlyModelViewSet): pagination_class = NxtbnPagination permission_classes = (AllowAny,) queryset = Product.objects.all() - serializer_class = ProductSerializer filter_backends = [ django_filters.rest_framework.DjangoFilterBackend, drf_filters.SearchFilter, - drf_filters.OrderingFilter + drf_filters.OrderingFilter, ] filterset_class = ProductFilter - search_fields = ['name', 'summary', 'description', 'category__name', 'type'] ordering_fields = ['name', 'created_at'] + def paginate_and_serialize(self, queryset): # Custom + # Helper function to handle pagination and serialization + page = self.paginate_queryset(queryset) + if page is not None: + serializer = self.get_serializer(page, many=True) + return self.get_paginated_response(serializer.data) + serializer = self.get_serializer(queryset, many=True) + return Response(serializer.data) + + def get_serializer_class(self): + # Select the serializer dynamically based on the action + if self.action == 'default': + return ProductWithDefaultVariantSerializer + return ProductWithVariantSerializer + + @action(detail=False, methods=['get'], url_path='default') + def list_products(self, request): + queryset = self.filter_queryset(self.queryset) + return self.paginate_and_serialize(queryset) + + + @action(detail=False, methods=['get'], url_path='withvariant') + def list_products_with_variant(self, request): + queryset = self.filter_queryset(self.queryset) + return self.paginate_and_serialize(queryset) + + class CollectionListView(generics.ListAPIView): permission_classes = (AllowAny,) pagination_class = None