Django: установка сеанса и получение ключа сеанса в том же виде - PullRequest
19 голосов
/ 27 февраля 2011

Я хочу сохранить некоторые вещи в базе данных и использую текущий сеанс в качестве внешнего ключа: из models.py

class Visited(models.Model):
    session = models.ForeignKey(Session)
    page = models.ForeignKey(Page)
    times_visited = models.PositiveIntegerField()
    ip_address = models.IPAddressField()
    date_last_visited = models.DateTimeField()
    def __unicode__(self):
        return u'(%s, %s)' % (str(self.session.session_key), str(self.page.name))

Чтобы создать новую запись для этой модели, я использую следующее для получения текущего сеанса (в views.py):

Session.objects.get(session_key=request.session.session_key)

Однако, если пользователь впервые заходит на сайт и, таким образом, еще не настроен файл cookie, приведенный выше код выдаст ошибку DoesNotExist.


Я знаю, что даже если сейчас есть набор файлов cookie, вы все равно можете устанавливать объекты сеанса. Так что я могу придумать несколько хаков для этой работы, таких как:

  • Установить уникальный идентификатор в качестве объекта сеанса (в дополнение к ключу сеанса)
  • Временно сохранить данные, которые я хочу добавить в базу данных объекта сеанса, и использовать функцию декоратора, чтобы проверить, существует ли он до использования сеанса.
  • Просто используйте объекты сеанса и не храните ничего в базе данных (это было бы технически возможно, но для моей реализации это зависело бы от словарей Python - с несколькими сотнями записей), по крайней мере, таких же эффективных, как база данных для таких вещей, как сортировка.)


Но я бы хотел лучшее решение, с которым я мог бы жить. Есть ли общепринятые или хорошие решения этой проблемы? Или я даже правильно ссылаюсь на сеансы в моей модели?

Спасибо за вашу помощь.

Ответы [ 2 ]

44 голосов
/ 27 февраля 2011

request.session - это объект SessionStore с уникальным ключом сеанса.

Сеансовый ключ создается, как только к атрибуту обращаются. Но сам объект сеанса сохраняется в базе данных только после обработки представления (в методе process_response промежуточного программного обеспечения сеанса) путем вызова метода save объекта SessionStore.

Это на самом деле не задокументировано, но, глядя на исходный код, я предполагаю, что вы должны создать новый объект сеанса, подобный этому:

if not request.session.exists(request.session.session_key):
    request.session.create() 

Вы также можете создать пользовательское промежуточное программное обеспечение сеанса, которое гарантирует, что ваш новый объект сеанса всегда доступен, прежде чем какое-либо из ваших представлений попытается получить к нему доступ:

from django.conf import settings
from django.contrib.sessions.middleware import SessionMiddleware

class CustomSessionMiddleware(SessionMiddleware):
    def process_request(self, request):
        engine = import_module(settings.SESSION_ENGINE)
        session_key = request.COOKIES.get(settings.SESSION_COOKIE_NAME, None)
        request.session = engine.SessionStore(session_key)
        if not request.session.exists(request.session.session_key):
            request.session.create() 

(Конечно, вы должны ссылаться на свое новое промежуточное программное обеспечение сеанса через SESSION_ENGINE внутри вашего settings.py)

Но учтите - этот подход будет генерировать новый объект сеанса для каждого запроса, если браузер пользователя не поддерживает файлы cookie ...

0 голосов
/ 07 июня 2018

Если вы хотите уничтожить сессию, я бы посоветовал лучше использовать оболочку django.

from django.contrib.sessions.models import Session
Session.objects.all() #you see all sessions
Session.objects.all().delete() 

В последнем запросе вы можете фильтровать в соответствии с вашими потребностями.и нажмите на запрос

...