"""Product app views.""" from rest_framework import generics, permissions from django.shortcuts import get_object_or_404 from product.models import Product from comment.models import Comment from product import filters, serializers from comment.serializers import CommentRUDSerializer from utils.views import FavoritesCreateDestroyMixinView from utils.pagination import PortionPagination from django.conf import settings class ProductBaseView(generics.GenericAPIView): """Product base view""" permission_classes = (permissions.AllowAny,) def get_queryset(self): """Override get_queryset method.""" return Product.objects.published() \ .with_base_related() \ .annotate_in_favorites(self.request.user) \ .order_by('-created') class ProductListView(ProductBaseView, generics.ListAPIView): """List view for model Product.""" serializer_class = serializers.ProductBaseSerializer filter_class = filters.ProductFilterSet def get_queryset(self): qs = super().get_queryset().with_extended_related() \ .by_country_code(self.request.country_code) return qs class ProductSimilarView(ProductListView): """Resource for getting a list of similar product.""" serializer_class = serializers.ProductBaseSerializer pagination_class = PortionPagination class ProductDetailView(ProductBaseView, generics.RetrieveAPIView): """Detail view fro model Product.""" lookup_field = 'slug' serializer_class = serializers.ProductDetailSerializer class CreateFavoriteProductView(FavoritesCreateDestroyMixinView): """View for create/destroy product in favorites.""" _model = Product serializer_class = serializers.ProductFavoritesCreateSerializer class ProductCommentCreateView(generics.CreateAPIView): """View for create new comment.""" lookup_field = 'slug' serializer_class = serializers.ProductCommentCreateSerializer queryset = Comment.objects.all() class ProductCommentListView(generics.ListAPIView): """View for return list of product comments.""" permission_classes = (permissions.AllowAny,) serializer_class = serializers.ProductCommentCreateSerializer def get_queryset(self): """Override get_queryset method""" product = get_object_or_404(Product, slug=self.kwargs['slug']) return product.comments.order_by('-created') class ProductCommentRUDView(generics.RetrieveUpdateDestroyAPIView): """View for retrieve/update/destroy product comment.""" serializer_class = CommentRUDSerializer queryset = Product.objects.all() def get_object(self): """Returns the object the view is displaying.""" queryset = self.filter_queryset(self.get_queryset()) product_obj = get_object_or_404(queryset, slug=self.kwargs['slug']) comment_obj = get_object_or_404(product_obj.comments.by_user(self.request.user), pk=self.kwargs['comment_id']) # May raise a permission denied self.check_object_permissions(self.request, comment_obj) return comment_obj class SimilarListView(ProductSimilarView): """Return similar products.""" def get_queryset(self): """Overridden get_queryset method.""" return super().get_queryset() \ .has_location() \ .similar(slug=self.kwargs.get('slug'))[:settings.QUERY_OUTPUT_OBJECTS]