首页 > 其他分享 >美多商城项目(四)

美多商城项目(四)

时间:2023-01-11 11:34:25浏览次数:34  
标签:count 项目 request self bytes cart data 商城

购物车部分

  • 购物车商品应当存储那些数据

    • sku_id,count(用户购买几个),selected(是否被勾选)
- 登录用户: 允许使用服务器资源

    - 存储到 redis,每条数据分两种格式存储

        - Set:{sku_id_1,sku_id_2......} # 有放入集合(自带去重功能),就表示已勾选

        - Hash:dict {sku_id_1:count,sku_id_2:count......}

- 未登录用户: 不允许使用服务器资源

    - 存储到 浏览器cookie(存到 localStorage也可以...)

    - cookie中只能存储'键值对',key-value都是必须是str类型

        - response.set_cookie('cart','value','过期时间')

        - 类似的数据格式:

            {
                sku_id_1:{'count':1,'selected':true},
                sku_id_2:{'count':1,'selected':true}
            }

pickle模块(比json模块高效)和base64模块(简单加密/解密)

  • pickle模块: 提供了对于 python 数据的序列化操作,可以将数据转换为 bytes 类型

    • pickle.dumps(): 将 python 数据序列化为 bytes 类型

    • pickle.loads(): 将 bytes 类型数据反序列化为 python 的数据类型( 字典, 对象等 )

import pickle

data = {'1': {'count': 10, 'selected': True}, '2': {'count': 20, 'selected': False}}
bytes_data = pickle.dumps(data)
print(bytes_data) # b'\x80\x03}q\x00(X\x01\x00\x00\x001q\x01}q\x02(X\x05\x00......
dict_data = pickle.loads(bytes_data)
print(dict_data) # {'1': {'count': 10, 'selected': True}, '2': {'count': 20, 'selected': False}}
  • base64模块:把bytes类型数据,作进一步'加密'/'解密'处理
import base64

bytes_data = b'king'
encode_bytes_data = base64.b64encode(bytes_data)
print(encode_bytes_data) # b'a2luZw=='
decode_bytes_data = base64.b64decode(encode_bytes_data)
print(decode_bytes_data) # b'king'
  • 项目应用
- 读取步骤

    - 先获取用户是否操作过 cookie作为购物车

        # cart_str是经过b64加密后的字符串
        - cart_str = request.COOKIES.get('cart')

    - 把 cart_str 转换为 bytes

        - cart_str_bytes = cart_str.encode()

    - cart_str_bytes 作 base64解密

        - b64 = base64.b64decode(cart_str_bytes)

    - 把 b64经过pickle.loads(),转换成字典

        - cart_dict = pickle.loads(b64)

- 添加步骤
    
    # cart_dict 是购物车数据
    - 先将 cart_dict 经过 pickle.dumps()转换成 bytes

        - cart_dict_bytes = pickle.dumps(cart_dict)

    - 将 cart_dict_bytes 经过b64加密

        - b64 = base64.b64encode(cart_str_bytes)

    - 将b64转换为str,最后写入cookie

        cookie_cart_str = b64.decode()
        response.set_cookie('cart',cookie_cart_str)
  • 后端编写购物车接口
# apps.carts.views
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework_jwt.authentication import JSONWebTokenAuthentication
from rest_framework.permissions import IsAuthenticated


class CartView(APIView):

    # authentication_classes = [JSONWebTokenAuthentication,]
    # permission_classes = [IsAuthenticated,]

    def post(self,request):
        return Response({'msg':'响应成功'})


    def get(self,request):
        pass

    def put(self,request):
        pass

    def delete(self,request):
        pass

  • 前端代码
......
// 添加购物车
add_cart: function(){
    axios.post(this.host+'/carts/', {
            // 把 sku_id 和 count 发送到后端
            sku_id: parseInt(this.sku_id),
            count: this.sku_count
        }, {
            headers: { // 校验
                'Authorization': 'JWT ' + this.token
            },
            responseType: 'json',
            withCredentials: true
        })
        .then(response => {
            alert('添加购物车成功');
            this.cart_total_count += response.data.count;
        })
        .catch(error => {
            if ('non_field_errors' in error.response.data) {
                alert(error.response.data.non_field_errors[0]);
            } else {
                alert('添加购物车失败');
            }
            console.log(error.response.data);
        })
},
  • 未登录用户的认证问题
- 不管用户是否登录,都必须实现购物车功能

- 而当用户未登录时候,前端依然在 headers 加入 'Authorization'
  所以请求还没到视图views,就会被认证类 JSONWebTokenAuthentication 拦截
  无法实现后续购物车的逻辑

    - 解决办法一: 前端不在headers加入 'Authorization'

    - 解决办法二: 后端作'延迟认证'处理(使用这个方法处理)
  • 查看后端认证的APIView源码
- 先走dispatch

