3

デコレータは正常に動作していますが、ユーザーが必要なグループのいずれにも属していない場合、エラー メッセージを表示したいと思います (メッセージ フレームワークを使用したい)。デコレータは次のとおりです。

def group_required(*group_names):
    """Requires user membership in at least one of the groups passed in."""
    def in_groups(user):
        if user.is_authenticated():
            if bool(user.groups.filter(name__in=group_names)) or user.is_superuser:
                return True
        return False
    return user_passes_test(in_groups)

次のようなものを使用して呼び出します。

@require_http_methods(['GET'])    
@group_required('supervisor')
def home_view(request):
    return render(request, 'home.html')

このスニペットを使用してメッセージ フレームワークを使用しようとしましたが (これにはリクエストオブジェクトが必要なため)、メッセージ フレームワークミドルウェアがデコレータ内にインストールされていないように見えました。

私はそれが必要とするものは何でも喜んで変更します:)

アップデート:

私が探しているもの:

def group_required(request, *group_names):
    """Requires user membership in at least one of the groups passed in."""
    def in_groups(user):
        if user.is_authenticated():
            if user.groups.filter(name__in=group_names).exists() or user.is_superuser:
                return True
            else:
                # I'm getting:
                # You cannot add messages without installing django.contrib.messages.middleware.MessageMiddleware
                messages.add_message(request, messages.ERROR, 'Group is not allowed')
        return False
    return user_passes_test(in_groups, request)
4

1 に答える 1

1

このユースケースでは、スレッドローカルが本当に必要だとは思いません。通常、スレッドローカルが Django アプリで唯一の方法であると思われる場合、構造化されていないコンテキスト レイヤーが存在する可能性があります。threadlocals と比較すると、複製user_passes_testしてから変更して に渡しrequestたいと思います ( のコードを変更せずに簡単にin_groups渡すことはできませんでした。質問を確認してください: user_passes_test デコレータ呼び出し可能関数で Django 要求オブジェクトを渡す方法.) (多分これのチケット?)requestis_groupuser_passes_test

さらに、bool(user.groups.filter(name__in=group_names))存在を決定する前に項目が DB アダプターと Python インスタンスに取得されるため、DB バックエンドから boolexists()結果user.groups.filter(name__in=group_names).exists()を直接返す方がはるかに効率的です。

于 2013-05-04T17:09:53.157 に答える