Я использую приведенное ниже, чтобы убедиться, что у пользователя есть настраиваемое разрешение, прежде чем разрешить им запускать представление. однако я хотел бы добавить несколько условий, т.е. пользователь has_perm sites.can_view_mgmt или sites.can_view_finanical
@user_passes_test(lambda u: u.has_perm('sites.can_view_mgmt'))
возможно ли пройти тест или пройти тест?
Спасибо
вы хотите написать функцию для передачи в @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)
дело в том, что это должно вызвать ошибку. извините, мой псевдокод не идеален, на самом деле вы должны утверждать и перехватывать исключения. Если вы поймали исключение, верните False
, в противном случае верните True
Если необходимо выполнить хотя бы один условий, вы можете использовать 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
Спасибо, это то, что мне нужно
Это просто и легко понять. Спасибо.
Для правильного способа и другой пользовательской проверки разрешений сделайте так, как указано выше в @ 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
Но разве это не вызовет ошибку в
user_test
? Если я правильно понимаю, тест должен возвращатьTrue
илиFalse
.