Django Generic Viewsへのログインを要求するにはどうすればよいですか?


87

Django GenericViewsで処理されるURLへのアクセスを制限したい。

私の見解では、login_requiredデコレータがその役割を果たしていることを知っています。また、ジェネリックビューの作成/削除/更新がlogin_required議論になりますが、他のジェネリックビューに対してこれを行う方法が見つかりませんでした。

回答:


104

Django <1.5の場合、関数をURLでラップすることでデコレータを追加できます。これにより、一般的なビューをラップできます。

from django.contrib.auth.decorators import login_required
from django.views.generic.simple import direct_to_template
urlpatterns = patterns('',
    (r'^foo/$', login_required(direct_to_template), {'template': 'foo_index.html'}),
    )

関数ベースの汎用ビューはDjango1.4で非推奨になり、Django1.5で削除されました。ただし、同じ原則が適用されます。クラスベースのビューのビュー関数をlogin_requiredデコレータでラップするだけです。

login_required(TemplateView.as_view(template_name='foo_index.html'))

ここでlogin_urlを指定する方法login_required(TemplateView.as_view(template_name = 'foo_index.html'))
SaisivaA19年

101

Django1.9またはdjango-bracesの使用

Django 1.9では、次のように使用されるLoginRequiredMixinが導入されました。

from django.contrib.auth.mixins import LoginRequiredMixin

class MyView(LoginRequiredMixin, View):
    login_url = '/login/'
    redirect_field_name = 'redirect_to'

古いバージョンのdjangoを使用している場合は、django-bracesとほぼ同じミックスインを使用できます。Djangoバージョンはdjango -bracesバージョンに基づいていました。 django-braces1.4.xは引き続きDjango1.4をサポートしているため、かなり古いバージョンで使用できます。

古い方法

クラスベースのビューを装飾する方法をグーグルで調べているときにこの質問を見つけたので、その答えを追加します。

これは、クラスベースのビューの装飾に関するドキュメントセクションで説明されていますurls.pyラッパーがありますが、dispatch()メソッドにデコレータを適用することもできます。ドキュメントからの例:

URLconfで飾る

from django.contrib.auth.decorators import login_required, permission_required
from django.views.generic import TemplateView

from .views import VoteView

urlpatterns = patterns('',
    (r'^about/', login_required(TemplateView.as_view(template_name="secret.html"))),
    (r'^vote/', permission_required('polls.can_vote')(VoteView.as_view())),
)

クラスを飾る

from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator
from django.views.generic import TemplateView

class ProtectedView(TemplateView):
    template_name = 'secret.html'

    @method_decorator(login_required)
    def dispatch(self, *args, **kwargs):
        return super(ProtectedView, self).dispatch(*args, **kwargs)

詳細については、上記のリンク先のドキュメントを参照してください。


驚くばかり!しかしdef dispatch、のサブクラスとしてメソッドのみを使用して単純なクラスを作成しましたView。:今、私は単にこのような何か作ることができますclass ProtectedTemplateView(TemplateView, ProtectedView): pass
WBAR

login_urlを設定せず、settings.pyで設定した場合、デフォルトでこれにリダイレクトされますか?
マラームキタリアン

38

Djangoのバージョン1.3では、汎用ビューが関数からオブジェクトに変更されました。そのため、WillMcCutchenとWillHardyの回答がバージョン1.3で動作するためには、わずかな変更が必要です。

from django.contrib.auth.decorators import login_required
from django.views.generic import TemplateView

urlpatterns = patterns('',
    (r'^foo/$', login_required(TemplateView.as_view(template_name='foo_index.html'))),
)

また、ドキュメントにはこれを行う方法も記載されています。


2
読者の皆さん、この答えを考慮に入れてください。時間が経ち、ソフトウェアが進化するからです。最初の解決策は私にはうまくいきませんでした。
n3storm 2012

12

問題の汎用ビューの周りに独自の薄いラッパーを記述したくない場合(Aamirが提案したように)、urls.pyファイルで次のようなことを行うこともできます。

from django.conf.urls.defaults import *

# Directly import whatever generic views you're using and the login_required
# decorator
from django.views.generic.simple import direct_to_template
from django.contrib.auth.decorators import login_required

# In your urlpatterns, wrap the generic view with the decorator
urlpatterns = patterns('',
    (r'', login_required(direct_to_template), {'template': 'index.html'}),
    # etc
)

8

django 1.11の場合、クラスベースのビューにLoginRequiredMixinを使用できます

設定ファイルに追加する必要があります

LOGIN_URL="/login/"

あなたのviews.pyで

from django.contrib.auth.mixins import LoginRequiredMixin

class RestaurantLocationCreateView(LoginRequiredMixin,CreateView):
    ....

8

これを実現する別の方法は以下のとおりです。関数ベースのビューで行われる方法と非常によく似ており、変更urls.pyやオーバーライドを必要としませんdispatch

@method_decorator(login_required, name='dispatch')
class YourGenericViewSubclass(TemplateView):
    #
    # View methods
    #

3

ジェネリックビューから派生した多くのビューで認証を要求する再利用可能な方法が必要でした。他の宣言と同じ方法でビュークラスに追加できる置換ディスパッチ関数を作成しました。

class Index(generic.ListView):
    model = models.HomePage
    dispatch = auth.dispatch

auth.dispatchは、作業を行う場所です。

def dispatch(self, request, *args, **kw):
    """Mix-in for generic views"""
    if userSession(request):
        return  super(self.__class__, self).dispatch(request, *args, **kw)

    # auth failed, return login screen
    response = user(request)
    response.set_cookie('afterauth', value=request.path_info)
    return response


1

以下を使用してください。

from django.contrib.auth.decorators import login_required

@login_required
def your_view():
    # your code here

5
質問の日付に基づいて、OPは関数ベースのビューではなく、djangoのクラスベースのジェネリックビューの解決策を求めていると思います。
ドルフ

0

以下はこの問題を解決する可能性があります。

// in views.py:
class LoginAuthenAJAX(View):
    def dispatch(self, request, *args, **kwargs):
        if request.user.is_authenticated:
            jsonr = json.dumps({'authenticated': True})
        else:
            jsonr = json.dumps({'authenticated': False})
        return HttpResponse(jsonr, content_type='application/json')

// in urls.py
    path('login_auth', views.LoginAuthenAJAX.as_view(), name="user_verify"),

//in xxx.html
<script src = “{% static “xxx/script.js” %}” 
var login_auth_link = “{%  url ‘user_verify’ %}”
</script>

// in script.js
        $.get(login_auth_link, {
            'csrfmiddlewaretoken' : csrf_token,
            },
            function(ret){
                if (ret.authenticated == false) {
                    window.location.pathname="/accounts/login/"
                }
                $("#message").html(ret.result);
            }
        )
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.