Как требовать входа в систему для общих представлений Django?


87

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

Что касается моих представлений, я знаю, что 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'}),
    )

Базовые представления на основе функций устарели в Django 1.4 и были удалены в Django 1.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'))
Saisiva A,

101

Django 1.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-braces 1.4.x по-прежнему поддерживает Django 1.4, поэтому вы можете использовать его с довольно старыми версиями.

Старые методы

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

Это описано в разделе документации по украшению представлений на основе классов . Есть 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)

Дополнительную информацию см. В документации по ссылке выше.


КЛАССНО! но я сделал простой класс только с def dispatchметодом в качестве подкласса View. Теперь я могу просто class ProtectedTemplateView(TemplateView, ProtectedView): pass
написать

если я не буду устанавливать login_url, но установлю это в settings.py, будет ли он перенаправлен на это по умолчанию?
Марат Мхитарян

38

В версии 1.3 Django общие представления изменились с функций на объекты. Таким образом, есть небольшое изменение, необходимое для ответов Уилла МакКатчена и Уилла Харди для работы с версией 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

12

Если вы не хотите писать свою собственную тонкую оболочку вокруг рассматриваемых общих представлений (как предложил Аамир), вы также можете сделать что-то вроде этого в своем 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

3

В Django => 3.0 это сделать довольно просто:

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

@method_decorator(login_required(login_url='/login/'), name='dispatch')
class ProtectedView(TemplateView):
    template_name = 'secret.html'

для справки: https://docs.djangoproject.com/en/3.0/topics/class-based-views/intro/#decorating-the-class


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);
            }
        )
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.