代码之家  ›  专栏  ›  技术社区  ›  user984003

在django/python中从开始到结束跟踪单个请求

  •  0
  • user984003  · 技术社区  · 8 年前

    Django中有没有一种方法可以从开始到结束唯一地跟踪单个请求?明确地。我想知道beforeviewmiddleware中的请求与responseMiddleware中的请求相同。

    当前我使用request.session:

    # executes at start of processing
    class BeforeViewMiddleware(object):
        def process_view(self, request, view_func, view_args, view_kwargs):
            id = insert_data_into_table()
            request.session["id"] = id
    
    # executes when all processing is done
    class ResponseMiddleware(object):
        def process_response(self, request, view_func, view_args, view_kwargs):
            # Match the request with the request in BeforeViewMiddleware
            id = request.session["id"]
            update_table(id)
    

    但是,如果同时从同一会话发出两个或多个请求,则此操作失败。然后它会变成比赛条件,首先开始的可能会最后结束,而ID会混淆。

    2 回复  |  直到 8 年前
        1
  •  1
  •   user2390182    8 年前

    为什么不对请求本身使用具体的属性:

    class BeforeViewMiddleware(object):
        def process_view(self, request, view_func, view_args, view_kwargs):
            id = ...
            request._unik_attr = id
    
    class ResponseMiddleware(object):
        def process_response(self, request, view_func, view_args, view_kwargs):
            id = request._unik_attr
            # ...
    

    与会话不同,请求对象只存在于一个请求重复周期中。

        2
  •  0
  •   little_birdie    8 年前

    存储您的 id 会话中的值不起作用,因为正如您所认识到的,无论并发请求的数量如何,每个用户只有一个会话。

    更好的方法是将数据存储在线程局部变量中。每个请求从头到尾都由同一个线程处理,因此数据与请求保持一致。

    from threading import local
    _thread_data = local()
    
    class BeforeViewMiddleware(object):
        def process_view(self, request, view_func, view_args, view_kwargs):
            _thread_data.my_id = insert_data_into_table()
    
    class ResponseMiddleware(object):
        def process_response(self, request, view_func, view_args, view_kwargs):
            update_table(_thread_data.my_id)