Просмотр django - пользователь проходит тест нескольких условий?

Я использую приведенное ниже, чтобы убедиться, что у пользователя есть настраиваемое разрешение, прежде чем разрешить им запускать представление. однако я хотел бы добавить несколько условий, т.е. пользователь has_perm sites.can_view_mgmt или sites.can_view_finanical

@user_passes_test(lambda u: u.has_perm('sites.can_view_mgmt'))  

возможно ли пройти тест или пройти тест?

Спасибо

4
0
1 394
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

вы хотите написать функцию для передачи в @user_passes_test, которая включает все ваши проверки.

что-то вроде этого:

def user_test(user):
    try: 
        assert user.has_perm
        assert user.next_test
    except AssertionError:
        return False
    return True

и так далее, пока вы не найдете тест, который сломает его или нет, и пользователь не пройдет. Затем вы просто передаете user_test декоратору, и все готово.

@user_passes_test(user_test)

Но разве это не вызовет ошибку в user_test? Если я правильно понимаю, тест должен возвращать True или False.

Willem Van Onsem 10.08.2018 17:49

дело в том, что это должно вызвать ошибку. извините, мой псевдокод не идеален, на самом деле вы должны утверждать и перехватывать исключения. Если вы поймали исключение, верните False, в противном случае верните True

rchurch4 10.08.2018 17:51
Ответ принят как подходящий

ИЛИ-логика

Если необходимо выполнить хотя бы один условий, вы можете использовать or в лямбда-выражении:

@user_passes_test(lambda u: u.has_perm('sites.can_view_mgmt') or u.has_perm('sites.can_view_mgmt'))
def some_view(request):
    # ...
    pass

Если список большой, вы можете использовать функцию any(..):

need_one_of = ['sites.can_view_mgmt', 'sites.can_view_mgmt']

@user_passes_test(lambda u: any(map(u.has_perm, need_one_of)))
def some_view(request):
    # ...
    pass

И-логика

Если необходимо выполнить условия все, вы можете использовать and вместо or. Однако в Django есть функция User.has_perms, которая проверяет, удерживаются ли разрешения все, поэтому:

@user_passes_test(lambda u: u.has_perms(['sites.can_view_mgmt', 'sites.can_view_mgmt']))
def some_view(request):
    # ...
    pass

Или мы можем использовать функцию all(..):

need_all_of = ['sites.can_view_mgmt', 'sites.can_view_mgmt']

@user_passes_test(lambda u: all(map(u.has_perm, need_all_of)))
def some_view(request):
    # ...
    pass

Спасибо, это то, что мне нужно

AlexW 10.08.2018 17:47

Это просто и легко понять. Спасибо.

Hmatrix 26.05.2020 00:37

Для правильного способа и другой пользовательской проверки разрешений сделайте так, как указано выше в @ rchurch4. но изменить так:

def user_test(user):
if user.has_perm: 
    return True
else:
    redirect(<login_page>) OR
    redirect(<custom_error_page>)

Также я использовал аналогичную логику, если вам больше нравится:

def management_required(function=None, redirect_field_name=REDIRECT_FIELD_NAME, 
login_url='home:home'):

actual_decorator = user_passes_test(
    lambda u: u.user_role == 2,
    login_url=login_url,
    redirect_field_name=redirect_field_name
)
if function:
    return actual_decorator(function)
return actual_decorator

И чем просто выставить на обозрение:

@manangement_required
def view_home(request):
  pass

Другие вопросы по теме