У меня есть иерархия проверок разрешений и просмотров, которые должны быть защищены ими. Например, рассмотрите эти две проверки.Составляйте декораторы, применяемые к классам.
def has_profile(user):
return user.profile is not None
def is_a_sorcerer(user):
return user.profile.category == 'sorcerer'
Обратите внимание, что это имеет смысл только для вызова is_a_sorcerer
если пользователь имеет профиль.
Некоторые виды должны быть доступны для всех, у кого есть профиль, некоторые виды ограничены только магами.
class ProfileView(View):
@method_decorator(user_passes_test(has_profile))
def dispatch(self, *args, **kwargs):
return super().dispatch(*args, **kwargs)
class SorcererView(ProfileView):
@method_decorator(user_passes_test(is_a_sorcerer))
def dispatch(self, *args, **kwargs):
return super().dispatch(*args, **kwargs)
Однако, обратите внимание, что из-за наследства, is_a_sorcerer
будет называться перед темhas_profile
и без ошибок.
можно проверить has_profile
в is_a_sorcerer
:
def is_a_sorcerer(user):
return has_profile(user) and user.profile.category == 'sorcerer'
В то время как это фиксирует ошибку, это приводит к проверке has_profile
дважды, и более чем в два уровня проверки накладных накапливает быстро.
Как создать эти декораторы без дублирующего кода? Я все равно хотел бы, чтобы проверки разрешений выполнялись как функции, чтобы их можно было применять к представлениям, основанным на функциях.
В чем проблема с этим наследованием? Если у пользователя нет профиля, он не может быть колдуном, не так ли? В реализации 'is_a_sorcerer' вы должны проверить, есть ли' has_profile'. – afilardo
Использование [разрешений] (https://docs.djangoproject.com/en/1.10/topics/auth/customizing/#custom-permissions) не является вариантом? – afilardo
Добавление декоратора 'permission_required' к представлениям не будет отличаться от' user_passes_test', и все равно придется проверять разрешения дважды. – Koterpillar