1

私の Django アプリケーションの各ユーザーは部門に関連付けられており、事実上すべての要求には部門関連の処理が含まれます。したがって、アプリケーション全体で部門オブジェクトを利用できるようにしたいと考えています。

これらのうち、取るべき最も適切なアプローチはどれですか?

  1. request関連する部門を DB から取得し、オブジェクトにrequest.departmentアタッチするカスタムAuthenticationMiddlewareミドルウェアrequest.user。(たとえば、ここここを参照)
  2. ユーザーのログイン時に部門をセッションに配置し、その後 Django のrequest.sessionインターフェースを使用してビューで取得します。

私はまだ Django のキャッシング機能に慣れる機会がありませんでしたが、最終的にはユーザーごとに部門をキャッシュして、リクエストごとに余分な DB ヒットを回避したいと考えています。Django のセッションには、組み込みのキャッシング サポートが用意されているようです。また、最初のアプローチでもキャッシングを実装できると思います。

このような場合、カスタム ミドルウェア (上記の #1) よりもセッション (上記の #2) を使用する利点はありますか? ミドルウェアのアプローチは、内部 API の観点からはよりクリーンに見えますが、これはまさにセッションが設計されている種類のものであると推測しています。

ご指導ありがとうございます。

4

1 に答える 1

1

基本的に、両方のアプローチは非常に似ています。request.sessionこのアプローチでは、ミドルウェアでキャッシングを手動で設定することで余分な手順を省くことができます。セッション アプローチの悪い点は、すぐに使用できるキャッシュ ストレージを使用すると、データが利用可能であることが保証されないことです。たとえば、Cookie が無効になっているユーザーが 0.1% いる場合、memcache ストレージを使用している場合、再デプロイ時に memcache サーバーを再起動する必要があり、ログインしているユーザーのデータが失われる可能性があります。重要なデータには、キャッシュ ストレージを備えたセッションを使用します。私のプロジェクトでは、より高度な制御が可能になるため、最初のオプションを使用することを好みます。

view_nameリクエストに変数を追加し、どこに何を表示するかを制御できるようにする特別なミドルウェアを設定できます。

class NameMiddleware(object):
    def process_view(self, request, view_func, view_args, view_kwargs):
        # add current view
        if isinstance(view_func, str):
            request.view_name = view_func
        elif hasattr(view_func, '__name__'):
            request.view_name = view_func.__name__

次に、リクエストに追加情報を提供する場所をより詳細に制御できます。たとえば、context_processors では、部門の情報を選択したビューにのみアタッチし、効率的な方法で結果をキャッシュできます (必要に応じてデータベースにリクエストをプロキシする)。 ):

def department_context_processor(request):
    if hasattr(request, 'view_name'):
        if request.view_name == 'department_view1' or request.view_name == 'department_view2':
            departments = cache.get('department_'+str(request.user), None)
            if departments is None:
                departments = Department.objects.filter(user=request.user)
                cache.set('department_'+str(request.user), departments, 60*60)
            if departments:
                return {
                    'departments': departments
                }
    return {}
于 2014-01-02T21:00:05.687 に答える