fix: 修复授权树一些问题

This commit is contained in:
xinwen
2021-02-25 14:45:21 +08:00
committed by 老广
parent 5de5fa2e96
commit 1036d1c132
13 changed files with 214 additions and 182 deletions

View File

@@ -10,8 +10,11 @@
"""
import uuid
from functools import reduce, partial
import inspect
from django.db.models import *
from django.db.models import QuerySet
from django.db.models.functions import Concat
from django.utils.translation import ugettext_lazy as _
@@ -86,3 +89,84 @@ def concated_display(name1, name2):
def output_as_string(field_name):
return ExpressionWrapper(F(field_name), output_field=CharField())
class UnionQuerySet(QuerySet):
after_union = ['order_by']
not_return_qs = [
'query', 'get', 'create', 'get_or_create',
'update_or_create', 'bulk_create', 'count',
'latest', 'earliest', 'first', 'last', 'aggregate',
'exists', 'update', 'delete', 'as_manager', 'explain',
]
def __init__(self, *queryset_list):
self.queryset_list = queryset_list
self.after_union_items = []
self.before_union_items = []
def __execute(self):
queryset_list = []
for qs in self.queryset_list:
for attr, args, kwargs in self.before_union_items:
qs = getattr(qs, attr)(*args, **kwargs)
queryset_list.append(qs)
union_qs = reduce(lambda x, y: x.union(y), queryset_list)
for attr, args, kwargs in self.after_union_items:
union_qs = getattr(union_qs, attr)(*args, **kwargs)
return union_qs
def __before_union_perform(self, item, *args, **kwargs):
self.before_union_items.append((item, args, kwargs))
return self.__clone(*self.queryset_list)
def __after_union_perform(self, item, *args, **kwargs):
self.after_union_items.append((item, args, kwargs))
return self.__clone(*self.queryset_list)
def __clone(self, *queryset_list):
uqs = UnionQuerySet(*queryset_list)
uqs.after_union_items = self.after_union_items
uqs.before_union_items = self.before_union_items
return uqs
def __getattribute__(self, item):
if item.startswith('__') or item in UnionQuerySet.__dict__ or item in [
'queryset_list', 'after_union_items', 'before_union_items'
]:
return object.__getattribute__(self, item)
if item in UnionQuerySet.not_return_qs:
return getattr(self.__execute(), item)
origin_item = object.__getattribute__(self, 'queryset_list')[0]
origin_attr = getattr(origin_item, item, None)
if not inspect.ismethod(origin_attr):
return getattr(self.__execute(), item)
if item in UnionQuerySet.after_union:
attr = partial(self.__after_union_perform, item)
else:
attr = partial(self.__before_union_perform, item)
return attr
def __getitem__(self, item):
return self.__execute()[item]
def __iter__(self):
return iter(self.__execute())
def __str__(self):
return str(self.__execute())
def __repr__(self):
return repr(self.__execute())
@classmethod
def test_it(cls):
from assets.models import Asset
assets1 = Asset.objects.filter(hostname__startswith='a')
assets2 = Asset.objects.filter(hostname__startswith='b')
qs = cls(assets1, assets2)
return qs

View File

@@ -277,7 +277,3 @@ def bulk_get(d, *keys, default=None):
for key in keys:
values.append(d.get(key, default))
return values
def isinstance_method(attr):
return isinstance(attr, type(Time().time))

View File

@@ -93,21 +93,21 @@ class DistributedLock(RedisLock):
if self.locked_by_current_thread():
self._acquired_reentrant_lock = True
logger.debug(
f'I[{self.id}] reentry lock[{self.name}] in thread[{self._thread_id}].')
f'Reentry lock ok: lock_id={self.id} owner_id={self.get_owner_id()} lock={self.name} thread={self._thread_id}')
return True
logger.debug(f'I[{self.id}] attempt acquire reentrant-lock[{self.name}].')
logger.debug(f'Attempt acquire reentrant-lock: lock_id={self.id} lock={self.name} thread={self._thread_id}')
acquired = super().acquire(blocking=blocking, timeout=timeout)
if acquired:
logger.debug(f'I[{self.id}] acquired reentrant-lock[{self.name}] now.')
logger.debug(f'Acquired reentrant-lock ok: lock_id={self.id} lock={self.name} thread={self._thread_id}')
setattr(thread_local, self.name, self.id)
else:
logger.debug(f'I[{self.id}] acquired reentrant-lock[{self.name}] failed.')
logger.debug(f'Acquired reentrant-lock failed: lock_id={self.id} lock={self.name} thread={self._thread_id}')
return acquired
else:
logger.debug(f'I[{self.id}] attempt acquire lock[{self.name}].')
logger.debug(f'Attempt acquire lock: lock_id={self.id} lock={self.name} thread={self._thread_id}')
acquired = super().acquire(blocking=blocking, timeout=timeout)
logger.debug(f'I[{self.id}] acquired lock[{self.name}] {acquired}.')
logger.debug(f'Acquired lock: ok={acquired} lock_id={self.id} lock={self.name} thread={self._thread_id}')
return acquired
@property
@@ -126,17 +126,17 @@ class DistributedLock(RedisLock):
def _release_on_reentrant_locked_by_brother(self):
if self._acquired_reentrant_lock:
self._acquired_reentrant_lock = False
logger.debug(f'I[{self.id}] released reentrant-lock[{self.name}] owner[{self.get_owner_id()}] in thread[{self._thread_id}]')
logger.debug(f'Released reentrant-lock: lock_id={self.id} owner_id={self.get_owner_id()} lock={self.name} thread={self._thread_id}')
return
else:
self._raise_exc_with_log(f'Reentrant-lock[{self.name}] is not acquired by me[{self.id}].')
self._raise_exc_with_log(f'Reentrant-lock is not acquired: lock_id={self.id} owner_id={self.get_owner_id()} lock={self.name} thread={self._thread_id}')
def _release_on_reentrant_locked_by_me(self):
logger.debug(f'I[{self.id}] release reentrant-lock[{self.name}] in thread[{self._thread_id}]')
logger.debug(f'Release reentrant-lock locked by me: lock_id={self.id} lock={self.name} thread={self._thread_id}')
id = getattr(thread_local, self.name, None)
if id != self.id:
raise PermissionError(f'Reentrant-lock[{self.name}] is not locked by me[{self.id}], owner[{id}]')
raise PermissionError(f'Reentrant-lock is not locked by me: lock_id={self.id} owner_id={self.get_owner_id()} lock={self.name} thread={self._thread_id}')
try:
# 这里要保证先删除 thread_local 的标记,
delattr(thread_local, self.name)
@@ -158,9 +158,9 @@ class DistributedLock(RedisLock):
def _release(self):
try:
self._release_redis_lock()
logger.debug(f'I[{self.id}] released lock[{self.name}]')
logger.debug(f'Released lock: lock_id={self.id} lock={self.name} thread={self._thread_id}')
except NotAcquired as e:
logger.error(f'I[{self.id}] release lock[{self.name}] failed {e}')
logger.error(f'Release lock failed: lock_id={self.id} lock={self.name} thread={self._thread_id} error: {e}')
self._raise_exc(e)
def release(self):
@@ -174,11 +174,11 @@ class DistributedLock(RedisLock):
else:
_release = self._release_on_reentrant_locked_by_brother
else:
self._raise_exc_with_log(f'Reentrant-lock[{self.name}] is not acquired in current-thread[{self._thread_id}]')
self._raise_exc_with_log(f'Reentrant-lock is not acquired: lock_id={self.id} lock={self.name} thread={self._thread_id}')
# 处理是否在事务提交时才释放锁
if self._release_on_transaction_commit:
logger.debug(f'I[{self.id}] release lock[{self.name}] on transaction commit ...')
logger.debug(f'Release lock on transaction commit ... :lock_id={self.id} lock={self.name} thread={self._thread_id}')
transaction.on_commit(_release)
else:
_release()