|
|
|
@ -22,7 +22,9 @@ class Node(OrgModelMixin):
|
|
|
|
|
date_create = models.DateTimeField(auto_now_add=True) |
|
|
|
|
|
|
|
|
|
is_node = True |
|
|
|
|
_full_value_cache_key_prefix = '_NODE_VALUE_{}' |
|
|
|
|
_assets_amount = None |
|
|
|
|
_full_value_cache_key = '_NODE_VALUE_{}' |
|
|
|
|
_assets_amount_cache_key = '_NODE_ASSETS_AMOUNT_{}' |
|
|
|
|
|
|
|
|
|
class Meta: |
|
|
|
|
verbose_name = _("Node") |
|
|
|
@ -49,30 +51,56 @@ class Node(OrgModelMixin):
|
|
|
|
|
def name(self): |
|
|
|
|
return self.value |
|
|
|
|
|
|
|
|
|
@property |
|
|
|
|
def assets_amount(self): |
|
|
|
|
""" |
|
|
|
|
获取节点下所有资产数量速度太慢,所以需要重写,使用cache等方案 |
|
|
|
|
:return: |
|
|
|
|
""" |
|
|
|
|
if self._assets_amount is not None: |
|
|
|
|
return self._assets_amount |
|
|
|
|
cache_key = self._assets_amount_cache_key.format(self.key) |
|
|
|
|
cached = cache.get(cache_key) |
|
|
|
|
if cached is not None: |
|
|
|
|
return cached |
|
|
|
|
assets_amount = self.get_all_assets().count() |
|
|
|
|
cache.set(cache_key, assets_amount, 3600) |
|
|
|
|
return assets_amount |
|
|
|
|
|
|
|
|
|
@assets_amount.setter |
|
|
|
|
def assets_amount(self, value): |
|
|
|
|
self._assets_amount = value |
|
|
|
|
|
|
|
|
|
def expire_assets_amount(self): |
|
|
|
|
ancestor_keys = self.get_ancestor_keys(with_self=True) |
|
|
|
|
cache_keys = [self._assets_amount_cache_key.format(k) for k in ancestor_keys] |
|
|
|
|
cache.delete_many(cache_keys) |
|
|
|
|
|
|
|
|
|
@classmethod |
|
|
|
|
def expire_nodes_assets_amount(cls, nodes=None): |
|
|
|
|
if nodes: |
|
|
|
|
for node in nodes: |
|
|
|
|
node.expire_assets_amount() |
|
|
|
|
return |
|
|
|
|
key = cls._assets_amount_cache_key.format('*') |
|
|
|
|
cache.delete_pattern(key) |
|
|
|
|
|
|
|
|
|
@property |
|
|
|
|
def full_value(self): |
|
|
|
|
key = self._full_value_cache_key_prefix.format(self.key) |
|
|
|
|
key = self._full_value_cache_key.format(self.key) |
|
|
|
|
cached = cache.get(key) |
|
|
|
|
if cached: |
|
|
|
|
return cached |
|
|
|
|
value = self.get_full_value() |
|
|
|
|
self.cache_full_value(value) |
|
|
|
|
return value |
|
|
|
|
|
|
|
|
|
def get_full_value(self): |
|
|
|
|
# ancestor = [a.value for a in self.get_ancestor(with_self=True)] |
|
|
|
|
if self.is_root(): |
|
|
|
|
return self.value |
|
|
|
|
parent_full_value = self.parent.full_value |
|
|
|
|
value = parent_full_value + ' / ' + self.value |
|
|
|
|
return value |
|
|
|
|
|
|
|
|
|
def cache_full_value(self, value): |
|
|
|
|
key = self._full_value_cache_key_prefix.format(self.key) |
|
|
|
|
key = self._full_value_cache_key.format(self.key) |
|
|
|
|
cache.set(key, value, 3600) |
|
|
|
|
return value |
|
|
|
|
|
|
|
|
|
def expire_full_value(self): |
|
|
|
|
key = self._full_value_cache_key_prefix.format(self.key) |
|
|
|
|
key = self._full_value_cache_key.format(self.key) |
|
|
|
|
cache.delete_pattern(key+'*') |
|
|
|
|
|
|
|
|
|
@property |
|
|
|
@ -182,17 +210,18 @@ class Node(OrgModelMixin):
|
|
|
|
|
child.save() |
|
|
|
|
self.save() |
|
|
|
|
|
|
|
|
|
def get_ancestor(self, with_self=False): |
|
|
|
|
if self.is_root(): |
|
|
|
|
root = self.__class__.root() |
|
|
|
|
return [root] |
|
|
|
|
_key = self.key.split(':') |
|
|
|
|
def get_ancestor_keys(self, with_self=False): |
|
|
|
|
parent_keys = [] |
|
|
|
|
key_list = self.key.split(":") |
|
|
|
|
if not with_self: |
|
|
|
|
_key.pop() |
|
|
|
|
ancestor_keys = [] |
|
|
|
|
for i in range(len(_key)): |
|
|
|
|
ancestor_keys.append(':'.join(_key)) |
|
|
|
|
_key.pop() |
|
|
|
|
key_list.pop() |
|
|
|
|
for i in range(len(key_list)): |
|
|
|
|
parent_keys.append(":".join(key_list)) |
|
|
|
|
key_list.pop() |
|
|
|
|
return parent_keys |
|
|
|
|
|
|
|
|
|
def get_ancestor(self, with_self=False): |
|
|
|
|
ancestor_keys = self.get_ancestor_keys(with_self=with_self) |
|
|
|
|
ancestor = self.__class__.objects.filter( |
|
|
|
|
key__in=ancestor_keys |
|
|
|
|
).order_by('key') |
|
|
|
@ -227,10 +256,6 @@ class Node(OrgModelMixin):
|
|
|
|
|
defaults = {'value': 'Default'} |
|
|
|
|
return cls.objects.get_or_create(defaults=defaults, key='1') |
|
|
|
|
|
|
|
|
|
@classmethod |
|
|
|
|
def get_tree_name_ref(cls): |
|
|
|
|
pass |
|
|
|
|
|
|
|
|
|
@classmethod |
|
|
|
|
def generate_fake(cls, count=100): |
|
|
|
|
import random |
|
|
|
|