Coverage for src/wishlists/views.py: 40%
50 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
1from django.contrib.contenttypes.models import ContentType
3from rest_framework import viewsets, status
4from rest_framework.decorators import action
5from rest_framework.response import Response
6from rest_framework.exceptions import ValidationError
8from src.wishlists.models import Wishlist
9from src.wishlists.serializers import WishlistSerializer
10from src.wishlists.services import WishlistService
11from src.wishlists.constants import WishlistErrorMessages
14class WishlistViewSet(viewsets.ModelViewSet):
16 # Use WishlistSerializer for data serialization
17 serializer_class = WishlistSerializer
19 def get_queryset(self):
20 try:
21 # Get user identification filters
22 user_filters = WishlistService.get_user_identifier(self.request)
24 # Filter wishlist items by user and optimize with select_related
25 return Wishlist.objects.filter(**user_filters).select_related(
26 'content_type',
27 'user',
28 )
29 except ValidationError:
30 # Return empty queryset if user identification fails
31 return Wishlist.objects.none()
33 def create(self, request, *args, **kwargs):
34 """
35 This method adds a new item to the user's wishlist after validating
36 the request data and ensuring the item doesn't already exist.
37 """
38 try:
39 # Get user identification filters
40 user_filters = WishlistService.get_user_identifier(request)
42 # Validate request data
43 serializer = self.get_serializer(data=request.data)
44 serializer.is_valid(raise_exception=True)
46 # Extract validated data
47 content_type = serializer.validated_data['content_type']
48 object_id = serializer.validated_data['object_id']
50 # Create wishlist item using service
51 wishlist_item = WishlistService.create_wishlist_item(
52 user_filters, content_type, object_id
53 )
55 # Serialize and return response
56 response_serializer = self.get_serializer(wishlist_item)
57 return Response(
58 response_serializer.data,
59 status=status.HTTP_201_CREATED,
60 )
61 except ValidationError as e:
62 # Return validation error details
63 return Response(
64 e.detail,
65 status=status.HTTP_400_BAD_REQUEST,
66 )
68 @action(
69 detail=False,
70 methods=['delete'],
71 url_path='remove/(?P<content_type_name>[^/.]+)/(?P<object_id>[^/.]+)',
72 )
73 def remove_item(self, request, content_type_name=None, object_id=None):
74 """
75 This custom action removes a specific wishlist item based on
76 content type name and object ID. It validates the parameters
77 and handles various error cases.
78 """
79 try:
80 # Get user identification filters
81 user_filters = WishlistService.get_user_identifier(request)
83 try:
84 # Convert content_type_name to ContentType object
85 content_type = ContentType.objects.get(model=content_type_name)
87 # Convert object_id string to integer
88 object_id_int = int(object_id) if object_id is not None else 0
89 except (ContentType.DoesNotExist, ValueError):
90 # Handle invalid content type or object ID
91 return Response(
92 {
93 'detail': WishlistErrorMessages.ERROR_INVALID_CONTENT_TYPE_OR_ID
94 },
95 status=status.HTTP_400_BAD_REQUEST,
96 )
98 # Delete the wishlist item using service
99 WishlistService.delete_wishlist_item(
100 user_filters, content_type, object_id_int
101 )
103 # Return success response with no content
104 return Response(status=status.HTTP_204_NO_CONTENT)
106 except ValidationError as e:
107 # Return validation error details
108 return Response(
109 e.detail,
110 status=status.HTTP_400_BAD_REQUEST,
111 )
113 @action(detail=False, methods=['get'], url_path='count')
114 def get_wishlist_count(self, request):
115 """
116 This custom action returns the number of items in the user's
117 wishlist, useful for displaying wishlist count in the UI.
118 """
119 try:
120 # Get user identification filters
121 user_filters = WishlistService.get_user_identifier(request)
123 # Count wishlist items for the user
124 count = Wishlist.objects.filter(**user_filters).count()
126 # Return count in response
127 return Response(
128 {'count': count},
129 status=status.HTTP_200_OK,
130 )
132 except ValidationError as e:
133 # Return validation error details
134 return Response(
135 e.detail,
136 status=status.HTTP_400_BAD_REQUEST,
137 )