【Vue+Django REST framework实战】第7章——商品详情页功能

viewsets实现商品详情页接口

#配置goods的url
router.register(r'goods', GoodsListViewSet, base_name="goods")

class GoodsListViewSet(CacheResponseMixin, mixins.ListModelMixin, mixins.RetrieveModelMixin, viewsets.GenericViewSet):
    """
    商品列表页, 分页, 搜索, 过滤, 排序
    """
    # throttle_classes = (UserRateThrottle, )
    queryset = Goods.objects.all()
    serializer_class = GoodsSerializer
    pagination_class = GoodsPagination
    # authentication_classes = (TokenAuthentication, )
    filter_backends = (DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter)
    filter_class = GoodsFilter
    search_fields = ('name', 'goods_brief', 'goods_desc')
    ordering_fields = ('sold_num', 'shop_price')

    def retrieve(self, request, *args, **kwargs):
        instance = self.get_object()
        instance.click_num += 1
        instance.save()
        serializer = self.get_serializer(instance)
        return Response(serializer.data)

vue前端

//商品详情
export const getGoodsDetail = goodId => { return axios.get(`${host}/goods/${goodId}`+'/') }

轮播图接口

#轮播图url
router.register(r'banners', BannerViewset, base_name="banners")
class BannerViewset(mixins.ListModelMixin, viewsets.GenericViewSet):
    """
    获取轮播图列表
    """
    queryset = Banner.objects.all().order_by("index")
    serializer_class = BannerSerializer

class BannerSerializer(serializers.ModelSerializer):
    class Meta:
        model = Banner
        fields = "__all__"

vue

//获取轮播图
export const bannerGoods = params => { return axios.get(`${host}/banners/`) }

热卖商品接口实现

vue:

 getDetails () { //  请求商品详情
          getGoodsDetail(this.productId)
            .then((response)=> {
                console.log(response.data);
                this.proDetail = response.data;
                this.curShow = this.proDetail.images[0];
            }).catch(function (error) {
                console.log(error);
            });
        },
//商品详情
export const getGoodsDetail = goodId => { return axios.get(`${host}/goods/${goodId}`+'/') }

AP接口:

同上,略……

用户收藏接口实现

#收藏
router.register(r'userfavs', UserFavViewset, base_name="userfavs")
class UserFavViewset(mixins.CreateModelMixin, mixins.ListModelMixin, mixins.RetrieveModelMixin,
                     mixins.DestroyModelMixin, viewsets.GenericViewSet):
    """
    list:
        获取用户收藏列表
    retrieve:
        判断某个商品是否已经收藏
    create:
        收藏商品
    """
    permission_classes = (IsAuthenticated, IsOwnerOrReadOnly)
    authentication_classes = (JSONWebTokenAuthentication, SessionAuthentication)
    lookup_field = "goods_id"	# url中的数字代表的就是该字段的值

    def get_queryset(self):
        return UserFav.objects.filter(user=self.request.user)

    # def perform_create(self, serializer):
    #     instance = serializer.save()
    #     goods = instance.goods
    #     goods.fav_num += 1
    #     goods.save()

    def get_serializer_class(self):
        if self.action == "list":
            return UserFavDetailSerializer
        elif self.action == "create":
            return UserFavSerializer

        return UserFavSerializer
class UserFavDetailSerializer(serializers.ModelSerializer):
    goods = GoodsSerializer()

    class Meta:
        model = UserFav
        fields = ("goods", "id")


class UserFavSerializer(serializers.ModelSerializer):
# 获得当前用户
    user = serializers.HiddenField(
        default=serializers.CurrentUserDefault()
    )

    class Meta:
        model = UserFav
        validators = [
            UniqueTogetherValidator(
                queryset=UserFav.objects.all(),
                fields=('user', 'goods'),
                message="已经收藏"
            )
        ]

        fields = ("user", "goods", "id")

vue:

    addCollect () { //加入收藏
          addFav({
              goods: this.productId
          }).then((response)=> {
                console.log(response.data);
                this.hasFav = true
                alert('已成功加入收藏夹');
            }).catch(function (error) {
                console.log(error);
            });
        },
//收藏
export const addFav = params => { return axios.post(`${host}/userfavs/`, params) }

drf的权限验证

# -*- coding: utf-8 -*-
__author__ = 'bobby'
from rest_framework import permissions


class IsOwnerOrReadOnly(permissions.BasePermission):
    """
    Object-level permission to only allow owners of an object to edit it.
    Assumes the model instance has an `owner` attribute.
    """

    def has_object_permission(self, request, view, obj):
        # Read permissions are allowed to any request,
        # so we'll always allow GET, HEAD or OPTIONS requests.
        if request.method in permissions.SAFE_METHODS:
            return True

        # Instance must have an attribute named `owner`.
        return obj.user == request.user
views参考上面

删除收藏

vue:

 deleteCollect () {
            //删除收藏
          delFav(this.productId).then((response)=> {
            console.log(response.data);
            this.hasFav = false
          }).catch(function (error) {
            console.log(error);
          });
        },
//取消收藏
export const delFav = goodsId => { return axios.delete(`${host}/userfavs/`+goodsId+'/') }

你可能感兴趣的:(Vue+Django,REST,framework实战)