3


に関してAuthenticationMiddleware、なぜ Django 1.3userはクラス レベルでプロパティを処理したのですか? また、なぜ 1.4 でインスタンス プロパティに変更されたのですか?


これは1.3から

class LazyUser(object):
    def __get__(self, request, obj_type=None):
        if not hasattr(request, '_cached_user'):
            from django.contrib.auth import get_user
            request._cached_user = get_user(request)
        return request._cached_user


class AuthenticationMiddleware(object):
    def process_request(self, request):
        request.__class__.user = LazyUser()
        return None


そしてこれは1.4から

def get_user(request):
    if not hasattr(request, '_cached_user'):
        request._cached_user = auth.get_user(request)
    return request._cached_user


class AuthenticationMiddleware(object):
    def process_request(self, request):
        assert hasattr(request, 'session'), "The Django authentication middleware requires session middleware to be installed. Edit your MIDDLEWARE_CLASSES setting to insert 'django.contrib.sessions.middleware.SessionMiddleware'."

        request.user = SimpleLazyObject(lambda: get_user(request))
        # SimpleLazyObject inherits from LazyObject


1.3 では、クラス レベル属性にprocess_request割り当てられることを理解しました。これは、基本的に次の 2 つのことを意味します。LazyUser()user

  • HttpRequestクラス ( )は2 つの要求の間でrequest.__class__その属性を保存したため、将来のオブジェクトはそれにアクセスできました。userrequest
  • ビュー関数が にアクセスしようとするたびrequest.userに、LazyUserオブジェクトの__get__メソッドがトリガーされ、リクエストのキャッシュまたは認証ストレージからユーザー オブジェクトが返されました。

私はそれについて正しいですか?

また、1.4 で次の 2 つの大きな変更点があることに気付きました。

  • SimpleLazyObjectクラスではなく に割り当てられrequestます (つまり、インスタンス プロパティです)。
  • LazyObjectSimpleLazyObject独自の__get__メソッドを定義 (カスタマイズ) しないでください。

このように、いつget_userトリガーされますか?2 つのリクエスト間で request.user を保存し、Http のステートレス性をオーバーライドする
方法は?AuthenticationMiddleware

4

1 に答える 1

2

いいえ。2つのバージョンは同等です。ただし、1.4バージョンの方が簡単です。

以前はどのように機能していましたか

LazyUserオブジェクトは記述子プロトコルを実装しました。

記述子は理解するのが少し複雑ですが、ここでの一般的な考え方userは、クラス属性であるにもかかわらず、 request.userwoud呼び出しにアクセスするため、メソッドに要求パラメーターにアクセスrequest.__class__.user.__get__(request)させ、要求にバインドされたユーザーを返すために使用するというものです。__get__

今の仕組み

userプロパティは、SimpeLazyObject同じ目標を達成するために構成を使用します。必要がない場合は、すべてのユーザー機構をロードしないようにします。

いつget_user呼ばれるかについて:

request.userたとえば、の属性にアクセスすると、が呼び出されrequest.user.attr1、次にrequest.user.__getattr__('attr1')が呼び出され、request.user._setup()最終的にはが呼び出されますget_user

Djangoがステートフルネスを作成する方法

セッションの使用を通じて。djangoのセッションミドルウェアをご覧ください。

于 2013-03-02T12:30:55.927 に答える