2

私のアプリはフォーラムのようなものですが、各投稿にはそれを見ることができる人々のグループがあるとしましょう。

SecretPost(Model):
    can_see = myapp.main.models.GroupOfUsers()

これらの投稿へのユーザーのアクセスを制限するビューを作成したいのですが、デコレータを使用したいと思います。これは、他の場所でアクセス制御を処理してきた方法だからです。

SecretPostView(DetailView):
    """Can only be seen by members of its group"""

    @method_decorator(part_of_its_group)
    def dispatch(self, request, *args, **kwargs):
        return super(SecretPostView, self).dispatch(request, *args, **kwargs)

しかし、dispatch()が呼び出されたとき、私はそのオブジェクトについて何も知りません。オブジェクトが既に取得された後にユーザー アクセスを制限する適切な/慣用的な方法はありますか?

4

1 に答える 1

2

selfメソッドデコレーター内にアクセスできるため、現在のオブジェクト呼び出しにアクセスできますself.get_object()

とにかく、この動作を一般的なビューでのみ使用している場合は、メソッドを実装するdispatch(またはメソッドである可能性があるget_object) ミックスインを作成して、そこでチェックを行う方がよいでしょう。あなたのグループは定義されています、おそらくあなたは django.contrib.auth グループを使用しています):

class GroupRestrictionMixin(object):
    group_field = 'group'

    def dispatch(request, *args, **kwargs):
        self.request = request
        self.args = args
        self.kwargs = kwargs

        obj_group = getattr(self.get_object(), self.group_field)
        user_groups = request.user.groups

        if obj_group not in user_groups:
            raise PermissionDenied

        return super(GroupRestrictionMixin, self).dispatch(request, *args, **kwargs)

次に、ミックスインを使用して、その動作が必要なビューを作成できます。

class SecretPostView(GroupRestrictionMixin, DetailView):
    pass

それがあなたが「慣用的」と呼ぶものであるかどうかはわかりませんが、それはそれをシンプルで再利用可能に保つための最も簡単な方法です。

編集:メソッドがそれらにアクセスできるように、リクエスト、引数、およびkwargsをここに設定する必要がありget_objectます。少し醜くなります(ベースdispatchメソッドにあるコードを繰り返す必要があります)が、それでも機能します:F

于 2013-03-03T02:58:03.393 に答える