記事のディレクトリ
ショッピングカートストレージソリューション
- 2つのケースがあります
ユーザーログイン
- 完全なショッピングカートレコードの必要性を説明する
- ユーザー、製品、数量、ステータスの確認
- データの保存:user_id、sku_id、count、選択済み
- ストレージの場所:
- redisデータベースを選択してください
- データストレージタイプ
-
(1)ハッシュタイプを選択し、ユーザー、製品、数量、その他の情報を保存します。
保存されるデータは次のとおりです。carts_user_id:{sku_id1:count、sku_id3:count、sku_id5:count、…} -
(2)チェック状態:セットタイプストレージを採用
-
チェックされた商品のsku_idのみをセットに保存します。たとえば、1番目と3番目の商品がチェックされます。
-
形式:selected_user_id:[sku_id1、sku_id3 ...]
-
- ストレージロジックの説明
- ショッピングカートに追加するアイテムがすでに存在する場合、アイテムの数量は累積的に計算されます
- ショッピングカートに追加する商品が存在しない場合は、ハッシュにフィールドと値を追加するだけです。
ユーザーがログインしていません
データの保存
- 上記と同じuser_id、sku_id、count、selected
ストレージの場所
- ユーザーがログインしていないため、サーバーはユーザーIDを取得できません
- ユーザーのブラウザCookieにログインしていないユーザーのショッピングカートデータをキャッシュでき、各ユーザーの独自のブラウザのCookieは独自のショッピングカートデータを保存します
ストレージタイプ
- (1)ブラウザのCookieに保存されるデータの種類は文字列です
- (2)JSON文字列は、複雑な構造の文字列データを記述できるため、ショッピングカートのレコードを個別に保存する必要がありません。
- データ構造表示:
{
"sku_id1":{
"count":"1",
"selected":"True"
},
"sku_id3":{
"count":"3",
"selected":"True"
},
"sku_id5":{
"count":"3",
"selected":"False"
}
}
ストレージロジックの説明
- ショッピングカートに追加する商品が既に存在する場合は、商品数を累積計算します。
- ショッピングカートに追加する商品が存在しない場合は、JSONにフィールドと値を追加するだけです。
データセキュリティ処理:
- (1)ブラウザのCookieに保存されるのは文字列の平文データです
- データを暗号化する必要があります
- (2)解決策:pickleモジュールとbase64モジュール
ピクルスモジュールの紹介
- pickleモジュールはPythonの標準モジュールであり、Pythonデータのシリアル化操作を提供し、データをバイト型に変換でき、シリアル化の速度は高速です。
- 指示:
- pickle.dumps()は、Pythonデータをバイト型データにシリアル化します
- pickle.loads()は、バイト型データをPythonデータに逆シリアル化します。
base64モジュールの概要
- 注意!!!:pickleモジュールによってシリアル化および変換されたデータはbytes型であり、ブラウザのCookieを保存できません。
- 前書き:
- base64モジュールはPythonの標準モジュールであり、バイト型データをエンコードしてバイト型暗号文データを取得できます。
- 使用する:
- base64.b64encode()Base64-バイト型データをエンコードし、エンコードされたバイト型データを返します
- base64.b64deocde()は、base64でエンコードされたバイト型データをデコードし、デコードされたバイト型データを返します。
以下は特定のコード実装です
ショッピングカートを追加する
redis
redis_conn = get_redis_connection('carts')
pl = redis_conn.pipeline()
# 新增购物车数据
pl.hincrby('carts_%s' % user.id, sku_id, count)
# 新增选中的状态
if selected:
pl.sadd('selected_%s' % user.id, sku_id)
# 执行管道
pl.execute()
クッキー中
# 用户未登录,操作cookie购物车
cart_str = request.COOKIES.get('carts')
# 如果用户操作过cookie购物车
if cart_str:
# 将cart_str转成bytes,再将bytes转成base64的bytes,最后将bytes转字典
cart_dict = pickle.loads(base64.b64decode(cart_str.encode()))
else: # 用户从没有操作过cookie购物车
cart_dict = {
}
# 判断要加入购物车的商品是否已经在购物车中,如有相同商品,累加求和,反之,直接赋值
if sku_id in cart_dict:
# 累加求和
origin_count = cart_dict[sku_id]['count']
count += origin_count
cart_dict[sku_id] = {
'count': count,
'selected': selected
}
# 将字典转成bytes,再将bytes转成base64的bytes,最后将bytes转字符串
cookie_cart_str = base64.b64encode(pickle.dumps(cart_dict)).decode()
# 创建响应对象
response = http.JsonResponse({
'code': RETCODE.OK, 'errmsg': '添加购物车成功'})
# 响应结果并将购物车数据写入到cookie
response.set_cookie('carts', cookie_cart_str, max_age=constants.CARTS_COOKIE_EXPIRES)
ショッピングカートを削除する
redis
redis_conn = get_redis_connection('carts')
pl = redis_conn.pipeline()
# 删除键,就等价于删除了整条记录
pl.hdel('carts_%s' % user.id, sku_id)
pl.srem('selected_%s' % user.id, sku_id)
pl.execute()
クッキーショッピングカートを削除する
cart_str = request.COOKIES.get('carts')
if cart_str:
# 将cart_str转成bytes,再将bytes转成base64的bytes,最后将bytes转字典
cart_dict = pickle.loads(base64.b64decode(cart_str.encode()))
else:
cart_dict = {
}
# 创建响应对象
response = http.JsonResponse({
'code': RETCODE.OK, 'errmsg': '删除购物车成功'})
if sku_id in cart_dict:
del cart_dict[sku_id]
# 将字典转成bytes,再将bytes转成base64的bytes,最后将bytes转字符串
cookie_cart_str = base64.b64encode(pickle.dumps(cart_dict)).decode()
# 响应结果并将购物车数据写入到cookie
response.set_cookie('carts', cookie_cart_str, max_age=constants.CARTS_COOKIE_EXPIRES)
return response
残りの変更とディスプレイショッピングカートは類似しているため、ここでは説明しません。
すべてのショッピングカートを選択
redisの場合:
# 用户已登录,操作redis购物车
redis_conn = get_redis_connection('carts')
cart = redis_conn.hgetall('carts_%s' % user.id)
sku_id_list = cart.keys()
if selected:
# 全选
redis_conn.sadd('selected_%s' % user.id, *sku_id_list)
else:
# 取消全选
redis_conn.srem('selected_%s' % user.id, *sku_id_list)
return http.JsonResponse({
'code': RETCODE.OK, 'errmsg': '全选购物车成功'})
クッキー中
# 用户已登录,操作cookie购物车
cart = request.COOKIES.get('carts')
response = http.JsonResponse({
'code': RETCODE.OK, 'errmsg': '全选购物车成功'})
if cart is not None:
cart = pickle.loads(base64.b64decode(cart.encode()))
for sku_id in cart:
cart[sku_id]['selected'] = selected
cookie_cart = base64.b64encode(pickle.dumps(cart)).decode()
response.set_cookie('carts', cookie_cart, max_age=constants.CARTS_COOKIE_EXPIRES)
ショッピングカートをマージする
# 获取cookie中的购物车数据
cookie_cart_str = request.COOKIES.get('carts')
# cookie中没有数据就响应结果
if not cookie_cart_str:
return response
cookie_cart_dict = pickle.loads(base64.b64decode(cookie_cart_str.encode()))
new_cart_dict = {
}
new_cart_selected_add = []
new_cart_selected_remove = []
# 同步cookie中购物车数据
for sku_id, cookie_dict in cookie_cart_dict.items():
new_cart_dict[sku_id] = cookie_dict['count']
if cookie_dict['selected']:
new_cart_selected_add.append(sku_id)
else:
new_cart_selected_remove.append(sku_id)
# 将new_cart_dict写入到Redis数据库
redis_conn = get_redis_connection('carts')
pl = redis_conn.pipeline()
pl.hmset('carts_%s' % user.id, new_cart_dict)
# 将勾选状态同步到Redis数据库
if new_cart_selected_add:
pl.sadd('selected_%s' % user.id, *new_cart_selected_add)
if new_cart_selected_remove:
pl.srem('selected_%s' % user.id, *new_cart_selected_remove)
pl.execute()
# 清除cookie
response.delete_cookie('carts')
それだけです。Cookieとredisの追加、削除、変更、チェック、操作がすべてです。実際には非常に面倒ですが、難しくはありません。ロジックの実装を注意深く理解できます。