Django Rest Framework 乐观锁 - Etag

问题描述

所以...我正在尝试通过使用带有 ETag 条件视图的 django-rest-framework-condition 库来实现乐观锁定。

我使用以下哈希函数:

def my_etag(request,*args,**kwargs):
    return hashlib.md5(':'.join(request.GET.dict().values()).encode('utf-8')).hexdigest()

这是我与 @etag 装饰器一起使用的视图函数。

# Usine list
class UsineList(APIView):
    queryset = Usine.objects.all()

    permission_classes = (CustomDjangoModelPermissions,)

    # user_gains_perms(request,request.user.pk)
    @etag(my_etag)
    def get(self,request,format=None):
        #print(request.META.get("ETag"))
        #print("JJJ",request.META.get('HTTP_IF_MATCH',''))
        usines = Usine.objects.all()
        serializer = UsineSerializer(usines,many=True)
        response = Response({"usines": serializer.data})
        return response

class UsineDetail(APIView):
    queryset = Usine.objects.all()
    permission_classes = (CustomDjangoModelPermissions,)

    def get_object(self,pk):
        try:
            return Usine.objects.get(pk=pk)
        except Usine.DoesNotExist:
            raise Http404

    @etag(my_etag)
    def put(self,pk,format=None): #,**kwargs):
        #print(request.headers)
        usine = self.get_object(pk)
        serializer = UsineSerializer(usine,data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors,status=status.HTTP_400_BAD_REQUEST)

我正在模拟两个用户对同一资源执行 GETPUT 操作。在每个 GET 请求中,我将 ETag 值存储在客户端上,并在执行 If-Match 请求时将其发送回 PUT 标头中。

我注意到当两个用户同时执行 PUT 请求时,资源的哈希值不会改变,因此第二个 PUT 请求不会被阻止保存资源中的新信息。

这是因为我在实现中做错了还是django条件函数没有处理hash值的更新?

编辑

我想我知道为什么哈希值没有更新。 my_etag 函数根据从客户端 HttpRequest 对象接收到的 Querydict 值返回一个哈希值,在我的情况下它们是空的,因为我没有在我的 http 请求中指定任何参数。

但是通过检查 https://tools.ietf.org/html/rfc7232#section-2.3 文档,它说“实体标签是一个不透明的验证器 区分 相同的多个表示 资源,无论这些多重表示是否是 由于资源状态随时间变化"

根据定义,我的结论是 ETag 值应该是所请求资源的哈希值,因此应该在发送响应之前而不是在收到第一个请求时计算哈希值。

>

这是一个解决方案吗?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...