15

ajax リクエストに応答するいくつかのビューを作成しているときに、login_required デコレーターが認証されていないユーザーに対して常に 302 ステータス コードを返すのは少し奇妙だと思います。これらのビューは ajax ビューであるため、これはやや不適切に思えます。このような場合にユーザーにログインさせたくないのですが、そのようなビューにアクセスするには認証が必要であることをDjangoにクライアントに伝えてもらいたいです(401は正しいステータスコードであると思います)。

これを達成するために、私は独自のデコレータlogin_required_ajaxを書き始めましたが、どういうわけかこれは私のスキルを超えています. これは私がこれまでに思いついたものです:

def login_required_ajax(function=None,redirect_field_name=None):
    """
    Just make sure the user is authenticated to access a certain ajax view

    Otherwise return a HttpResponse 401 - authentication required
    instead of the 302 redirect of the original Django decorator
    """
    def _decorator(view_func):
        def _wrapped_view(request, *args, **kwargs):
            if request.user.is_authenticated():
                return view_func(request, *args, **kwargs)
            else:
                return HttpResponse(status=401)

        if function is None:
            return _decorator
        else:
            return _decorator(function)

ビューでこのデコレータを使用すると、サイトのページにアクセスしようとするとすぐに ViewDoesNotExist 例外が発生します。

応答オブジェクトは呼び出し可能オブジェクトではないため、ユーザーが認証されていない場合に HttpResponse が直接返される可能性があると最初に考えました。しかし、問題のビューにアクセスしようとしない限り、デコレータは機能するはずですよね? そして、これが本当に重要な場合、ステータス コード 401 で HttpResponse を返すデコレータをどのように作成すればよいでしょうか?

4

1 に答える 1

18

That's a pretty good attempt. Here's a couple of problems I spotted:

  1. Your _decorator function should return _wrapped_view.
  2. The indentation for your if function is None block is a bit off -- the login_required_ajax function needs to return the decorated function.

Here's the decorator with those changes made:

def login_required_ajax(function=None,redirect_field_name=None):
    """
    Just make sure the user is authenticated to access a certain ajax view

    Otherwise return a HttpResponse 401 - authentication required
    instead of the 302 redirect of the original Django decorator
    """
    def _decorator(view_func):
        def _wrapped_view(request, *args, **kwargs):
            if request.user.is_authenticated():
                return view_func(request, *args, **kwargs)
            else:
                return HttpResponse(status=401)
        return _wrapped_view

    if function is None:
        return _decorator
    else:
        return _decorator(function)
于 2012-04-05T15:10:14.743 に答える