Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Fixed #18978 #420

Closed
wants to merge 7 commits into from

3 participants

@tricoder42

Moved cleanup management command to contrib.sessions.

See https://code.djangoproject.com/ticket/18978

@apollo13
Owner

Hi, the PR isn't mergeable currently and please make sure to address @ptone 's comments on the ticket (tests etc…)

@tricoder42

It's there. Documentation and simple test.

@aaugustin
Owner

Thanks for working on this pull request.

In order to make your work easier to merge, I'm going to split it in two patches, one for ticket 18978 and one for ticket 18194.

The patch for 18978 is probably very close to ready for checkin.

@aaugustin aaugustin closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Oct 3, 2012
  1. @tricoder42
  2. @tricoder42

    Added documentation

    tricoder42 authored
Commits on Oct 25, 2012
  1. @tricoder42

    Merge branch 'master' into 18978

    tricoder42 authored
    Conflicts:
    	docs/releases/1.5.txt
  2. @tricoder42
  3. @tricoder42

    Updated docs for Sessions

    tricoder42 authored
  4. @tricoder42
Commits on Oct 26, 2012
  1. @tricoder42
This page is out of date. Refresh to see the latest.
View
2  django/bin/daily_cleanup.py
@@ -10,4 +10,4 @@
from django.core import management
if __name__ == "__main__":
- management.call_command('cleanup')
+ management.call_command('cleansessions')
View
7 django/contrib/sessions/backends/base.py
@@ -281,3 +281,10 @@ def load(self):
Loads the session data and returns a dictionary.
"""
raise NotImplementedError
+
+ @classmethod
+ def cleanup(cls):
+ """
+ Cleanup the expired sessions.
+ """
+ raise NotImplementedError
View
4 django/contrib/sessions/backends/db.py
@@ -71,6 +71,10 @@ def delete(self, session_key=None):
except Session.DoesNotExist:
pass
+ @classmethod
+ def cleanup(cls):
+ Session.objects.filter(expire_date__lt=timezone.now()).delete()
+ transaction.commit_unless_managed()
# At bottom to avoid circular import
from django.contrib.sessions.models import Session
View
21 django/contrib/sessions/backends/file.py
@@ -142,3 +142,24 @@ def delete(self, session_key=None):
def clean(self):
pass
+
+ @classmethod
+ def cleanup(cls):
+ storage_path = getattr(settings, "SESSION_FILE_PATH", tempfile.gettempdir())
+ file_prefix = settings.SESSION_COOKIE_NAME
+
+ # Get all file sessions stored
+ sessions = [cls(session[len(file_prefix):])
+ for session in os.listdir(storage_path)
+ if session.startswith(file_prefix)]
+
+ for session in sessions:
+ old_key = session.session_key
+ session.load()
+ new_key = session.session_key
+
+ # The key was changed i.e. new session created, so the existing one
+ # was invalid. Lests clean it all up
+ if old_key != new_key:
+ session.delete(old_key)
+ session.delete(new_key)
View
0  django/contrib/sessions/management/__init__.py
No changes.
View
0  django/contrib/sessions/management/commands/__init__.py
No changes.
View
11 django/contrib/sessions/management/commands/cleansessions.py
@@ -0,0 +1,11 @@
+from django.core.management.base import NoArgsCommand
+from django.utils.importlib import import_module
+from django.conf import settings
+
+
+class Command(NoArgsCommand):
+ help = "Clean expired sessions."
+
+ def handle_noargs(self, **options):
+ engine = import_module(settings.SESSION_ENGINE)
+ engine.SessionStore.cleanup()
View
23 django/contrib/sessions/tests.py
@@ -12,6 +12,7 @@
from django.contrib.sessions.backends.signed_cookies import SessionStore as CookieSession
from django.contrib.sessions.models import Session
from django.contrib.sessions.middleware import SessionMiddleware
+from django.core import management
from django.core.cache import DEFAULT_CACHE_ALIAS
from django.core.exceptions import ImproperlyConfigured, SuspiciousOperation
from django.http import HttpResponse
@@ -257,6 +258,7 @@ def test_decode(self):
data = {'a test key': 'a test value'}
encoded = self.session.encode(data)
self.assertEqual(self.session.decode(encoded), data)
+
class DatabaseSessionTests(SessionTestsMixin, TestCase):
@@ -290,6 +292,27 @@ def test_sessionmanager_save(self):
del self.session._session_cache
self.assertEqual(self.session['y'], 2)
+ def test_cleansessions_command(self):
+ """
+ Test cleansessions command for cleaning expired sessions from db.
+ """
+ self.assertFalse(Session.objects.count())
+
+ # One object in the future
+ self.session['foo'] = 'bar'
+ self.session.set_expiry(timezone.now() + timedelta(hours=1))
+ self.session.save()
+
+ # One object in the past
+ self.session._session_key = None
+ self.session.set_expiry(timezone.now() - timedelta(hours=1))
+ self.session.save()
+
+ # Two sessions are in DB before clean...
+ self.assertEqual(2, Session.objects.count())
+ management.call_command('cleansessions')
+ # ... and one expired is deleted.
+ self.assertEqual(1, Session.objects.count())
@override_settings(USE_TZ=True)
class DatabaseSessionWithTimeZoneTests(DatabaseSessionTests):
View
8 django/core/management/commands/cleanup.py
@@ -1,11 +1,9 @@
+from django.core import management
from django.core.management.base import NoArgsCommand
-from django.utils import timezone
+
class Command(NoArgsCommand):
help = "Can be run as a cronjob or directly to clean out old data from the database (only expired sessions at the moment)."
def handle_noargs(self, **options):
- from django.db import transaction
- from django.contrib.sessions.models import Session
- Session.objects.filter(expire_date__lt=timezone.now()).delete()
- transaction.commit_unless_managed()
+ management.call_command('cleansessions', **options)
View
24 docs/ref/django-admin.txt
@@ -1,4 +1,7 @@
=============================
+
+
+..
django-admin.py and manage.py
=============================
@@ -93,8 +96,11 @@ cleanup
.. django-admin:: cleanup
-Can be run as a cronjob or directly to clean out old data from the database
-(only expired sessions at the moment).
+Can be run as a cronjob or directly to clean out old data from the database.
+Right now it only calls :djadmin:`cleansessions` management command from
+``django.contrib.sessions``.
+
+.. versionchanged:: 1.5
compilemessages
---------------
@@ -1199,6 +1205,20 @@ This command is only available if the :doc:`Sitemaps framework
Please refer to its :djadmin:`description <ping_google>` in the Sitemaps
documentation.
+``django.contrib.sessions``
+---------------------------
+
+cleansessions
+~~~~~~~~~~~~~
+
+This command is only available if the :doc:`Sessions </topics/http/sessions>`
+(``django.contrib.sessions``) are installed.
+
+Please refer to its :djadmin:`description <cleansessions>` in the Sessions
+documentation.
+
+.. versionadded:: 1.5
+
``django.contrib.staticfiles``
------------------------------
View
7 docs/releases/1.5.txt
@@ -452,6 +452,13 @@ with the :meth:`~django.forms.Form.is_valid()` method and not with the
presence or absence of the :attr:`~django.forms.Form.cleaned_data` attribute
on the form.
+Cleaned :djadmin:`cleanup` management command
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This command have contained only expired sessions clean up for years.
+Therefore new command :djadmin:`cleansessions` in ``django.contrib.sessions``
+do the job and :djadmin:`cleanup` command just call it.
+
Miscellaneous
~~~~~~~~~~~~~
View
33 docs/topics/http/sessions.txt
@@ -261,6 +261,11 @@ You can edit it multiple times.
Returns either ``True`` or ``False``, depending on whether the user's
session cookie will expire when the user's Web browser is closed.
+ .. method:: SessionBase.cleanup()
+
+ Class method which cleans up expired session (eg. delete related rows
+ in database, files, etc.)
+
Session object guidelines
-------------------------
@@ -460,9 +465,15 @@ table. Django updates this row each time the session data changes. If the user
logs out manually, Django deletes the row. But if the user does *not* log out,
the row never gets deleted.
-Django provides a sample clean-up script: ``django-admin.py cleanup``.
-That script deletes any session in the session table whose ``expire_date`` is
-in the past -- but your application may have different requirements.
+.. versionadded:: 1.5
+
+There is simple clean-up script in ``django-admin.py cleansessions``. That
+script deletes any session in the session table whose ``expire_date`` is in
+the past -- but your application may have different requirements.
+
+Another way is to run ``bin/daily_cleanup.py`` which clean out old data from
+the database. Only ``django-admin.py cleansessions`` command is called at
+the moment.
Settings
========
@@ -576,6 +587,22 @@ that is, if any of its dictionary values have been assigned or deleted.
.. _Django settings: ../settings/
+Management commands
+===================
+
+.. highlight:: console
+
+``django.contrib.sessions`` exposes one management commands.
+
+cleansessions
+-------------
+
+.. django-admin:: cleansessions
+
+Cleans expired sessions from database.
+
+.. versionadded:: 1.5
+
Technical details
=================
Something went wrong with that request. Please try again.