### 5.8 浏览记录
#### 1.统计分类商品访问量
- 统计分类商品访问量 是统计一天内该类别的商品被访问的次数。
- 需要统计的数据,包括商品分类,访问次数,访问时间。
- 一天内,一种类别,统计一条记录。
实现:
1. 获取当前浏览产品的caretory_id
2. 获取当前日期
3. 查看表中数据是否有当前日期,如果没有的话添加 如果有的话在访问量值处加1
models类:
```python
#分类访问量
class GoodsVitstCount(BaseModel):
"""统计分类商品访问量模型类"""
category = models.ForeignKey(GoodsCategory, on_delete=models.CASCADE, verbose_name='商品分类')
count = models.IntegerField(verbose_name='访问量', default=0)
date = models.DateField(auto_now_add=True, verbose_name='统计日期')
class Meta:
db_table = 'tb_goods_visit'
verbose_name = '统计分类商品访问量'
verbose_name_plural = verbose_name
```
view:
```python
class GoodsVisitView(View):
def post(self,request,category_id):
#1. 获取当前浏览商品
try:
visitgoods = GoodsVitstCount.objects.get(category_id=category_id)
except:
visitgoods = GoodsVitstCount.objects.create(category_id=category_id,count=1)
else:
#todo 看看明天日期是否增加
visitgoods.count +=1
visitgoods.save()
```
#### 2.rabbitmq的安装
- 下载带管理工具的rabbitmq镜像
```
sudo docker pull rabbitmq:3-management
```
如果安装本地文件:
```
sudo docker load -i rabbitmq_3-management.tar(文件名 需要带路径)
```
- 运行,创建容器
```
sudo docker run -d --name rabbit1 --hostname rabbit1 -p 5672:5672 -p 15672:15672 rabbitmq:3-management
```
-p 端口映射
- 在celery中连接配置
```
broker_url= 'amqp://guest:guest@127.0.0.1:5672'
```
- 在浏览器中查看管理工具地址
```
http://127.0.0.1:15672
账号密码均为guest
```
#### 3.redis的相关命令
[redis的命令](http://redisdoc.com/)
此时浏览记录使用redis进行保存 并不是必须使用redis才能保存,mysql也可以进行保存
##### 1.dev中配置浏览记录的储存位置
```python
CACHES = {
"history": { # 用户浏览记录
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://127.0.0.1:6379/3",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
}
},
}
```
3. ##### 存储类型说明
> - 由于用户浏览记录跟用户浏览商品详情的顺序有关,所以我们选择使用Redis中的**list**类型存储 sku_id
> - hush为类似字典的格式
> - 每个用户维护一条浏览记录,且浏览记录都是独立存储的,不能共用。所以我们需要对用户的浏览记录进行唯一标识。
> - 我们可以使用登录用户的ID来唯一标识该用户的浏览记录。
> - **存储类型:'history_user_id' : [sku_id_1, sku_id_2, ...]**
1.
使用的命令:(key为列表名,value为列表值)
- - lpush key value:将value回到列表key的第一个位置
- 从左插入 读取也从左边读取,即最先存放的最在列表的最后一位 类似于栈
- llen key:获取列表key的元素个数
- rpop key:删除列表中key的最后一个元素
- ltrim key start end:从列表中截取部分元素,会对原始列表进行修改 而不是产生一个新的列表 允许有负数
- lrange key 0 -1:读取列表的所有元素
- lrem key count value:删除指定个数的value(列表项)
- count=0时 表示全部删除
- count=正数时,从左到右删除该指定个数
- count=负数时,从右到左删除指定个数
#### 4.浏览记录的添加
需求:
获取用户最近浏览的5个产品
实现
1.在redis中新建一个列表 因为每个用户的浏览不一样 所以需要使用列表名进行区分 列表名使用用户id +一个字段即可区分
检查:判断sku_id是否存在
判断用户是否登录
1. 最新的元素需要在最前面显示(列表从左侧开始添加)
2. 只显示5个最近浏览记录(规定
3. 如果之前浏览了一个产品,再次浏览该产品 需要将这个产品放在最先浏览处(即 同一个商品只显示一次)
4. 显示列表元素(读取列表)
```python
def post(self, request):
# 接收数据
json_dict = json.loads(request.body.decode())
sku_id = json_dict.get('sku_id')
# 验证 验证用户是否登录
if not request.user.is_authenticated:
return http.JsonResponse({
'code': '400',
'emssg': '未登录'
})
# 验证 验证是否有数据传入
if not all([sku_id]):
return http.JsonResponse({
'code': '404',
'emssg': '没有数据传入'
})
# 处理 将数据存入数据库中
# 1.连接数据库
redis_cli = get_redis_connection('user_history')
# 由于每个用户的浏览记录都不一样 所以需要根据用户名设置key
key = 'history_%d' % request.user.id
# 1.删除列表中的元素 即如果元素已经存在了
redis_cli.lrem(key,0,sku_id)
# 2.左侧加入元素
redis_cli.lpush(key,sku_id)
# 3.截取个数
redis_cli.ltrim(key,0,4)
return http.JsonResponse({
'code': 'OK',
'errmsg': 'OK'
})
```
#### 5.浏览记录的读取
列表推导式:
```python
sku_list = [int(sku_id) for sku_id in spu_id_bytes]
```
遍历spu_id_bytes 遍历出来的数据为sku_id,将sku_id进行操作int(sku_id),生成的值放入列表中
```python
def get(self,request,):
user = request.user
#连接数据库
redis_cil = get_redis_connection('user_history')
key = 'history_%d' % request.user.id
#获取操作的数据 取出来的数据为商品的sku_id
spu_id_bytes = redis_cil.lrange(key,0,-1)
#将获取的浏览记录列表转换 从redis中读取的数字为字节型数据
sku_list = [int(sku_id) for sku_id in spu_id_bytes]
sku_send = []
for sku_id in sku_list:
sku = SKU.objects.get(id=sku_id)
sku_send.append({
'id':sku.id,
'name':sku.name,
'default_image_url':sku.skuimage_set.all()[0].image.url,
'price':sku.price
})
print(sku_send)
return http.JsonResponse({
'code':'ok',
'errmsg':'OK',
'skus':sku_send
})
```
#### 6.前端代码的实现
本次使用vue进行显示
```html
<ul class="goods_type_list clearfix">
<li v-for="sku in histories">
<a :href="sku.url"><img :src="sku.default_image_url"></a>
<h4><a :href="sku.url">[[ sku.name ]]</a></h4>
<div class="operate">
<span class="price">¥[[ sku.price ]]</span>
<span class="unit">台</span>
<a href="#" class="add_goods" title="加入购物车"></a>
</div>
</li>
</ul>
```
] |
|