You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
42 lines
1.2 KiB
42 lines
1.2 KiB
from functools import wraps |
|
|
|
from django.utils.decorators import classonlymethod |
|
from rest_framework.viewsets import ViewSetMixin |
|
|
|
try: |
|
from django_scopes import scope |
|
except ImportError: |
|
from xenua.decorators import no_op as scope |
|
|
|
try: |
|
from rest_framework import APIView |
|
except ImportError: |
|
APIView = None |
|
|
|
|
|
class ScopedViewMixin: |
|
def dispatch(self, request, *args, **kwargs): |
|
for method_name in self.http_method_names: |
|
if (method := getattr(self, method_name, None)) is not None: |
|
wrapped_method = wraps(method)(self.apply_scopes(method, method_name)) |
|
setattr(self, method_name, wrapped_method) |
|
|
|
return super().dispatch(request, *args, **kwargs) |
|
|
|
def apply_scopes(self, to: callable, http_method): |
|
def wrapper(request, *args, **kwargs): |
|
with scope(**self.get_scopes(request, *args, **kwargs)): |
|
return to(request, *args, **kwargs) |
|
|
|
return wrapper |
|
|
|
def get_scopes(self, request, *args, **kwargs): |
|
return {} |
|
|
|
|
|
class UserScopedViewMixin(ScopedViewMixin): |
|
user_scope_name = 'user' |
|
|
|
def get_scopes(self, r, *args, **kwargs): |
|
return {self.user_scope_name: r.user} |
|
|
|
|