wake-up-neo.net

Wie benötige ich ein Login für Django Generic Views?

Ich möchte den Zugriff auf URLs beschränken, die von Django Generic Views verwaltet werden.

Für meine Ansichten weiß ich, dass login_required decorator den Job erledigt . Generische Ansichten erstellen/löschen/aktualisieren nimmt jedoch das login_required-Argument, aber ich konnte keinen Weg finden, dies für andere generische Ansichten zu tun.

68
hamdiakoguz

Bei Django <1.5 können Sie einen Dekorator hinzufügen, indem Sie die Funktion in Ihre URLs einschließen, wodurch Sie die generischen Ansichten einschließen können:

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'}),
    )

Die funktionsbasierten generischen Ansichten werden in Django 1.4 nicht mehr unterstützt und wurden in Django 1.5 entfernt. Es gilt jedoch das gleiche Prinzip, die Ansichtsfunktion der klassenbasierten Ansicht mit dem login_required-Dekorator zu umschließen:

login_required(TemplateView.as_view(template_name='foo_index.html'))
94
Will Hardy

Django 1.9 oder mit Django-Klammern

Django 1.9 hat ein LoginRequiredMixin eingeführt, das folgendermaßen verwendet wird:

from Django.contrib.auth.mixins import LoginRequiredMixin

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

Wenn Sie eine ältere Version von Django verwenden, können Sie ziemlich dieselbe Mischung aus Django-Klammern verwenden - Die Django-Version basierte auf der Django-Klammerversion. Django-Braces 1.4.x unterstützt noch Django 1.4 , so dass Sie es mit ziemlich alten Versionen verwenden können.

Ältere Methoden

Ich habe diese Frage beim googeln gefunden, wie man klassenbasierte Ansichten dekoriert, um die Antwort darauf hinzuzufügen:

Dies wird in den Dokumentationsabschnitten über dekorative Klassenansichten behandelt. Es gibt den Wrapper urls.py oder Sie können den Dekorator auf die dispatch()-Methode anwenden. Beispiele aus der Dokumentation:

Dekorieren in URL-Konf

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())),
)

Die Klasse dekorieren

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)

Weitere Informationen finden Sie in der Dokumentation, auf die oben verwiesen wurde.

75
Hamish Downer

Die generischen Ansichten haben sich mit Version 1.3 von Django von Funktionen zu Objekten geändert. Daher ist für Will McCutchen und Will Hardy eine leichte Änderung erforderlich, um mit Version 1.3 zu arbeiten:

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'))),
)

Auch die Dokumentation beschreibt, wie das geht.

35
Brian Fisher

Wenn Sie keinen eigenen dünnen Wrapper für die fraglichen generischen Ansichten schreiben möchten (wie Aamir vorgeschlagen hat), können Sie auch Folgendes in Ihrer urls.py-Datei tun:

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
)
12
Will McCutchen

Für Django 1.11 können Sie LoginRequiredMixin für klassenbasierte Ansichten verwenden

in der Einstellungsdatei sollten Sie hinzufügen

LOGIN_URL="/login/"

in deinen Ansichten.py

from Django.contrib.auth.mixins import LoginRequiredMixin

class RestaurantLocationCreateView(LoginRequiredMixin,CreateView):
    ....
7
Natiq Vahabov

Eine andere Möglichkeit, dies zu erreichen, ist unten. Ich mag es, dass es ziemlich ähnlich ist wie bei funktionsbasierten Ansichten und es ist nicht notwendig, urls.py zu ändern oder dispatch zu überschreiben:

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

Ich wollte eine wiederverwendbare Methode, um auth von vielen Ansichten zu verlangen, die von generischen Ansichten abgeleitet wurden. Ich habe eine Ersetzungsversendefunktion erstellt, die ich meiner Ansichtsklasse genauso hinzufügen kann wie andere Deklarationen.

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

in auth.dispatch erledigen wir die Arbeit:

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
3
Julian

Verwenden Sie folgendes:

from Django.contrib.auth.decorators import login_required

@login_required
def your_view():
    # your code here
1
Aamir Hussain

Folgendes könnte dieses Problem lösen.

// 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);
            }
        )
0
Shuyuan Yu