Coverage for src/products/views/product.py: 80%
64 statements
« prev ^ index » next coverage.py v7.9.2, created at 2025-08-04 12:59 +0300
« prev ^ index » next coverage.py v7.9.2, created at 2025-08-04 12:59 +0300
1"""
2This module contains views for product listing, detail, attribute retrieval, and review management.
4It provides:
5- List and detail views for each product type (Earwear, Neckwear, Wristwear, Fingerwear)
6- Attribute views for product properties like color, metal, stone, and collection
7- Both synchronous and asynchronous endpoints for attribute retrieval
8- Custom permission for reviewer access to all product reviews
9- Review management endpoints for products
10"""
12from src.common.permissions import IsOrderManager
13from src.products.models.product import Color, Metal, Stone, Collection
15from src.products.serializers.product import (
16 CollectionSerializer,
17 ColorSerializer,
18 EarwearItemSerializer,
19 FingerwearItemSerializer,
20 MetalSerializer,
21 NeckwearItemSerializer,
22 NeckwearListSerializer,
23 EarwearListSerializer,
24 StoneSerializer,
25 WristwearItemSerializer,
26 WristwearListSerializer,
27 FingerwearListSerializer,
28)
30from src.products.models import Earwear, Neckwear, Wristwear, Fingerwear
32from src.products.views.base import (
33 BaseAttributeView,
34 BaseProductItemView,
35 BaseProductListView,
36)
38from rest_framework.views import APIView
39from rest_framework.permissions import IsAuthenticated
40from rest_framework.response import Response
41from src.products.models.review import Review
42from src.products.serializers.review import ReviewSerializer
43from django.contrib.contenttypes.models import ContentType
44from rest_framework import status
47class EarwearListView(BaseProductListView):
48 model = Earwear
49 serializer_class = EarwearListSerializer
52class NeckwearListView(BaseProductListView):
53 model = Neckwear
54 serializer_class = NeckwearListSerializer
57class WristwearListView(BaseProductListView):
58 model = Wristwear
59 serializer_class = WristwearListSerializer
62class FingerwearListView(BaseProductListView):
63 model = Fingerwear
64 serializer_class = FingerwearListSerializer
67class EarwearItemView(BaseProductItemView):
68 model = Earwear
69 serializer_class = EarwearItemSerializer
72class NeckwearItemView(BaseProductItemView):
73 model = Neckwear
74 serializer_class = NeckwearItemSerializer
77class WristwearItemView(BaseProductItemView):
78 model = Wristwear
79 serializer_class = WristwearItemSerializer
82class FingerwearItemView(BaseProductItemView):
83 model = Fingerwear
84 serializer_class = FingerwearItemSerializer
87class CollectionRetrieveView(BaseAttributeView):
88 model = Collection
89 serializer_class = CollectionSerializer
92class ColorRetrieveView(BaseAttributeView):
93 model = Color
94 serializer_class = ColorSerializer
97class MetalRetrieveView(BaseAttributeView):
98 model = Metal
99 serializer_class = MetalSerializer
102class StoneRetrieveView(BaseAttributeView):
103 model = Stone
104 serializer_class = StoneSerializer
107class ProductAllReviewsView(APIView):
108 permission_classes = [IsAuthenticated, IsOrderManager]
110 def get(self, request, category, pk):
111 # Map category to model
112 from src.products.models.product import (
113 Earwear,
114 Neckwear,
115 Fingerwear,
116 Wristwear,
117 )
119 model_map = {
120 'earwear': Earwear,
121 'neckwear': Neckwear,
122 'fingerwear': Fingerwear,
123 'wristwear': Wristwear,
124 }
125 model = model_map.get(category.lower())
126 if not model:
127 return Response(
128 {'detail': 'Invalid category.'},
129 status=status.HTTP_400_BAD_REQUEST,
130 )
131 try:
132 product = model.objects.get(pk=pk)
133 except model.DoesNotExist:
134 return Response(
135 {'detail': 'Product not found.'},
136 status=status.HTTP_404_NOT_FOUND,
137 )
138 # Get all reviews for this product
139 content_type = ContentType.objects.get_for_model(model)
140 reviews = Review.objects.filter(
141 content_type=content_type, object_id=product.id
142 ).order_by('-created_at')
143 serializer = ReviewSerializer(reviews, many=True)
145 return Response({'reviews': serializer.data})