26

データベースにいくつかのものを保存したいのですが、現在のセッションを外部キーとして使用しています: 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 辞書に依存し、少なくとも並べ替えなどのデータベースと同じくらい効率的です)。


しかし、私は一緒に暮らすことができるより良い解決策が欲しい. この問題に対して一般的に使用されている、または適切な解決策はありますか? または、モデルでセッションを適切に参照していますか?

ご協力ありがとうございました。

4

2 に答える 2

58

request.session一意の session_key を持つSessionStore オブジェクトです。

session_key は、属性がアクセスされるとすぐに作成されます。ただし、セッション オブジェクト自体は、SessionStore オブジェクトの save メソッドを呼び出すことによって (セッション ミドルウェアの process_response メソッドで) ビューが処理された後にのみ、データベースに保存されます。

実際には文書化されていませんが、ソースコードを見ると、次のような新しいセッションオブジェクトを作成することになっていると思います:

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 をサポートしていない場合、このアプローチはリクエストごとに新しいセッション オブジェクトを生成します ...

于 2011-02-27T04:19:54.963 に答える