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, ...):
    ...
Вернуться на верх