用户浏览历史记录

用户在访问每个商品详情页面时,都要记录浏览历史记录

历史记录只需保存多个商品的sku_id即可,而且需要保持添加sku_id的顺序,所以采用redis中的列表来保存,redis的数据存储设计

'history_用户id': [sku_id列表]

在配置文件中增加浏览历史记录的redis配置

CACHES = {
    ...
    "history": {
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": "redis://10.211.55.5:6379/3",
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
        }
    },
}

1. 保存

后端接口设计

请求方式:POST /browse_histories/

请求参数:JSON 或 表单

参数类型是否必须说明
sku_id int 商品sku 编号

返回数据:JSON

返回值类型是否必须说明
sku_id int 商品sku 编号

后端实现

在users/serializes.py中实现序列化器

class AddUserBrowsingHistorySerializer(serializers.Serializer):
    """
    添加用户浏览历史序列化器
    """
    sku_id = serializers.IntegerField(label="商品SKU编号", min_value=1)

    def validate_sku_id(self, value):
        """
        检验sku_id是否存在
        """
        try:
            SKU.objects.get(id=value)
        except SKU.DoesNotExist:
            raise serializers.ValidationError('该商品不存在')
        return value

    def create(self, validated_data):
        """
        保存
        """
        user_id = self.context['request'].user.id
        sku_id = validated_data['sku_id']

        redis_conn = get_redis_connection("history")
        pl = redis_conn.pipeline()

        # 移除已经存在的本商品浏览记录
        pl.lrem("history_%s" % user_id, 0, sku_id)
        # 添加新的浏览记录
        pl.lpush("history_%s" % user_id, sku_id)
        # 只保存最多5条记录
        pl.ltrim("history_%s" % user_id, 0, constants.USER_BROWSING_HISTORY_COUNTS_LIMIT-1)

        pl.execute()

        return validated_data

在users/views.py中编写视图

class UserBrowsingHistoryView(mixins.CreateModelMixin, GenericAPIView):
    """
    用户浏览历史记录
    """
    serializer_class = AddUserBrowsingHistorySerializer
    permission_classes = [IsAuthenticated]

    def post(self, request):
        """
        保存
        """
        return self.create(request)

前端实现

在detail.js中添加

mounted: function(){
        // 添加用户浏览历史记录
        this.get_sku_id();
        if (this.user_id) {
            axios.post(this.host+'/browse_histories/', {
                sku_id: this.sku_id
            }, {
                headers: {
                    'Authorization': 'JWT ' + this.token
                }
            })
        }
        this.get_cart();
        this.get_hot_goods();
        this.get_comments();
    },

2. 查看

后端接口设计

请求方式:GET /browse_histories/

请求参数: 无

返回数据: JSON

[
    {
        "id": 14,
        "name": "华为 HUAWEI P10 Plus 6GB+128GB 玫瑰金 移动联通电信4G手机 双卡双待",
        "price": "3788.00",
        "default_image_url": "http://image.meiduo.site:8888/group1/M00/00/02/CtM3BVrRdMSAaDUtAAVslh9vkK04466364",
        "comments": 1
    },
    {
        "id": 16,
        "name": "华为 HUAWEI P10 Plus 6GB+128GB 曜石黑 移动联通电信4G手机 双卡双待",
        "price": "3788.00",
        "default_image_url": "http://image.meiduo.site:8888/group1/M00/00/02/CtM3BVrRdPeAXNDMAAYJrpessGQ9777651",
        "comments": 0
    }
]
返回值类型是否必须说明
id int 商品sku 编号
name str 商品名称
price decimal 单价
default_image_url str 默认图片
comments int 评论量

后端实现

在users/views.py中UserBrowsingHistoryView视图补充get方法

from goods.serializers import SKUSerializer

class UserBrowsingHistoryView(mixins.CreateModelMixin, GenericAPIView):
    """
    用户浏览历史记录
    """
    ...

    def get(self, request):
        """
        获取
        """
        user_id = request.user.id

        redis_conn = get_redis_connection("history")
        history = redis_conn.lrange("history_%s" % user_id, 0, constants.USER_BROWSING_HISTORY_COUNTS_LIMIT-1)
        skus = []
        # 为了保持查询出的顺序与用户的浏览历史保存顺序一致
        for sku_id in history:
            sku = SKU.objects.get(id=sku_id)
            skus.append(sku)

        s = SKUSerializer(skus, many=True)
        return Response(s.data)
posted @ 2018-07-30 22:10  程序视界  阅读(2315)  评论(0编辑  收藏  举报