web-dev-qa-db-ja.com

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辞書-数百のエントリ-少なくとも同じくらい効率的です)に依存しますソートなどのデータベースとして。)


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

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

20
Jon Cox

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

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

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

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() 

(もちろん、settings.py内のSESSION_ENGINEを介して新しいセッションミドルウェアを参照する必要があります)

ただし、注意してください。このアプローチでは、ユーザーのブラウザがCookieをサポートしていない場合、リクエストごとに新しいセッションオブジェクトが生成されます...

45
codecraft

セッションを破棄したい場合は、最初にDjango Shellを使用することをお勧めします。

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

最後のクエリでは、必要に応じてフィルタリングできます。クエリをヒット

0
Himanshu