对商品浏览记录的理解
商品浏览记录实现 分为2个接口
- post保存浏览记录sku_id
- get获取浏览记录
为什么使用redis保存浏览记录
浏览记录频繁更新和读取,redis读写速度快。
redis的数据存储设计
‘history_用户id’: [sku_id列表]
列表有序
实现流程
在user/serializers定义浏览历史序列化器
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
在user/views.py中定义视图继承 CreateModelMixin,GenericAPIView
class UserBrowsingHistoryView(mixins.CreateModelMixin, GenericAPIView): """ 用户浏览历史记录 """ serializer_class = AddUserBrowsingHistorySerializer permission_classes = [IsAuthenticated] def post(self, request): """ 保存 """ return self.create(request)
在goods/utils.py定义商品列表序列化器
from rest_framework import serializers from .models import SKU class SKUSerializer(serializers.ModelSerializer): class Meta: model = SKU fields = ('id', 'name', 'price', 'default_image_url', 'comments')
在user/views.py中添加获取浏览记录视图
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)