Добавление к списку заменяет последний элемент в промежуточном ПО Django
У меня есть промежуточное ПО, которое я использую для сохранения истории маршрутов в моем приложении 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 не знает, что вы изменили список, и поэтому данные записываются в сессию непоследовательно. Из документации:
По умолчанию, Django сохраняет в базе данных сессии только тогда, когда сессия была изменена - то есть, если любое из ее словарных значений было присвоено или удалено.
т.е. если вы измените список, не переназначив его или не удалив, то он не будет знать, что сессия была изменена. Снова из документации:
мы можем явно сообщить объекту сессии, что он был изменен, установив атрибут
modifiedна объекте сессии.
Так что ваш оригинальный код должен работать, если вы добавите эту строку после модификации списка на месте:
request.session.modified = True
(Замена списка полностью, как предложено в другом ответе, также работает - я просто пытаюсь объяснить почему ваш оригинальный код не работает).