附加到列表替换 Django 中间件中的最后一项

Appending to list replaces last item in Django middleware

我有一个中间件,用于在我的 Django 应用程序中保留路由历史记录以与面包屑一起使用,但由于某种原因,列表中的最后一项不断被替换,而不是附加到列表末尾的项目.

ROOT_ROUTE_PATH = '/labels/'

class RouteHistoryMiddleware(object):
    request = None
    history = None

    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        self.request = request

        if 'history' not in request.session:
            request.session['history'] = []

        self.history = request.session['history']

        request.session['history'].append(request.path)

        if len(self.history) == 0:
            self.request.previous_route = ROOT_ROUTE_PATH
        elif len(self.history) == 1:
            self.request.previous_route = request.session['history'][-1]
        elif len(self.history) > 1:
            self.request.previous_route = request.session['history'][-2]
        
        return self.get_response(request)

request.session['history'] 突变说明:

打开页面A

['/page_a/']

打开页面B

['/page_a/', '/page_b/']

打开C页

['/page_a/', '/page_c/']

不要将路径附加到会话,而是尝试附加到 self.history,然后用新数组覆盖历史:

    ...
    self.history = request.session['history']

    self.history.append(request.path)
    request.session['history'] = self.history
    ...

之后您可能需要更改 if/else 条件

您 运行 遇到的问题是 Django 不知道您已经修改了列表,因此数据写入会话的方式不一致。来自 documentation:

By default, Django only saves to the session database when the session has been modified – that is if any of its dictionary values have been assigned or deleted.

即,如果您修改列表而不重新分配或删除它,那么它不会知道会话已被修改。再次来自文档:

we can tell the session object explicitly that it has been modified by setting the modified attribute on the session object.

因此,如果您在就地修改列表后添加此行,您的原始代码应该可以工作:

request.session.modified = True

(完全替换列表,如其他答案中所建议的,也有效 - 我只是想解释 为什么 您的原始代码不起作用)。