Django: Пользовательский декоратор для проверки свойств модели
У меня есть проект Django, в котором есть модель Project, имеющая свойство ManyToMany auhtorized_users, которое использует встроенный объект User:
authorized_users = models.ManyToManyField(User, related_name='auhtorized_users')
Теперь для каждого представления я добавил декоратор login_required для проверки того, зарегистрирован ли пользователь.
@login_required(redirect_field_name=None)
def viewproject(request, project_id):
project = get_object_or_404(Project, pk=project_id)
...
До этого момента все работало отлично. Все представления могут просматривать только авторизованные пользователи. Теперь я хочу добавить еще один тест, чтобы проверить, входит ли текущий пользователь в список авторизованных пользователей проекта, если нет, то выдать ему PermissionDenied. Для этого я решил использовать пользовательский декоратор для проверки авторизации пользователя. Я создал следующий пользовательский декоратор:
def request_passes_test(test_func, login_url=None):
def decorator(view_func):
@wraps(view_func)
def _wrapped_view(request, *args, **kwargs):
if test_func(request):
return view_func(request, *args, **kwargs)
else:
if login_url:
return redirect(login_url)
else:
raise PermissionDenied()
return _wrapped_view
return decorator
И я добавил этот новый декоратор к представлению для проверки авторизации пользователя:
@login_required(redirect_field_name=None)
@request_passes_test(user_authorization_check)
def viewproject(request, project_id):
...
Этот пользовательский декоратор похож на встроенный user_passes_test, за исключением того, что он принимает объект request вместо requst.user. (Узнал об этом из https://stackoverflow.com/a/11872933/798953). Теперь, в моем user_authorization_check коде, я испытываю трудности, пытаясь понять, как получить project_id параметр представления, чтобы я мог получить модель проекта из базы данных и проверить, является ли текущий пользователь частью авторизованных пользователей
Этот псевдокод у меня на уме:
def user_authorization_check(request, project_id):
# get project
p = get_object_or_404(Project, pk=project_id)
# Perform test
approved = p.authorized_users.filter(username=request.user.username)
return (approved.count() > 0)
Как мне реализовать эту идею? Мне нужно передать project_id параметр из представления в код декоратора user_authorization_check, я не могу понять, как это сделать.
ТИА