Как требовать логин для Django Generic Views?


Я хочу ограничить доступ к URL-адресам, обрабатываемым общими представлениями Django.

для моих взглядов я знаю, что login_required оформителя делает работу. Также создать/удалить / обновить общие представления возьмите login_required аргумент, но я не мог найти способ сделать это для других общих взглядов.

9 67

9 ответов:

для Django

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

общие представления на основе функций устарели в Django 1.4 и были удалены в Django 1.5. Но тот же принцип применяется, просто оберните функцию представления представления на основе класса с помощью login_required оформитель:

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

Django 1.9 или с помощью Django-фигурных скобок

Django 1.9 ввел LoginRequiredMixin это используется таким образом:

from django.contrib.auth.mixins import LoginRequiredMixin

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

если вы используете более старую версию django, вы можете использовать почти тот же mixin от Джанго-скобки - версия Django была основана на версии django-braces. django-брекеты 1.4.x по-прежнему поддерживает Django 1.4 так что вы можете использовать его с довольно старых версий.

старший Методы

Я нашел этот вопрос, когда искал, как украсить представления на основе классов, поэтому добавить ответ на этот вопрос:

это описано в разделе документации на украшения класса на основе представлений. Там есть urls.py обертка, или вы можете применить декоратор к dispatch() метод. Примеры из документации:

украшение в URL conf

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)

посмотреть документация, связанная с выше для получения более подробной информации.

общие представления изменились с функций на объекты с версией 1.3 Django. Таким образом, есть небольшое изменение, необходимое для Will McCutchen и Will Hardy answers для работы с версией 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'))),
)

и документация описывает, как это сделать.

Если вы не хотите писать свою собственную тонкую обертку вокруг общих представлений, о которых идет речь (как предложил Аамир), вы также можете сделать что-то подобное в своем urls.py file:

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
)

для django 1.11 вы можете использовать LoginRequiredMixin для представлений на основе классов

в файле настроек вы должны добавить

LOGIN_URL="/login/"

в вашем views.py

from django.contrib.auth.mixins import LoginRequiredMixin

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

Я хотел, чтобы повторно использовать способ требует проверки подлинности на множество мнений, полученных от родовых представлений. Я создал функцию replacement dispatch, которую я могу добавить в свой класс представления так же, как и другие объявления.

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

auth.отправка-это то, где мы делаем работу:

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

другой способ добиться этого ниже, мне нравится, что это очень похоже на то, как это делается с функциональными представлениями и не требует изменения urls.py или переопределение dispatch:

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

использовать следующий:

from django.contrib.auth.decorators import login_required

@login_required
def your_view():
    # your code here

следующее может решить эту проблему.

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