Промежуточное программное обеспечение сеанса Django, вызывающее исключения

#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