class APIView(View):
    ......
    def dispatch(self, request, *args, **kwargs):
        ......
        try:
            # 走这个方法
            self.initial(request, *args, **kwargs)

    def initial(self, request, *args, **kwargs):
        ......
        # 走认证,权限和节流
        # 进 perform_authentication()
        self.perform_authentication(request)
        self.check_permissions(request)
        self.check_throttles(request)

    def perform_authentication(self, request):

        ### 看注释
        """
        Perform authentication on the incoming request.

        Note that if you override this and simply 'pass', then authentication
        will instead be performed lazily, the first time either
        `request.user` or `request.auth` is accessed.
        """
        request.user

        '''
        当简单重写这个方法的时候, 校验会变'懒'(延迟校验),直至出现 request.user / request.auth
        校验才会继续进行
        '''

### setttings
......
#---------DRF配置项------------#
REST_FRAMEWORK = {
   ......
    'DEFAULT_AUTHENTICATION_CLASSES': [
        # 首选是JWT
        'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
    ],

    # 这个权限类不能加,加上就验证: IsAuthenticated 会调用 request.user/auth
    # 'DEFAULT_PERMISSION_CLASSES': [
    #     # IsAuthenticated 仅通过认证的用户
    #     'rest_framework.permissions.IsAuthenticated'
    # ]
}

### views
......
class CartView(APIView):

    # 重写这个方法,延迟校验
    def perform_authentication(self, request):
        pass

    def post(self,request):
        return Response({'msg':'响应成功'})


    def get(self,request):
        pass

    def put(self,request):
        pass

    def delete(self,request):
        pass

- 测试: http://127.0.0.1:8000/carts/

    - 参数: Authorization: JWT空格

- 加上 request.user 测试

    def post(self,request):

        # 启用校验逻辑,触发异常: "detail": "Invalid Authorization header. No credentials provided."
        user = request.user
        return Response({'msg':'响应成功'})

- 捕获该异常并继续执行我们的逻辑

    def post(self,request):

        try:
            user = request.user
        except:
            user = None

        return Response({'msg':'响应成功'})

标签:count,项目,request,self,bytes,cart,data,商城
From: https://www.cnblogs.com/qinganning/p/17043219.html

相关文章

  • 年终汇报工作,如何用项目管理工具展现成果
    据报道,2022年11月20日的一次京东内部会议上,刘强东痛批京东中高层管理人员,表示部分高管醉心于PPT和奇妙词汇,或吹得天花乱坠但是执行一塌糊涂。不可否认,刘强东提到的现象,......
  • 微服务项目如何显示多个模块的启动项
    微服务项目如何显示多个模块的启动项在.idea>>workspace.xml文件中添加以上内容,重新编译生效!<componentname="RunDashboard"><optionname="configurationTypes">......
  • idea创建maven + tomcat项目
                        移动文件夹:           找到tomcat文件目录          配置......
  • 记录使用adb连接rn项目进行开发
    先在本地安装adbADB全称AndroidDebugBridge,译作Android调试桥。ADB是一种功能多样的命令行工具,可让您与设备进行通信。ADB命令可用于执行各种设备操作(例如安装和调......
  • SQL优化案例9(广东某管理局项目)
    同事找我优化SQL,同一条SQL语句LIKE过滤条件不同,执行时间差别很多,废话不说安排一下。LIKE过滤条件执行快的SQL和执行计划:EXPLAINANALYZESELECTcase_id,cate_......
  • Java(SpringBoot)项目打包(构建)成`Docker`镜像的几种方式
    前置说明最为原始的打包方式spring-boot-maven-plugin插件jib-maven-plugin插件dockerfle-maven-plugin插件最为原始的方式也就是使用Docker的打包命令去打包,麻......
  • BBS项目修改密码及退出登录思路总结
    BBS项目修改密码及退出登录思路总结创建超级管理员用户和登录步骤一、修改密码编写步骤概览开设修改密码路由首页前端代码写Ajax请求回到后端继续修改密码逻辑......
  • 如何优雅地升级一个Creator 2.x 项目到 3.6.2 ?
    最近,我将之前用CocosCreator2.x写的一个微信小游戏《球球要回家》移植到了CocosCreator3.6.2上。编程语言也从JavaScript迁移到了TypeScript,并成功上线微信小......
  • 前端开源项目 CDN | 网站整理
    官网描述BootCDN附带搜索,编辑好格式可以直接复制百度静态资源公共库百度的,支持搜索,不支持直接复制新浪js库不算很方便七牛云存储开放静态文件国内知......
  • openEuler社区开源项目:CPDS(容器故障检测系统)介绍
    容器故障检测系统CPDS(ContainerProblemDetectSystem)是由北京凝思软件股份有限公司(以下简称“凝思软件”)设计并开发的容器集群故障检测系统,该软件系统实现了对容器TO......