bugfix> python > 投稿

ログインしたユーザーがアプリケーションの特定のセクションにアクセスできることを確認するために、カスタム認証を追加しています。きれいではありませんが、動作します:

view_permissions = {
    'admin_list': {
        'school':{'userrole':['S','A'], 'usertype':[]},
        'class':{'userrole':['S','A'], 'usertype':[]},
        ' ... '
    },
    'delete_object': { ... },
    'edit_object': { ... },
    }
}
def check_permissions(request, viewname, objecttype):
    if(request.user.userrole in view_permissions[viewname][objecttype]['userrole'] or 
       request.user.usertype in view_permissions[viewname][objecttype]['usertype']
    ):
        return True
    else:
        return False
def delete_object(request, objecttype, objectid):
    # Redirect to home page if not authorized
    if(not check_permissions(request, 'delete_object', objecttype)):
        return redirect('wakemeup:index')
    # Otherwise, continue processing
    myobject.delete()
    ...
    return admin_list(request, objecttype)

私がしたいのは、 redirect を移動することです check_permissions の中にいる関数、このようなもの:

def check_permissions(request, viewname, objecttype):
    if( <check permissions are valid> ):
        pass # Authorized: Do nothing and continue with caller view logic
    else:
        return redirect('wakemeup:index') # Unauthorized: redirect to home
def delete_object(request, objecttype, objectid):
    # Redirect to home page if not authorized
    check_permissions(request, 'delete_object', objecttype))

問題は、 check_permissions 内のリダイレクト関数は何もしません。 return を追加した場合にのみリダイレクトします呼び出しロジックへ:

def delete_object(request, objecttype, objectid):
    # Redirect to home page if not authorized
    return check_permissions(request, 'delete_object', objecttype))

ネストされた関数呼び出しが出力を元の呼び出し元に返すことに関係していると思います。しかし、リダイレクトを check_permissions 内から動作させる簡単な方法はありますか関数?

編集

更新された機能- request にアクセスする必要がありますargs [0]経由でオブジェクト、しかし kwargs 経由で他の変数にアクセスできます 。フォームでは、リクエストオブジェクトは引数としてではなく、単にカバーの下に渡されるためだと思います。

def check_perm(view):
    viewname = view.__name__
    def view_wrapper(*args, **kwargs):
        objecttype = kwargs['objecttype']
        myuser = args[0].user
        if not (
            myuser.userrole in view_permissions[viewname][objecttype]['userrole'] or 
            myuser.usertype in view_permissions[viewname][objecttype]['usertype']
        ):
            # Invalid permission - redirect
            return redirect('wakemeup:index')
        # Valid permission - continue
        return view(*args, **kwargs)
    return view_wrapper
...
@check_perm
def delete_object(request, objecttype, objectid):
  ...

回答 1 件
  • 関数デコレータはこの問題の完璧な解決策だと思います。以下を使用すると、条件(アクセス許可)を確認し、必要に応じてリダイレクトで応答をハイジャックし、そうでない場合は通常のビュー応答を続行できます。

    from django.shortcuts import redirect
    def check_permissions(view):
        view_name = view.__name__
        def view_wrapper(*args, **kwargs):
            # Check permissions here.
            if False or False or True:
                # Hijack response with a redirect if conditions not met.
                return redirect('wakemeup:index')
            # Conditions met, continue with normal response.
            return view(*args, **kwargs)
        return view_wrapper
    @check_permissions
    def delete_object(request, object_type, object_id):
        # Your normal view...
        return
    
    

    また、ビュー名をキャプチャする方法にも注意してください。私の意見でははるかに動的です。

あなたの答え