因此,我试图通过使用带有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)
我正在模拟两个用户对同一资源执行GET
和PUT
操作。在每次GET
请求时,我将ETag值存储在客户机上,并在执行PUT
请求时将其发送回If-Match
头中
我注意到,当两个用户同时执行PUT
请求时,资源的哈希不会改变,因此第二个PUT
请求不会被阻止在资源中保存新信息
这是因为我在实现中做错了什么,还是django条件函数没有处理哈希值的更新
编辑
我想我知道为什么哈希值没有更新。my_etag函数根据从客户端HttpRequest对象接收的Querydict值返回一个哈希值,在我的情况下,这些值是空的,因为我在http请求中没有指定任何参数
但是通过检查https://www.rfc-editor.org/rfc/rfc7232#section-2.3文档,它表示“实体标记是一个不透明的验证程序 区分相同的的多个表示 资源,无论这些多个表示是否 由于资源状态随时间而变化”
根据定义,我的结论是ETag
值应该是请求资源的哈希值,因此哈希值应该在发送响应之前计算,而不是在接收第一个请求时计算
这是一个解决方案吗
目前没有回答
相关问题 更多 >
编程相关推荐