登录合并购物车
在用户登录时,将cookie中的购物车数据合并到redis中,并清除cookie中的购物车数据。
普通登录和QQ登录都要合并,所以将合并逻辑放到公共函数里实现。
在carts/utils.py中创建merge_cart_cookie_to_redis方法
import pickle
import base64
from django_redis import get_redis_connection
def merge_cart_cookie_to_redis(request, user, response):
"""
合并请求用户的购物车数据,将未登录保存在cookie里的保存到redis中
:param request: 用户的请求对象
:param user: 当前登录的用户
:param response: 响应对象,用于清楚购物车cookie
:return:
"""
cookie_cart = request.COOKIES.get('cart')
if cookie_cart is not None:
cookie_cart = pickle.loads(base64.b64decode(cookie_cart.encode()))
redis_conn = get_redis_connection('cart')
redis_cart = redis_conn.hgetall('cart_%s' % usert.id)
redis_cart_selected = redis_conn.smembers('cart_selected_%s' % user.id)
cart = {}
for sku_id, count in redis_cart.items():
cart[int(sku_id)] = int(count)
for sku_id, count_selected_dict in cookie_cart.items():
cart[sku_id] = count_selected_dict['count']
if count_selected_dict['selected']:
redis_cart_selected.add(sku_id)
if cart:
pl = redis_conn.pipeline()
pl.hmset('cart_%s' % user.id, cart)
pl.sadd('cart_selected_%s' % user.id, *redis_cart_selected)
pl.execute()
response.delete_cookie('cart')
return response
修改登录视图
rest_framework_jwt提供的obtain_jwt_token视图,实际从rest_framework_jwt.views.ObtainJSONWebToken类视图而来,我们可以重写此类视图里的post方法来添加合并逻辑
from rest_framework_jwt.views import ObtainJSONWebToken
class UserAuthorizeView(ObtainJSONWebToken):
"""
用户认证
"""
def post(self, request, *args, **kwargs):
# 调用父类的方法,获取drf jwt扩展默认的认证用户处理结果
response = super().post(request, *args, **kwargs)
# 仿照drf jwt扩展对于用户登录的认证方式,判断用户是否认证登录成功
# 如果用户登录认证成功,则合并购物车
serializer = self.get_serializer(data=request.data)
if serializer.is_valid():
user = serializer.validated_data.get('user')
response = merge_cart_cookie_to_redis(request, user, response)
return response
修改路径users/urls.py
urlpatterns = [
...
# url(r'^authorizations/$', obtain_jwt_token),
url(r'^authorizations/$', views.UserAuthorizeView.as_view()),
...
]