Подтвердить что ты не робот

Django: настройка сеанса и получение сеансового ключа в том же представлении

Я хочу сохранить некоторые вещи в базе данных и использую текущий сеанс как внешний ключ: from 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 - с несколькими сотнями записей - как минимум так же эффективно, как база данных для таких вещей, как сортировка.)


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

Благодарим вас за помощь.

4b9b3361

Ответ 1

request.session представляет собой объект SessionStore с уникальной session_key.

Session_key создается сразу после доступа к атрибуту. Но сам объект сеанса сохраняется только в базе данных после обработки представления (в методе process_response промежуточного программного обеспечения сеанса), вызывая метод сохранения объекта 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_ENIGNE внутри вашего settings.py)

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