[Answered ]-Set variable to an expired session out of a view in Django

1👍

You can’t do that on expired sessions. Django does not allow you.

But here is a hack:

class Command(BaseCommand):
    help = "My custom command."

    def handle(self, *args, **options):
        future = datetime.datetime(datetime.MAXYEAR, 1, 1)
        for s in Session.objects.all():
            ed = s.expire_date
            s.expire_date = future
            s.save()
            ss = SessionStore(session_key=s.session_key)
            ss['my_variable'] = None
            ss.save()
            updated_session = Session.objects.get(session_key=s.session_key)
            updated_session.expire_date = ed
            updated_session.save()

0👍

Try this:

from django.contrib.sessions.models import Session

class Command(BaseCommand):
    help = "My custom command."

    def handle(self, *args, **options):
        store_cls = Session.get_session_store_class()
        for session in Session.objects.all():
            s = store_cls(session.session_key)
            s['my_variable'] = None
            # so that any subsequent code which reads from the session sees your change
            s.save()

The code is loading saved session data from the db, but as Session model instances.

These are not the same as the session objects you get back from the SessionStore in the code shown at https://docs.djangoproject.com/en/4.2/topics/http/sessions/#using-sessions-out-of-views

We actually don’t really want to deal with Session model instances at all, what we need is the session_key from the instance, so that we can instantiate the session store.

We can then update the value in session object via __setitem__ and save it back into the db https://github.com/django/django/blob/main/django/contrib/sessions/backends/db.py#L73 (until we do that our change won’t be visible to any other code that tries to read the session data).

Since we only need the session_key we can amend the code above:

from django.contrib.sessions.models import Session

class Command(BaseCommand):
    help = "My custom command."

    def handle(self, *args, **options):
        store_cls = Session.get_session_store_class()
        for session_key in Session.objects.values_list("session_key", flat=True):
            s = store_cls(session_key)
            s['my_variable'] = None
            # so that any subsequent code which reads from the session sees your change
            s.save()

Leave a comment