# coding=utf-8 import json from django.db import transaction from django.db.models import F from django.conf import settings from django.utils import timezone from rest_framework import generics, mixins from rest_framework.viewsets import GenericViewSet from rest_framework.views import APIView from rest_framework.decorators import action from rest_framework.exceptions import NotFound from utils import response_ok from utils.permission import IsCustomer from utils.exceptions import CustomError from apps.commodity.models import Commodity from apps.commodity.filters import CommodityFilter from apps.log.models import BizLog from apps.customer.models import Customer from apps.collection.models import Collection from apps.option.filters import OptionFilter from apps.option.models import Option from .serializers import CommodityCategorySerializer, CommoditySerializer, CommodityDetailSerializer, HomeOptionSerializer class CollectionViewSet(GenericViewSet, mixins.ListModelMixin, mixins.RetrieveModelMixin): permission_classes = [IsCustomer, ] queryset = Commodity.objects.filter(status=settings.ONLINE, delete=False) serializer_class = CommoditySerializer @action(methods=['get'], detail=True) def collection(self, request, pk): instance = self.get_object() if instance.delete: raise CustomError(u'该商品已被删除!') if instance.status != settings.ONLINE: raise CustomError(u'该商品已下架!') customer = request.customer if Collection.is_collection(customer, instance): raise CustomError(u'该商品已收藏!') with transaction.atomic(): Collection.addnew(customer, instance) return response_ok() @action(methods=['post'], detail=False) def batch_collection(self, request): ids = json.loads(request.data.get('ids')) commoditys = self.queryset.filter(id__in=ids) with transaction.atomic(): for item in commoditys: ct = Collection.objects.filter(customer=request.customer, commodity=item).first() if not ct: Collection.objects.create(customer=request.customer, commodity=item, create_time=timezone.now()) if ct and ct.delete: ct.delete = False ct.create_time = timezone.now() ct.save() return response_ok() @action(methods=['get'], detail=True) def uncollection(self, request, pk): instance = self.get_object() customer = request.customer collection = Collection.objects.filter(customer=customer, commodity=instance).first() if not collection or collection.delete: raise CustomError(u'该商品尚未收藏!') with transaction.atomic(): Collection.objects.filter(customer=customer, commodity=instance).update(delete=True) return response_ok() class CommodityCategoryListView(generics.ListAPIView): queryset = Option.objects.filter(enable=True, delete=False, type=Option.COMMODITY_CATEGORY).order_by('sort') serializer_class = CommodityCategorySerializer def filter_queryset(self, queryset): queryset = queryset.filter() f = OptionFilter(self.request.GET, queryset=queryset) return f.qs def list(self, request, *args, **kwargs): try: data = super(CommodityCategoryListView, self).list(request) except NotFound: return response_ok([]) return data class CommodityListView(generics.ListAPIView): queryset = Commodity.objects.filter(status=settings.ONLINE, delete=False) serializer_class = CommoditySerializer def filter_queryset(self, queryset): queryset = queryset.filter().order_by('type', 'sort', '-id') f = CommodityFilter(self.request.GET, queryset=queryset) return f.qs def list(self, request, *args, **kwargs): try: data = super(CommodityListView, self).list(request) except NotFound: return response_ok([]) return data class CommodityDetailView(generics.RetrieveAPIView): queryset = Commodity.objects.filter(status=settings.ONLINE, delete=False) serializer_class = CommodityDetailSerializer def retrieve(self, request, *args, **kwargs): instance = self.get_object() if not instance: raise CustomError(u'未找到相应的商品!') serializer = self.get_serializer(instance) return response_ok(serializer.data) class HomeCommodityListView(generics.ListAPIView): queryset = Option.objects.filter(type=Option.COMMODITY_CATEGORY, delete=False, enable=True) serializer_class = HomeOptionSerializer def filter_queryset(self, queryset): queryset = queryset.filter() f = OptionFilter(self.request.GET, queryset=queryset) return f.qs def list(self, request, *args, **kwargs): ''' 首页商品列表 不分页 每类商品加载6条商品 :param request: :param args: :param kwargs: :return: ''' queryset = self.filter_queryset(self.get_queryset()) serializer = self.get_serializer(queryset, many=True) return response_ok(serializer.data)