Django Rest框架乐观锁定Etag

2024-09-29 23:33:18 发布

您现在位置:Python中文网/ 问答频道 /正文

因此,我试图通过使用带有ETag条件视图的django rest框架条件库来实现乐观锁定

我使用以下哈希函数:

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, request, pk, format=None): #, *args, **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值存储在客户机上,并在执行PUT请求时将其发送回If-Match头中

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

这是因为我在实现中做错了什么,还是django条件函数没有处理哈希值的更新

编辑

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

但是通过检查https://www.rfc-editor.org/rfc/rfc7232#section-2.3文档,它表示“实体标记是一个不透明的验证程序 区分相同的的多个表示 资源,无论这些多个表示是否 由于资源状态随时间而变化”

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

这是一个解决方案吗


Tags: 函数selfdatagetreturnobjectsrequestmy

热门问题