#python #django
Вопрос:
Я не могу понять, что здесь происходит. У меня есть сеанс, который сохраняется, когда пользователь обращается к URL-адресу, например: website.com/client, где клиент-это клиент, использующий систему. Это сохраняется в сеансе с помощью django.contrib.sessions
Вот моя декларация промежуточного программного обеспечения:
MIDDLEWARE = [ 'debug_toolbar.middleware.DebugToolbarMiddleware', # must be before session middleware 'utils.middleware.routers.ClientDatabaseRouterMiddleware', 'corsheaders.middleware.CorsMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.security.SecurityMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', # custom middleware # 'utils.middleware.CookieMiddleware.CookieMiddleware', # 'utils.middleware.ExtendSession.ExtendSessionMiddleware', 'utils.middleware.UniversalDataMiddleware.UniversalDataMiddleware', 'apps.fort.middleware.LoginRequiredMiddleware', 'utils.middleware.TimezonesMiddleware.TimezonesMiddleware', 'utils.middleware.SessionMiddleware.SessionMiddleware', # maybe rewrite this? 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', # 'simple_history.middleware.HistoryRequestMiddleware', # auto adds user who makes change # 'utils.middleware.Profilers.ProfileMiddleware', # anything under this is excluded when decorator @property_not_important is called 'utils.middleware.CheckPropertyMiddleware.ExcludePropertyMiddleware', # allow exclusion 'utils.middleware.CheckPropertyMiddleware.CheckPropertyMiddleware', # 'utils.middleware.ExcludeMiddleware.ExcludeMiddleware', ]
Он также находится в INSTALLED_APPS.
Моя проблема в том, что когда я client url
загружаю django, сеанс сохраняется, но когда я возвращаюсь на основной сайт, поиск сеанса вызывает ошибку 500, потому что сеансы хранятся в каждой клиентской базе данных… как я могу это исправить?
Если я вручную удалю sessionid
сеанс, сгенерированный django в моем браузере, мой сайт загрузится без 500, поэтому я не уверен, как его удалить.
Комментарии:
1. В чем заключается точная ошибка? Что такое написание и чтение кода из сеанса?
Ответ №1:
Проблема, как я уже говорил, заключалась в том, что моя django_sessions
таблица хранилась в другой БД, чем моя БД по умолчанию, поскольку я основывался на этом, client_url
чтобы определить, какая версия используемой системы (т. Е. Для какого клиента).
Чтобы исправить это, мне пришлось немного изменить промежуточное программное обеспечение сеанса, предоставляемое Django: django.contrib.sessions.middleware.SessionMiddleware
чтобы я мог проверить запрос на client_url
переменную, потому что это был единственный способ сохранить или обновить сеанс.
Вот пересмотренный код, который я использовал вместо: django.contrib.sessions.middleware.SessionMiddleware
import time from importlib import import_module from django.conf import settings from django.contrib.sessions.backends.base import UpdateError from django.contrib.sessions.exceptions import SessionInterrupted from django.urls import resolve from django.utils.cache import patch_vary_headers from django.utils.deprecation import MiddlewareMixin from django.utils.functional import SimpleLazyObject from django.utils.http import http_date class SessionMiddleware(MiddlewareMixin): pass # RemovedInDjango40Warning: when the deprecation ends, replace with: # def __init__(self, get_response): def __init__(self, get_response=None): super().__init__(get_response) engine = import_module(settings.SESSION_ENGINE) self.SessionStore = engine.SessionStore def process_request(self, request): session_key = request.COOKIES.get(settings.SESSION_COOKIE_NAME) # print(request.path, resolve(request.path_info).kwargs) if 'client_url' in resolve(request.path_info).kwargs: print('client url found') request.session = self.SessionStore(session_key) # print(self.SessionStore(session_key), self.SessionStore(session_key).__dict__) else: # this is an error because the db cannot be found without client_url, # but we need to assign session or auth does not work print('session eluded...') request.session = {} def process_response(self, request, response): """ If request.session was modified, or if the configuration is to save the session every time, save the changes and set a session cookie or delete the session cookie if the session has been emptied. """ try: accessed = request.session.accessed modified = request.session.modified empty = request.session.is_empty() except AttributeError: return response # First check if we need to delete this cookie. # The session should be deleted only if the session is entirely empty. if settings.SESSION_COOKIE_NAME in request.COOKIES and empty: response.delete_cookie( settings.SESSION_COOKIE_NAME, path=settings.SESSION_COOKIE_PATH, domain=settings.SESSION_COOKIE_DOMAIN, samesite=settings.SESSION_COOKIE_SAMESITE, ) patch_vary_headers(response, ('Cookie',)) else: if accessed: patch_vary_headers(response, ('Cookie',)) if (modified or settings.SESSION_SAVE_EVERY_REQUEST) and not empty: if request.session.get_expire_at_browser_close(): max_age = None expires = None else: max_age = request.session.get_expiry_age() expires_time = time.time() max_age expires = http_date(expires_time) # Save the session data and refresh the client cookie. # Skip session save for 500 responses, refs #3881. if response.status_code != 500: try: request.session.save() except UpdateError: raise SessionInterrupted( "The request's session was deleted before the " "request completed. The user may have logged " "out in a concurrent request, for example." ) response.set_cookie( settings.SESSION_COOKIE_NAME, request.session.session_key, max_age=max_age, expires=expires, domain=settings.SESSION_COOKIE_DOMAIN, path=settings.SESSION_COOKIE_PATH, secure=settings.SESSION_COOKIE_SECURE or None, httponly=settings.SESSION_COOKIE_HTTPONLY or None, samesite=settings.SESSION_COOKIE_SAMESITE, ) return response