Django декоратор, перенаправляющий пользователя на 404, если он заходит на неавторизованную страницу?
Я создал декоратор, используя users_passes_test
, и он отлично работает, но мое требование следующее,
Если пользователь не аутентифицирован:
Затем пользователя нужно перенаправить на страницу входа
Иначе, если пользователь аутентифицирован, но не имеет доступа к странице:
Тогда их нужно перенаправить на 404 страницу
Как модифицировать мой декоратор в соответствии с вышеуказанными потребностями?
from django.contrib.auth.decorators import user_passes_test
from django.contrib.auth import REDIRECT_FIELD_NAME
def is_student(function=None, redirect_field_name=REDIRECT_FIELD_NAME, login_url=None):
actual_decorator = user_passes_test(
lambda u: (u.is_authenticated and u.role == 'student'),
login_url=login_url,
redirect_field_name=redirect_field_name
)
if function:
return actual_decorator(function)
return actual_decorator
Это мой декоратор, помогите пожалуйста
Для простоты можно просто сложить декораторы @login_required и @user_passes_test и затем определить их соответствующие URL перенаправления:
@login_required(login_url='/login/')
@user_passes_test(lambda user: user.role == 'student', login_url='/notfound/')
def my_view(request):
...
Или повторно использовать общий декоратор:
from functools import partial
def is_student(function=None, redirect_field_name=None, login_url=None, notfound_url=None):
if function is None:
# Handle @is_student which translates to is_student(some_view) and @is_student(...) which translates to is_student(...)(some_view). The first will automatically pass the function while the second would call the response of this decorator (the partial function below) and pass the function.
return partial(is_student, redirect_field_name=redirect_field_name, login_url=login_url, notfound_url=notfound_url)
decorators = [
login_required(login_url=login_url),
user_passes_test(lambda user: user.role == 'student', login_url=notfound_url),
]
decorated_func = function
for decorator in reversed(decorators):
decorated_func = decorator(decorated_func)
return decorated_func
@is_student(redirect_field_name="next", login_url="/login/", notfound_url="/notfound/")
def some_view(request, ...):
...