Commit b81c52ae authored by ibuler's avatar ibuler

[Update] 优化节点

parent a315df29
...@@ -73,19 +73,21 @@ class AssetViewSet(LabelFilter, OrgBulkModelViewSet): ...@@ -73,19 +73,21 @@ class AssetViewSet(LabelFilter, OrgBulkModelViewSet):
node = get_object_or_404(Node, id=node_id) node = get_object_or_404(Node, id=node_id)
show_current_asset = self.request.query_params.get("show_current_asset") in ('1', 'true') show_current_asset = self.request.query_params.get("show_current_asset") in ('1', 'true')
# 当前节点是顶层节点, 并且仅显示直接资产
if node.is_root() and show_current_asset: if node.is_root() and show_current_asset:
queryset = queryset.filter( queryset = queryset.filter(
Q(nodes=node_id) | Q(nodes__isnull=True) Q(nodes=node_id) | Q(nodes__isnull=True)
) ).distinct()
# 当前节点是顶层节点,显示所有资产
elif node.is_root() and not show_current_asset: elif node.is_root() and not show_current_asset:
pass return queryset
# 当前节点不是鼎城节点,只显示直接资产
elif not node.is_root() and show_current_asset: elif not node.is_root() and show_current_asset:
queryset = queryset.filter(nodes=node) queryset = queryset.filter(nodes=node)
else: else:
queryset = queryset.filter( children = node.get_all_children(with_self=True)
nodes__key__regex='^{}(:[0-9]+)*$'.format(node.key), queryset = queryset.filter(nodes__in=children).distinct()
) return queryset
return queryset.distinct()
def filter_admin_user_id(self, queryset): def filter_admin_user_id(self, queryset):
admin_user_id = self.request.query_params.get('admin_user_id') admin_user_id = self.request.query_params.get('admin_user_id')
......
...@@ -13,8 +13,11 @@ ...@@ -13,8 +13,11 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
from rest_framework import generics, mixins, viewsets import time
from rest_framework import generics, mixins
from rest_framework.serializers import ValidationError from rest_framework.serializers import ValidationError
from rest_framework.pagination import LimitOffsetPagination
from rest_framework.views import APIView from rest_framework.views import APIView
from rest_framework.response import Response from rest_framework.response import Response
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
...@@ -22,6 +25,7 @@ from django.shortcuts import get_object_or_404 ...@@ -22,6 +25,7 @@ from django.shortcuts import get_object_or_404
from common.utils import get_logger, get_object_or_none from common.utils import get_logger, get_object_or_none
from common.tree import TreeNodeSerializer from common.tree import TreeNodeSerializer
from orgs.mixins import OrgModelViewSet
from ..hands import IsOrgAdmin from ..hands import IsOrgAdmin
from ..models import Node from ..models import Node
from ..tasks import update_assets_hardware_info_util, test_asset_connectivity_util from ..tasks import update_assets_hardware_info_util, test_asset_connectivity_util
...@@ -39,29 +43,26 @@ __all__ = [ ...@@ -39,29 +43,26 @@ __all__ = [
] ]
class NodeViewSet(viewsets.ModelViewSet): class NodeViewSet(OrgModelViewSet):
filter_fields = ('value', 'key', ) filter_fields = ('value', 'key', 'id')
search_fields = filter_fields search_fields = ('value', )
queryset = Node.objects.all() queryset = Node.objects.all()
permission_classes = (IsOrgAdmin,) permission_classes = (IsOrgAdmin,)
serializer_class = serializers.NodeSerializer serializer_class = serializers.NodeSerializer
pagination_class = LimitOffsetPagination
# 仅支持根节点指直接创建,子节点下的节点需要通过children接口创建
def perform_create(self, serializer): def perform_create(self, serializer):
child_key = Node.root().get_next_child_key() child_key = Node.root().get_next_child_key()
serializer.validated_data["key"] = child_key serializer.validated_data["key"] = child_key
serializer.save() serializer.save()
def update(self, request, *args, **kwargs): def perform_update(self, serializer):
node = self.get_object() node = self.get_object()
if node.is_root(): if node.is_root() and node.value != serializer.validated_data['value']:
node_value = node.value msg = _("You can't update the root node name")
post_value = request.data.get('value') raise ValidationError({"error": msg})
if node_value != post_value: return super().perform_update(serializer)
return Response(
{"msg": _("You can't update the root node name")},
status=400
)
return super().update(request, *args, **kwargs)
class NodeListAsTreeApi(generics.ListAPIView): class NodeListAsTreeApi(generics.ListAPIView):
...@@ -79,17 +80,19 @@ class NodeListAsTreeApi(generics.ListAPIView): ...@@ -79,17 +80,19 @@ class NodeListAsTreeApi(generics.ListAPIView):
permission_classes = (IsOrgAdmin,) permission_classes = (IsOrgAdmin,)
serializer_class = TreeNodeSerializer serializer_class = TreeNodeSerializer
def get_queryset(self): def to_tree_queryset(self, queryset):
queryset = Node.objects.all()
util = NodeUtil() util = NodeUtil()
nodes = util.get_nodes_by_queryset(queryset) nodes = util.get_nodes_by_queryset(queryset)
queryset = [node.as_tree_node() for node in nodes] queryset = [node.as_tree_node() for node in nodes]
return queryset return queryset
@staticmethod def get_queryset(self):
def refresh_nodes(queryset): queryset = Node.objects.all()
Node.expire_nodes_assets_amount() return queryset
Node.expire_nodes_full_value()
def filter_queryset(self, queryset):
queryset = super().filter_queryset(queryset)
queryset = self.to_tree_queryset(queryset)
return queryset return queryset
...@@ -112,18 +115,28 @@ class NodeChildrenAsTreeApi(generics.ListAPIView): ...@@ -112,18 +115,28 @@ class NodeChildrenAsTreeApi(generics.ListAPIView):
is_root = False is_root = False
def get_queryset(self): def get_queryset(self):
t1 = time.time()
self.check_need_refresh_nodes() self.check_need_refresh_nodes()
t2 = time.time()
print("1: ", t2 - t1)
node_key = self.request.query_params.get('key') node_key = self.request.query_params.get('key')
util = NodeUtil() # util = NodeUtil()
# 是否包含自己 # 是否包含自己
with_self = False with_self = False
if not node_key: if not node_key:
node_key = Node.root().key node_key = Node.root().key
with_self = True with_self = True
self.node = util.get_node_by_key(node_key) # self.node = util.get_node_by_key(node_key)
self.node = get_object_or_404(Node, key=node_key)
t3 = time.time()
print("2: ", t3 - t2)
queryset = self.node.get_children(with_self=with_self) queryset = self.node.get_children(with_self=with_self)
t4 = time.time()
queryset = [node.as_tree_node() for node in queryset] queryset = [node.as_tree_node() for node in queryset]
print("3: ", t4 - t3)
t5 = time.time()
queryset = sorted(queryset) queryset = sorted(queryset)
print("4: ", t5 - t4)
return queryset return queryset
def filter_assets(self, queryset): def filter_assets(self, queryset):
...@@ -131,7 +144,8 @@ class NodeChildrenAsTreeApi(generics.ListAPIView): ...@@ -131,7 +144,8 @@ class NodeChildrenAsTreeApi(generics.ListAPIView):
if not include_assets: if not include_assets:
return queryset return queryset
assets = self.node.get_assets().only( assets = self.node.get_assets().only(
"id", "hostname", "ip", 'platform', "os", "org_id", "protocols", "id", "hostname", "ip", 'platform', "os",
"org_id", "protocols",
) )
for asset in assets: for asset in assets:
queryset.append(asset.as_tree_node(self.node)) queryset.append(asset.as_tree_node(self.node))
......
...@@ -29,9 +29,14 @@ class ProtocolForm(forms.Form): ...@@ -29,9 +29,14 @@ class ProtocolForm(forms.Form):
class AssetCreateForm(OrgModelForm): class AssetCreateForm(OrgModelForm):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
if self.data:
return
nodes_field = self.fields['nodes'] nodes_field = self.fields['nodes']
nodes_field.choices = ((n.id, n.full_value) for n in if self.instance:
Node.get_queryset()) nodes_field.choices = ((n.id, n.full_value) for n in
self.instance.nodes.all())
else:
nodes_field.choices = []
class Meta: class Meta:
model = Asset model = Asset
...@@ -42,7 +47,7 @@ class AssetCreateForm(OrgModelForm): ...@@ -42,7 +47,7 @@ class AssetCreateForm(OrgModelForm):
] ]
widgets = { widgets = {
'nodes': forms.SelectMultiple(attrs={ 'nodes': forms.SelectMultiple(attrs={
'class': 'select2', 'data-placeholder': _('Nodes') 'class': 'nodes-select2', 'data-placeholder': _('Nodes')
}), }),
'admin_user': forms.Select(attrs={ 'admin_user': forms.Select(attrs={
'class': 'select2', 'data-placeholder': _('Admin user') 'class': 'select2', 'data-placeholder': _('Admin user')
...@@ -68,6 +73,17 @@ class AssetCreateForm(OrgModelForm): ...@@ -68,6 +73,17 @@ class AssetCreateForm(OrgModelForm):
class AssetUpdateForm(OrgModelForm): class AssetUpdateForm(OrgModelForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
if self.data:
return
nodes_field = self.fields['nodes']
if self.instance:
nodes_field.choices = ((n.id, n.full_value) for n in
self.instance.nodes.all())
else:
nodes_field.choices = []
class Meta: class Meta:
model = Asset model = Asset
fields = [ fields = [
...@@ -77,7 +93,7 @@ class AssetUpdateForm(OrgModelForm): ...@@ -77,7 +93,7 @@ class AssetUpdateForm(OrgModelForm):
] ]
widgets = { widgets = {
'nodes': forms.SelectMultiple(attrs={ 'nodes': forms.SelectMultiple(attrs={
'class': 'select2', 'data-placeholder': _('Node') 'class': 'nodes-select2', 'data-placeholder': _('Node')
}), }),
'admin_user': forms.Select(attrs={ 'admin_user': forms.Select(attrs={
'class': 'select2', 'data-placeholder': _('Admin user') 'class': 'select2', 'data-placeholder': _('Admin user')
......
This diff is collapsed.
...@@ -13,17 +13,24 @@ __all__ = [ ...@@ -13,17 +13,24 @@ __all__ = [
class NodeSerializer(BulkOrgResourceModelSerializer): class NodeSerializer(BulkOrgResourceModelSerializer):
assets_amount = serializers.IntegerField(read_only=True)
name = serializers.ReadOnlyField(source='value') name = serializers.ReadOnlyField(source='value')
full_value = serializers.SerializerMethodField(label=_("Full value"))
class Meta: class Meta:
model = Node model = Node
only_fields = ['id', 'key', 'value', 'org_id'] only_fields = ['id', 'key', 'value', 'org_id']
fields = only_fields + ['name', 'assets_amount'] fields = only_fields + ['name', 'full_value']
read_only_fields = [ read_only_fields = [
'key', 'name', 'assets_amount', 'org_id', 'key', 'name', 'full_value', 'org_id',
] ]
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.tree = Node.tree()
def get_full_value(self, obj):
return self.tree.get_node_full_tag(obj.key)
def validate_value(self, data): def validate_value(self, data):
instance = self.instance if self.instance else Node.root() instance = self.instance if self.instance else Node.root()
children = instance.parent.get_children() children = instance.parent.get_children()
......
...@@ -112,7 +112,8 @@ def on_node_assets_changed(sender, instance=None, **kwargs): ...@@ -112,7 +112,8 @@ def on_node_assets_changed(sender, instance=None, **kwargs):
@receiver(post_save, sender=Node) @receiver(post_save, sender=Node)
def on_node_update_or_created(sender, instance=None, created=False, **kwargs): def on_node_update_or_created(sender, instance=None, created=False, **kwargs):
if instance and not created: if instance and not created:
instance.expire_full_value() pass
# instance.expire_full_value()
@receiver(post_save, sender=AuthBook) @receiver(post_save, sender=AuthBook)
......
...@@ -236,7 +236,8 @@ function onBodyMouseDown(event){ ...@@ -236,7 +236,8 @@ function onBodyMouseDown(event){
} }
function onRename(event, treeId, treeNode, isCancel){ function onRename(event, treeId, treeNode, isCancel){
var url = "{% url 'api-assets:node-detail' pk=DEFAULT_PK %}".replace("{{ DEFAULT_PK }}", current_node_id); var url = "{% url 'api-assets:node-detail' pk=DEFAULT_PK %}"
.replace("{{ DEFAULT_PK }}", current_node_id);
var data = {"value": treeNode.name}; var data = {"value": treeNode.name};
if (isCancel){ if (isCancel){
return return
...@@ -250,7 +251,7 @@ function onRename(event, treeId, treeNode, isCancel){ ...@@ -250,7 +251,7 @@ function onRename(event, treeId, treeNode, isCancel){
treeNode.name = treeNode.name + ' (' + treeNode.meta.node.assets_amount + ')'; treeNode.name = treeNode.name + ' (' + treeNode.meta.node.assets_amount + ')';
zTree.updateNode(treeNode); zTree.updateNode(treeNode);
console.log("Success: " + treeNode.name) console.log("Success: " + treeNode.name)
} },
}) })
} }
......
...@@ -110,6 +110,27 @@ $(document).ready(function () { ...@@ -110,6 +110,27 @@ $(document).ready(function () {
$('.select2').select2({ $('.select2').select2({
allowClear: true allowClear: true
}); });
$(".nodes-select2").select2({
closeOnSelect: false,
ajax: {
url: '{% url "api-assets:node-list" %}',
data: function (params) {
var page = params.page || 1;
var query = {
search: params.term,
offset: (page -1) * 10,
limit: 10
};
return query
},
processResults: function (data) {
var results = $.map(data.results, function (v, i) {
return {id: v.id, text: v.full_value}
});
return {results: results, pagination: {"more": true}}
}
},
});
$(".labels").select2({ $(".labels").select2({
allowClear: true, allowClear: true,
templateSelection: format templateSelection: format
......
# ~*~ coding: utf-8 ~*~ # ~*~ coding: utf-8 ~*~
# #
import time
from functools import reduce from functools import reduce
from treelib import Tree
from django.db.models import Prefetch, Q from django.db.models import Prefetch, Q
from common.utils import get_object_or_none, get_logger from common.utils import get_object_or_none, get_logger, timeit
from common.struct import Stack from common.struct import Stack
from .models import SystemUser, Label, Node, Asset from .models import SystemUser, Label, Node, Asset
...@@ -54,10 +54,12 @@ class LabelFilter(LabelFilterMixin): ...@@ -54,10 +54,12 @@ class LabelFilter(LabelFilterMixin):
class NodeUtil: class NodeUtil:
full_value_sep = ' / '
def __init__(self, with_assets_amount=False, debug=False): def __init__(self, with_assets_amount=False, debug=False):
self.stack = Stack() self.stack = Stack()
self._nodes = {}
self.with_assets_amount = with_assets_amount self.with_assets_amount = with_assets_amount
self._nodes = {}
self._debug = debug self._debug = debug
self.init() self.init()
...@@ -65,62 +67,85 @@ class NodeUtil: ...@@ -65,62 +67,85 @@ class NodeUtil:
def sorted_by(node): def sorted_by(node):
return [int(i) for i in node.key.split(':')] return [int(i) for i in node.key.split(':')]
@timeit
def get_queryset(self): def get_queryset(self):
all_nodes = Node.objects.all() queryset = Node.objects.all().only('id', 'key', 'value')
if self.with_assets_amount: if self.with_assets_amount:
all_nodes = all_nodes.prefetch_related( queryset = queryset.prefetch_related(
Prefetch('assets', queryset=Asset.objects.all().only('id')) Prefetch('assets', queryset=Asset.objects.all().only('id')
) ))
all_nodes = list(all_nodes) return list(queryset)
for node in all_nodes:
node._assets = set(node.assets.all())
return all_nodes
def get_all_nodes(self): @staticmethod
all_nodes = sorted(self.get_queryset(), key=self.sorted_by) def set_node_default_attr(node):
setattr(node, '_full_value', node.value)
setattr(node, '_children', [])
setattr(node, '_all_children', [])
setattr(node, '_parents', [])
guarder = Node(key='', value='Guarder') @timeit
guarder._assets = [] def get_all_nodes(self):
all_nodes.append(guarder) queryset = sorted(list(self.get_queryset()), key=self.sorted_by)
return all_nodes guarder = Node(key='', value='ROOT')
self.set_node_default_attr(guarder)
queryset.append(guarder)
for node in queryset[:-1]:
self.set_node_default_attr(node)
if not self.with_assets_amount:
continue
assets = set([str(a.id) for a in node.assets.all()])
node._assets = assets
node._all_assets = assets
return queryset
def push_to_stack(self, node): def push_to_stack(self, node):
# 入栈之前检查 # 入栈之前检查
# 如果栈是空的,证明是一颗树的根部 # 如果栈是空的,证明是一颗树的根部
if self.stack.is_empty(): if self.stack.is_empty():
node._full_value = node.value node._full_value = node.value
node._parents = []
else: else:
# 如果不是根节点, # 如果不是根节点,
# 该节点的祖先应该是父节点的祖先加上父节点 # 该节点的祖先应该是父节点的祖先加上父节点
# 该节点的名字是父节点的名字+自己的名字 # 该节点的名字是父节点的名字+自己的名字
node._parents = [self.stack.top] + self.stack.top._parents node._parents = [self.stack.top] + getattr(self.stack.top, '_parents')
node._full_value = ' / '.join( node._full_value = self.full_value_sep.join(
[self.stack.top._full_value, node.value] [getattr(self.stack.top, '_full_value', ''), node.value]
) )
node._children = [] # self.debug("入栈: {}".format(node.key))
node._all_children = []
self.debug("入栈: {}".format(node.key))
self.stack.push(node) self.stack.push(node)
# 出栈 # 出栈
# @timeit
def pop_from_stack(self): def pop_from_stack(self):
_node = self.stack.pop() _node = self.stack.pop()
self.debug("出栈: {} 栈顶: {}".format(_node.key, self.stack.top.key if self.stack.top else None)) # self.debug("出栈: {} 栈顶: {}".format(
# _node.key, self.stack.top.key if self.stack.top else None)
# )
self._nodes[_node.key] = _node self._nodes[_node.key] = _node
if not self.stack.top: if not self.stack.top:
return return
if self.with_assets_amount: parent = self.stack.top
self.stack.top._assets.update(_node._assets) parent_children = getattr(parent, '_children')
_node._assets_amount = len(_node._assets) parent_all_children = getattr(parent, '_all_children')
delattr(_node, '_assets') node_all_children = getattr(_node, '_all_children')
self.stack.top._children.append(_node) parent_children.append(_node)
self.stack.top._all_children.extend([_node] + _node._all_children) parent_all_children.extend([_node] + node_all_children)
if not self.with_assets_amount:
return
node_all_assets = getattr(_node, '_all_assets')
parent_all_assets = getattr(parent, '_all_assets')
_node._assets_amount = len(node_all_assets)
parent_all_assets.update(node_all_assets)
@timeit
def init(self): def init(self):
all_nodes = self.get_all_nodes() all_nodes = self.get_all_nodes()
for node in all_nodes: for node in all_nodes:
self.debug("准备: {} 栈顶: {}".format(node.key, self.stack.top.key if self.stack.top else None)) self.debug("准备: {} 栈顶: {}".format(
node.key, self.stack.top.key if self.stack.top else None)
)
# 入栈之前检查,该节点是不是栈顶节点的子节点 # 入栈之前检查,该节点是不是栈顶节点的子节点
# 如果不是,则栈顶出栈 # 如果不是,则栈顶出栈
while self.stack.top and not self.stack.top.is_children(node): while self.stack.top and not self.stack.top.is_children(node):
...@@ -144,27 +169,19 @@ class NodeUtil: ...@@ -144,27 +169,19 @@ class NodeUtil:
def debug(self, msg): def debug(self, msg):
self._debug and logger.debug(msg) self._debug and logger.debug(msg)
def set_assets_amount(self):
for node in self._nodes.values():
node.assets_amount = node._assets_amount
def set_full_value(self):
for node in self._nodes.values():
node.full_value = node._full_value
@property @property
def nodes(self): def nodes(self):
return list(self._nodes.values()) return list(self._nodes.values())
def get_family_by_key(self, key): def get_family_by_key(self, key):
tree_nodes = set() family = set()
node = self.get_node_by_key(key) node = self.get_node_by_key(key)
if not node: if not node:
return [] return []
tree_nodes.update(node._parents) family.update(getattr(node, '_parents'))
tree_nodes.add(node) family.add(node)
tree_nodes.update(node._all_children) family.update(getattr(node, '_all_children'))
return list(tree_nodes) return list(family)
# 使用给定节点生成一颗树 # 使用给定节点生成一颗树
# 找到他们的祖先节点 # 找到他们的祖先节点
...@@ -179,8 +196,8 @@ class NodeUtil: ...@@ -179,8 +196,8 @@ class NodeUtil:
def get_some_nodes_family_by_keys(self, keys): def get_some_nodes_family_by_keys(self, keys):
family = set() family = set()
for key in keys: for key in keys:
family.update(self.get_family_by_key(key)) family.update(set(self.get_family_by_key(key)))
return family return list(family)
def get_some_nodes_family_keys_by_keys(self, keys): def get_some_nodes_family_keys_by_keys(self, keys):
family = self.get_some_nodes_family_by_keys(keys) family = self.get_some_nodes_family_by_keys(keys)
...@@ -191,7 +208,7 @@ class NodeUtil: ...@@ -191,7 +208,7 @@ class NodeUtil:
node = self.get_node_by_key(key) node = self.get_node_by_key(key)
if not node: if not node:
return [] return []
parents.update(set(node._parents)) parents.update(set(getattr(node, '_parents')))
if with_self: if with_self:
parents.add(node) parents.add(node)
return list(parents) return list(parents)
...@@ -203,21 +220,20 @@ class NodeUtil: ...@@ -203,21 +220,20 @@ class NodeUtil:
nodes = self.get_nodes_parents_by_key(key, with_self=with_self) nodes = self.get_nodes_parents_by_key(key, with_self=with_self)
return [n.key for n in nodes] return [n.key for n in nodes]
def get_all_children_by_key(self, key, with_self=True): def get_node_all_children_by_key(self, key, with_self=True):
children = set()
node = self.get_node_by_key(key) node = self.get_node_by_key(key)
if not node: if not node:
return [] return []
children.update(set(node._all_children)) children = set(getattr(node, '_all_children'))
if with_self: if with_self:
children.add(node) children.add(node)
return list(children) return list(children)
def get_all_children(self, node, with_self=True): def get_all_children(self, node, with_self=True):
return self.get_all_children_by_key(node.key, with_self=with_self) return self.get_node_all_children_by_key(node.key, with_self=with_self)
def get_all_children_keys_by_key(self, key, with_self=True): def get_all_children_keys_by_key(self, key, with_self=True):
nodes = self.get_all_children_by_key(key, with_self=with_self) nodes = self.get_node_all_children_by_key(key, with_self=with_self)
return [n.key for n in nodes] return [n.key for n in nodes]
...@@ -250,7 +266,42 @@ def test_node_tree(): ...@@ -250,7 +266,42 @@ def test_node_tree():
) )
class TreeService(Tree):
tag_sep = ' / '
@classmethod
@timeit
def new(cls):
from .models import Node
all_nodes = Node.objects.all()
tree = cls()
tree.create_node(tag='', identifier='')
for node in all_nodes:
tree.create_node(
tag=node.value, identifier=node.key,
parent=node.parent_key, data=node
)
return tree
def all_children(self, nid, with_self=True):
children_ids = self.expand_tree(nid)
if not with_self:
next(children_ids)
return [self[i] for i in children_ids]
def ancestors(self, nid, with_self=True):
ancestor_ids = list(self.rsearch(nid))
ancestor_ids.pop()
if not with_self:
ancestor_ids.pop(0)
return [self.get_node(i) for i in ancestor_ids]
def get_node_full_tag(self, nid):
ancestors = self.ancestors(nid)
ancestors.reverse()
return self.tag_sep.join(n.tag for n in ancestors)
def get_family(self, nid):
ancestors = self.ancestors(nid, with_self=False)
children = self.all_children(nid, with_self=False)
return ancestors + [self[nid]] + children
...@@ -304,10 +304,10 @@ LOGGING = { ...@@ -304,10 +304,10 @@ LOGGING = {
'handlers': ['gunicorn_console', 'gunicorn_file'], 'handlers': ['gunicorn_console', 'gunicorn_file'],
'level': 'INFO', 'level': 'INFO',
}, },
# 'django.db': { 'django.db': {
# 'handlers': ['console', 'file'], 'handlers': ['console', 'file'],
# 'level': 'DEBUG' 'level': 'DEBUG'
# } }
} }
} }
......
...@@ -41,17 +41,17 @@ class AssetPermissionForm(OrgModelForm): ...@@ -41,17 +41,17 @@ class AssetPermissionForm(OrgModelForm):
users_field = self.fields.get('users') users_field = self.fields.get('users')
users_field.queryset = current_org.get_org_users() users_field.queryset = current_org.get_org_users()
nodes_field = self.fields['nodes'] if self.data:
nodes_field.choices = ((n.id, n.full_value) for n in Node.get_queryset()) return
# 前端渲染优化, 防止过多资产 # 前端渲染优化, 防止过多资产
if not self.data: assets_field = self.fields['assets']
instance = kwargs.get('instance') nodes_field = self.fields['nodes']
assets_field = self.fields['assets'] if self.instance:
if instance: assets_field.queryset = self.instance.assets.all()
assets_field.queryset = instance.assets.all() nodes_field.queryset = self.instance.nodes.all()
else: else:
assets_field.queryset = Asset.objects.none() assets_field.queryset = Asset.objects.none()
nodes_field.queryset = Node.objects.none()
class Meta: class Meta:
model = AssetPermission model = AssetPermission
...@@ -69,7 +69,7 @@ class AssetPermissionForm(OrgModelForm): ...@@ -69,7 +69,7 @@ class AssetPermissionForm(OrgModelForm):
attrs={'class': 'select2', 'data-placeholder': _("Asset")} attrs={'class': 'select2', 'data-placeholder': _("Asset")}
), ),
'nodes': forms.SelectMultiple( 'nodes': forms.SelectMultiple(
attrs={'class': 'select2', 'data-placeholder': _("Node")} attrs={'class': 'nodes-select2', 'data-placeholder': _("Node")}
), ),
'system_users': forms.SelectMultiple( 'system_users': forms.SelectMultiple(
attrs={'class': 'select2', 'data-placeholder': _('System user')} attrs={'class': 'select2', 'data-placeholder': _('System user')}
......
...@@ -115,6 +115,27 @@ $(document).ready(function () { ...@@ -115,6 +115,27 @@ $(document).ready(function () {
$('.select2').select2({ $('.select2').select2({
closeOnSelect: false closeOnSelect: false
}); });
$(".nodes-select2").select2({
closeOnSelect: false,
ajax: {
url: '{% url "api-assets:node-list" %}',
data: function (params) {
var page = params.page || 1;
var query = {
search: params.term,
offset: (page -1) * 10,
limit: 10
};
return query
},
processResults: function (data) {
var results = $.map(data.results, function (v, i) {
return {id: v.id, text: v.full_value}
});
return {results: results, pagination: {"more": true}}
}
},
});
$('#date_start').daterangepicker(dateOptions); $('#date_start').daterangepicker(dateOptions);
$('#date_expired').daterangepicker(dateOptions); $('#date_expired').daterangepicker(dateOptions);
$("#id_assets").parent().find(".select2-selection").on('click', function (e) { $("#id_assets").parent().find(".select2-selection").on('click', function (e) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment