【Vue+DRF 生鲜电商】商品详情(五)

1. 商品详情

接口地址:http://127.0.0.1:8000/goods/1/

相比之前的商品列表,只是多了一个单个商品的 ID,因此只需在 GoodsListViewSet 再添加一个 RetrieveModelMixin 获取商品详情即可:

class GoodsListViewSet(mixins.ListModelMixin, mixins.RetrieveModelMixin, viewsets.GenericViewSet)

商品详情轮播图

goods/serializers.py

class GoodsImageSerializer(serializers.ModelSerializer):
    """商品详情中的轮播图"""

    class Meta:
        model = GoodsImage
        fields = ('image',)


class GoodsSerializer(serializers.ModelSerializer):
    """
    商品列表页
    """
    # 覆盖外键字段
    category = CategorySerializer()

    # 商品轮播图,覆盖外键字段,这里使用的 related_name='images'
    images = GoodsImageSerializer(many=True)

    class Meta:
        model = Goods
        fields = '__all__'

商品轮播图是一个外键字段,只需在商品列表页中嵌套该字段即可。

2. 热卖商品

接口地址:http://127.0.0.1:8000/goods/?is_hot=true

1、在 goods/filters.py 中添加 is_hot 字段:

class Meta:
    model = Goods
    fields = ['pricemin', 'pricemax', 'top_category', 'is_hot']

2、xadmin 后台中设置商品是否为热卖商品,前端即可显示

3. 用户收藏

用户收藏涉及到:

  • 收藏商品:会在 UserFav 中创建一条记录(使用 CreateModelMixin)
  • 取消收藏:删除记录(使用 DestroyModelMixin
  • 获取收藏列表:查看数据集(使用 ListModelMixin

需求:

  • 登录用户才能收藏、取消、查看收藏列表
  • 当前用户只能获取自己的收藏,不能查看其它用户收藏
  • 已收藏不能再收藏(提示)

接口地址:

  • 收藏:http://127.0.0.1:8000/userfavs/post 请求,携带参数:{goods: "4"}
  • 取消收藏: http://127.0.0.1:8000/userfavs/3/delete 请求
  • 收藏列表:http://127.0.0.1:8000/userfavs/get 请求

3.1 接口实现

1、新建 user_operation/serializers.py

from rest_framework import serializers
from rest_framework.validators import UniqueTogetherValidator

from user_operation.models import UserFav


class UserFavSerializer(serializers.ModelSerializer):
    """用户收藏商品"""
    # 获取当前登录用户
    user = serializers.HiddenField(
        default=serializers.CurrentUserDefault()
    )

    class Meta:
        # validate 实现唯一联合,一个商品只能收藏一次
        validators = [
            UniqueTogetherValidator(
                queryset=UserFav.objects.all(),
                fields=('user', 'goods'),
                message="已经收藏"  # 自定义提示信息
            )
        ]
        model = UserFav
        # 返回商品 ID,用于取消收藏
        fields = ('user', 'goods', 'id')

2、user_operation/views.py

class UserFavViewSet(viewsets.GenericViewSet, mixins.ListModelMixin, mixins.CreateModelMixin, mixins.DestroyModelMixin):
    """
    用户商品收藏
    ListModelMixin:收藏列表
    CreateModelMixin:收藏
    DestroyModelMixin:取消(删除)收藏,相应地要删除数据库中数据
    """
    serializer_class = UserFavSerializer
    queryset = UserFav.objects.all()

3、配置路由 MxShop/urls.py

router.register(r'userfavs', UserFavViewSet, basename='userfavs')   # 用户商品收藏

4、测试:

3.2 权限认证

权限认证使得只有登录用户才能收藏、取消收藏以及查看收藏列表等。

1、新建 apps/utils/permissions.py

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):
        # 允许任何请求读取权限
        if request.method in permissions.SAFE_METHODS:
            return True

        # obj 相当于 model,将 owner 改为 user
        return obj.user == request.user

2、user_operation/views.py

class UserFavViewSet(viewsets.GenericViewSet, mixins.ListModelMixin, mixins.CreateModelMixin, mixins.DestroyModelMixin):
    """
    用户商品收藏
    ListModelMixin:收藏列表
    CreateModelMixin:收藏
    DestroyModelMixin:取消(删除)收藏,相应地要删除数据库中数据
    """
    serializer_class = UserFavSerializer
    queryset = UserFav.objects.all()

    # IsAuthenticated:必须登录用户;IsOwnerOrReadOnly:必须是当前登录的用户
    permission_classes = (IsAuthenticated, IsOwnerOrReadOnly)

    # 用户认证
    authentication_classes = (JSONWebTokenAuthentication, SessionAuthentication)

    # 搜索的字段(取消收藏会用到 goods_id)
    lookup_field = 'goods_id'

    def get_queryset(self):
        # 只能查看当前登录用户的收藏,禁止获取其他用户的收藏
        return UserFav.objects.filter(user=self.request.user)

注意:JWT 不应该全局配置,因为有些页面不需要验证,所以局部验证即可,注释掉 settings 中相关配置即可。

posted @ 2020-09-07 22:44  Hubery_Jun  阅读(313)  评论(0编辑  收藏  举报