如何解决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)
我正在模拟两个用户对同一资源执行 GET
和 PUT
操作。在每个 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 举报,一经查实,本站将立刻删除。