|
|
|
@ -55,3 +55,40 @@ def hash_auth_view(fn): |
|
|
|
else: |
|
|
|
return HttpResponseForbidden('Access Denied') |
|
|
|
return wrapped |
|
|
|
|
|
|
|
|
|
|
|
# Lazy initialize metaclass |
|
|
|
class LazyInitMetaclass(type): |
|
|
|
""" |
|
|
|
Type this metaclass if you want to make your object with lazy initialize. |
|
|
|
Method __init__ called only when you try to call something method |
|
|
|
from object of your class. |
|
|
|
""" |
|
|
|
def __new__(mcs, name: str, bases: tuple, attrs: dict): |
|
|
|
new_class_new = super(LazyInitMetaclass, mcs).__new__ |
|
|
|
|
|
|
|
def _lazy_call_decorator(fn): |
|
|
|
def wrapped(self, *args, **kwargs): |
|
|
|
if not self._is_initialized: |
|
|
|
self._lazy_init(*self._args, **self._kwargs) |
|
|
|
return fn(self, *args, **kwargs) |
|
|
|
|
|
|
|
return wrapped |
|
|
|
|
|
|
|
# Apply decorator to all public class methods |
|
|
|
new_attrs = {k: _lazy_call_decorator(v) for k, v in attrs.items() if not k.startswith('__') and not k.endswith('__') and callable(v)} |
|
|
|
if new_attrs: |
|
|
|
attrs.update(new_attrs) |
|
|
|
attrs['_is_initialized'] = False |
|
|
|
|
|
|
|
new_class = new_class_new(mcs, name, bases, attrs) |
|
|
|
|
|
|
|
real_init = getattr(new_class, '__init__') |
|
|
|
|
|
|
|
def _lazy_init(self, *args, **kwargs): |
|
|
|
self._args = args |
|
|
|
self._kwargs = kwargs |
|
|
|
setattr(new_class, '__init__', _lazy_init) |
|
|
|
setattr(new_class, '_lazy_init', real_init) |
|
|
|
|
|
|
|
return new_class |