Opened 3 years ago
Last modified 3 years ago
#33533 closed Uncategorized
Should it be impossible for a session dict to return more than one value for a key? — at Initial Version
Reported by: | Michael | Owned by: | nobody |
---|---|---|---|
Component: | contrib.sessions | Version: | 4.0 |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
In my project, I store the serial number of the device that logs in it's session. However in the code that gets the value from the session:
SESSION_SERIAL_NUMBER = 'terminal_serial_number' user._serial_number = request.session.get(SESSION_SERIAL_NUMBER, '')
Very occasionally throws an error. The part that baffles me is:
get() returned more than one Session -- it returned more than 20!
How can a dict return more than one result, surely that is a bug for a dict to return more than one value?
Note: When I query the database django_sessions
table with the given sessionid
, it only returns one row.
Heres the error (from the email):
Internal Server Error: /accounts/login/ ProgrammingError at /accounts/login/ no results to fetch
And the traceback:
Traceback (most recent call last): File "/home/company/.venv/project/lib/python3.8/site-packages/django/contrib/sessions/backends/base.py", line 180, in _get_session return self._session_cache During handling of the above exception ('SessionStore' object has no attribute '_session_cache'), another exception occurred: File "/home/company/.venv/project/lib/python3.8/site-packages/django/core/handlers/exception.py", line 47, in inner response = get_response(request) File "./dist/terminals/middleware.py", line 11, in __call__ user._serial_number = request.session.get(SESSION_SERIAL_NUMBER, '') File "/home/company/.venv/project/lib/python3.8/site-packages/django/contrib/sessions/backends/base.py", line 65, in get return self._session.get(key, default) File "/home/company/.venv/project/lib/python3.8/site-packages/django/contrib/sessions/backends/base.py", line 185, in _get_session self._session_cache = self.load() File "/home/company/.venv/project/lib/python3.8/site-packages/django/contrib/sessions/backends/db.py", line 43, in load s = self._get_session_from_db() File "/home/company/.venv/project/lib/python3.8/site-packages/django/contrib/sessions/backends/db.py", line 32, in _get_session_from_db return self.model.objects.get( File "/home/company/.venv/project/lib/python3.8/site-packages/django/db/models/manager.py", line 85, in manager_method return getattr(self.get_queryset(), name)(*args, **kwargs) File "/home/company/.venv/project/lib/python3.8/site-packages/django/db/models/query.py", line 443, in get raise self.model.MultipleObjectsReturned( During handling of the above exception (get() returned more than one Session -- it returned more than 20!), another exception occurred: File "/home/company/.venv/project/lib/python3.8/site-packages/django/contrib/sessions/backends/base.py", line 180, in _get_session return self._session_cache During handling of the above exception ('SessionStore' object has no attribute '_session_cache'), another exception occurred: File "/home/company/.venv/project/lib/python3.8/site-packages/django/db/utils.py", line 97, in inner return func(*args, **kwargs) The above exception (no results to fetch) was the direct cause of the following exception: File "/home/company/.venv/project/lib/python3.8/site-packages/django/core/handlers/exception.py", line 47, in inner response = get_response(request) File "/home/company/.venv/project/lib/python3.8/site-packages/django/utils/deprecation.py", line 126, in __call__ response = response or self.get_response(request) File "/home/company/.venv/project/lib/python3.8/site-packages/django/core/handlers/exception.py", line 49, in inner response = response_for_exception(request, exc) File "/home/company/.venv/project/lib/python3.8/site-packages/django/core/handlers/exception.py", line 110, in response_for_exception response = handle_uncaught_exception(request, get_resolver(get_urlconf()), sys.exc_info()) File "/home/company/.venv/project/lib/python3.8/site-packages/django/core/handlers/exception.py", line 149, in handle_uncaught_exception return callback(request) File "./core/base/views.py", line 152, in error_500_view response = render(request, "core.base/500.html", context=context) File "/home/company/.venv/project/lib/python3.8/site-packages/django/shortcuts.py", line 19, in render content = loader.render_to_string(template_name, context, request, using=using) File "/home/company/.venv/project/lib/python3.8/site-packages/django/template/loader.py", line 62, in render_to_string return template.render(context, request) File "/home/company/.venv/project/lib/python3.8/site-packages/django/template/backends/django.py", line 61, in render return self.template.render(context) File "/home/company/.venv/project/lib/python3.8/site-packages/django/template/base.py", line 174, in render with context.bind_template(self): File "/usr/lib/python3.8/contextlib.py", line 113, in __enter__ return next(self.gen) File "/home/company/.venv/project/lib/python3.8/site-packages/debug_toolbar/panels/templates/panel.py", line 46, in _request_context_bind_template context = processor(self.request) File "./core/base/context_processors.py", line 13, in project menu = get_plug_menu(request.user) File "./dist/plug/menu.py", line 58, in get_plug_menu if user.is_anonymous or user.is_terminal: File "/home/company/.venv/project/lib/python3.8/site-packages/django/utils/functional.py", line 248, in inner self._setup() File "/home/company/.venv/project/lib/python3.8/site-packages/django/utils/functional.py", line 384, in _setup self._wrapped = self._setupfunc() File "/home/company/.venv/project/lib/python3.8/site-packages/django/contrib/auth/middleware.py", line 25, in <lambda> request.user = SimpleLazyObject(lambda: get_user(request)) File "/home/company/.venv/project/lib/python3.8/site-packages/django/contrib/auth/middleware.py", line 11, in get_user request._cached_user = auth.get_user(request) File "/home/company/.venv/project/lib/python3.8/site-packages/django/contrib/auth/__init__.py", line 177, in get_user user_id = _get_user_session_key(request) File "/home/company/.venv/project/lib/python3.8/site-packages/django/contrib/auth/__init__.py", line 60, in _get_user_session_key return get_user_model()._meta.pk.to_python(request.session[SESSION_KEY]) File "/home/company/.venv/project/lib/python3.8/site-packages/django/contrib/sessions/backends/base.py", line 50, in __getitem__ return self._session[key] File "/home/company/.venv/project/lib/python3.8/site-packages/django/contrib/sessions/backends/base.py", line 185, in _get_session self._session_cache = self.load() File "/home/company/.venv/project/lib/python3.8/site-packages/django/contrib/sessions/backends/db.py", line 43, in load s = self._get_session_from_db() File "/home/company/.venv/project/lib/python3.8/site-packages/django/contrib/sessions/backends/db.py", line 32, in _get_session_from_db return self.model.objects.get( File "/home/company/.venv/project/lib/python3.8/site-packages/django/db/models/manager.py", line 85, in manager_method return getattr(self.get_queryset(), name)(*args, **kwargs) File "/home/company/.venv/project/lib/python3.8/site-packages/django/db/models/query.py", line 435, in get num = len(clone) File "/home/company/.venv/project/lib/python3.8/site-packages/django/db/models/query.py", line 262, in __len__ self._fetch_all() File "/home/company/.venv/project/lib/python3.8/site-packages/django/db/models/query.py", line 1354, in _fetch_all self._result_cache = list(self._iterable_class(self)) File "/home/company/.venv/project/lib/python3.8/site-packages/django/db/models/query.py", line 51, in __iter__ results = compiler.execute_sql(chunked_fetch=self.chunked_fetch, chunk_size=self.chunk_size) File "/home/company/.venv/project/lib/python3.8/site-packages/django/db/models/sql/compiler.py", line 1234, in execute_sql return list(result) File "/home/company/.venv/project/lib/python3.8/site-packages/django/db/models/sql/compiler.py", line 1678, in cursor_iter for rows in iter((lambda: cursor.fetchmany(itersize)), sentinel): File "/home/company/.venv/project/lib/python3.8/site-packages/django/db/models/sql/compiler.py", line 1678, in <lambda> for rows in iter((lambda: cursor.fetchmany(itersize)), sentinel): File "/home/company/.venv/project/lib/python3.8/site-packages/django/db/utils.py", line 97, in inner return func(*args, **kwargs) File "/home/company/.venv/project/lib/python3.8/site-packages/django/db/utils.py", line 90, in __exit__ raise dj_exc_value.with_traceback(traceback) from exc_value File "/home/company/.venv/project/lib/python3.8/site-packages/django/db/utils.py", line 97, in inner return func(*args, **kwargs) Exception Type: ProgrammingError at /accounts/login/ Exception Value: no results to fetch Request information: USER: AnonymousUser
This is the middleware it sits in:
from dist.terminals.apps import SESSION_SERIAL_NUMBER class UserSerialNumberMiddleware: def __init__(self, get_response): self.get_response = get_response # One-time configuration and initialization. def __call__(self, request): user = request.user user._serial_number = request.session.get(SESSION_SERIAL_NUMBER, '') response = self.get_response(request) return response