Ausgabe
Ich muss abgelaufene Sitzungen aus der Datenbank löschen.
Ähnliche Stack Overflow-Threads scheinen vorzuschlagen, eine geplante Aufgabe (Cron, Sellerie usw.) einzuführen, um abgelaufene Sitzungen zu überprüfen und sie zu löschen.
Ich möchte jedoch vermeiden, für solch einfache Aufgaben einen schweren Stapel einzuführen, und suche nach einer “nativen” Möglichkeit, eine Sitzung aus einer Datenbank zu löschen, SOBALD sie abläuft.
Ich habe also ein pre_delete
Signal für das Session
Modell gesetzt, das das Löschen auslöst, wenn die Instanz des Modells abgelaufen ist. Aber es bleibt noch ein Schritt: Ich brauche Django, um delete
auf der Instanz ausgeführt zu werden, sobald es abläuft.
Idealerweise bräuchte ich eine Methode wie
request.session.on_expiry(some_function_that_deletes_a_session_from_db)
.
Gibt es eine Möglichkeit, dies zu tun?
Lösung
Ich habe also ein
pre_delete
Signal für dasSession
Modell gesetzt, das das Löschen auslöst, wenn die Instanz des Modells abgelaufen ist. Aber es bleibt noch ein Schritt: Ich brauche Django, um delete auf der Instanz auszuführen, sobald sie abläuft.
Ich verfolge nicht wirklich, welchen Unterschied das macht. Wenn das pre_delete
Signal ausgelöst wird, bedeutet dies, dass Django das Objekt löscht Session
, sodass das Löschen des Objekts im pre_delete
Signal nur dann zu einem Fehler führen kann, wenn ich es verstehe. Außerdem sind Signale nützlich, aber es gibt mehrere Möglichkeiten, Signale durch ORM-Aufrufe zu “umgehen”. Daher sollten Signale normalerweise nur verwendet werden, wenn alle Stricke reißen.
Beim Bereinigen abgelaufener Sitzungen werden die Entfernungen in großen Mengen durchgeführt, und normalerweise wird die Abfrage nicht ausgeführt. Daher ist es möglicherweise besser, einfach einen Verwaltungsbefehl zu schreiben, der regelmäßig überprüft, welche Daten zu einer Sitzung gehören, die nicht mehr existiert.
Idealerweise bräuchte ich eine Methode wie
request.session.on_expiry(some_function_that_deletes_a_session_from_db).
Das Django-Framework sucht nicht “aktiv” nach dem Ablauf einer Sitzung, es prüft einfach, ob die Sitzung abgelaufen ist, wenn es diese Sitzung benötigt. Es gibt keine Trigger beim Ablaufen.
Sie könnten solche Trigger selbst implementieren, indem Sie beispielsweise jedes Mal, wenn eine Sitzung erstellt/aktualisiert wird, eine Art asynchrone Funktion hinzufügen, die ausgeführt wird, wenn das Ablaufdatum erreicht ist. Aber das würde zu viel Buchhaltung führen, und außerdem, wenn der Server neu gestartet wird und Sie diese Funktionen nicht dauerhaft implementiert haben, werden diese Trigger nicht mehr existieren.
Tatsächlich müssen Sie gar keinen schweren Stapel einführen, er ist bereits da. Tatsächlich: Django hat eine request.session.clear_expired
[Django-doc] -Funktion, die Sie aufrufen können, um abgelaufene Sitzungen zu löschen. Darüber hinaus hat es eine clearsessions
Methode konstruiert, die ein Verwaltungsbefehl ist. Wenn Sie also die django.contrib.sessions
App aktiviert haben, gibt es einen Verwaltungsbefehl namens clearsessions
[Django-doc] , den Sie ausführen können:
manage.py clearsessions
Außerdem ist es in der Regel besser, Sitzungen in großen Mengen zu entfernen, als diese einzeln zu löschen, da die Belastung der Datenbank geringer ist. Sie können diesen Befehl häufig ausführen, wenn Sie die Anzahl der abgelaufenen Sitzungen reduzieren möchten.
Sie können ganz einfach einen benutzerdefinierten Verwaltungsbefehl [Django-doc] schreiben . Dies ist robuster, da ein Server, wenn er neu startet, immer noch aktiv nach solchen Dateien suchen kann, es auch einfach ist, zu konfigurieren, wie oft er ausgeführt wird, und außerdem könnte es effizienter sein, dies in großen Mengen zu tun.
Beantwortet von – Willem Van Onsem
Antwort geprüft von – David Marino (FixError Volunteer)