Как потребовать логин для Django Generic Views? - PullRequest
73 голосов
/ 26 января 2010

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

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

Ответы [ 9 ]

95 голосов
/ 26 января 2010

Для Django <1.5 вы можете добавить декоратор, поместив функцию в ваши URL, которая позволяет вам обернуть общие представления: </p>

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'))
80 голосов
/ 05 февраля 2013

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, вы можете использовать почти тот же миксин из django-braces - версия Django была основана на версии django-braces. django-braces 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)

Подробнее см. В документации, указанной выше.

36 голосов
/ 05 мая 2011

Общие представления изменены с функций на объекты с версией 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'))),
)

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

12 голосов
/ 26 января 2010

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

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

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

LOGIN_URL="/login/"

в ваших views.py

from django.contrib.auth.mixins import LoginRequiredMixin

class RestaurantLocationCreateView(LoginRequiredMixin,CreateView):
    ....
5 голосов
/ 13 февраля 2018

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

@method_decorator(login_required, name='dispatch')
class YourGenericViewSubclass(TemplateView):
    #
    # View methods
    #
3 голосов
/ 24 мая 2012

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

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
2 голосов
/ 26 января 2010

Используйте следующее:

from django.contrib.auth.decorators import login_required

@login_required
def your_view():
    # your code here
0 голосов
/ 21 августа 2018

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

// 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);
            }
        )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...