Django Generic Views에서 처리하는 URL에 대한 액세스를 제한하고 싶습니다.
내 뷰의 경우 login_required
데코레이터 가 작업을 수행 한다는 것을 알고 있습니다. 또한 Generic View 생성 / 삭제 / 업데이트가 login_required
인수를 취 했지만 다른 Generic View에 대해이 작업을 수행하는 방법을 찾을 수 없습니다.
Django Generic Views에서 처리하는 URL에 대한 액세스를 제한하고 싶습니다.
내 뷰의 경우 login_required
데코레이터 가 작업을 수행 한다는 것을 알고 있습니다. 또한 Generic View 생성 / 삭제 / 업데이트가 login_required
인수를 취 했지만 다른 Generic View에 대해이 작업을 수행하는 방법을 찾을 수 없습니다.
답변:
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'))
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()
방법. 문서의 예 :
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
일반 뷰는 Django 1.3 버전에서 함수에서 객체로 변경되었습니다. 따라서 Will McCutchen 및 Will Hardy 답변이 버전 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'))),
)
또한 문서 에는이를 수행하는 방법도 설명되어 있습니다.
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
)
django 1.11의 경우 클래스 기반 뷰에 LoginRequiredMixin을 사용할 수 있습니다.
설정 파일에 추가해야합니다.
LOGIN_URL="/login/"
views.py에서
from django.contrib.auth.mixins import LoginRequiredMixin
class RestaurantLocationCreateView(LoginRequiredMixin,CreateView):
....
이를 달성하는 또 다른 방법은 다음과 같습니다. 함수 기반 뷰로 수행하는 방법과 매우 유사하며 수정 urls.py
하거나 재정의 할 필요가 없습니다 dispatch
.
@method_decorator(login_required, name='dispatch')
class YourGenericViewSubclass(TemplateView):
#
# View methods
#
일반 뷰에서 파생 된 많은 뷰에 대한 인증을 요구하는 재사용 가능한 방법을 원했습니다. 다른 선언과 같은 방식으로 뷰 클래스에 추가 할 수있는 대체 디스패치 함수를 만들었습니다.
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
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
다음은이 문제를 해결할 수 있습니다.
// 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);
}
)